Skip to content

Commit 8bc5232

Browse files
committedDec 21, 2017
add labeled loops, labeled break, labeled continue. remove goto
closes #346 closes #630 regression: translate-c can no longer translate switch statements. after #629 we can ressurect and modify the code to utilize arbitrarily returning from blocks.
·
0.15.10.2.0
1 parent d686113 commit 8bc5232

File tree

15 files changed

+339
-688
lines changed

15 files changed

+339
-688
lines changed
 

‎doc/langref.html.in‎

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5847,11 +5847,9 @@ ParamDeclList = "(" list(ParamDecl, ",") ")"
58475847

58485848
ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "...")
58495849

5850-
Block = "{" many(Statement) option(Expression) "}"
5850+
Block = option(Symbol ":") "{" many(Statement) option(Expression) "}"
58515851

5852-
Statement = Label | LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"
5853-
5854-
Label = Symbol ":"
5852+
Statement = LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"
58555853

58565854
TypeExpr = PrefixOpExpression | "var"
58575855

@@ -5891,13 +5889,13 @@ SwitchProng = (list(SwitchItem, ",") | "else") "=>" option("|" option("*") Sy
58915889

58925890
SwitchItem = Expression | (Expression "..." Expression)
58935891

5894-
ForExpression(body) = option("inline") "for" "(" Expression ")" option("|" option("*") Symbol option("," Symbol) "|") body option("else" BlockExpression(body))
5892+
ForExpression(body) = option(Symbol ":") option("inline") "for" "(" Expression ")" option("|" option("*") Symbol option("," Symbol) "|") body option("else" BlockExpression(body))
58955893

58965894
BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression
58975895

58985896
ReturnExpression = option("%") "return" option(Expression)
58995897

5900-
BreakExpression = "break" option(Expression)
5898+
BreakExpression = "break" option(":" Symbol) option(Expression)
59015899

59025900
Defer(body) = option("%") "defer" body
59035901

@@ -5907,7 +5905,7 @@ TryExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|")
59075905

59085906
TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body))
59095907

5910-
WhileExpression(body) = option("inline") "while" "(" Expression ")" option("|" option("*") Symbol "|") option(":" "(" Expression ")") body option("else" option("|" Symbol "|") BlockExpression(body))
5908+
WhileExpression(body) = option(Symbol ":") option("inline") "while" "(" Expression ")" option("|" option("*") Symbol "|") option(":" "(" Expression ")") body option("else" option("|" Symbol "|") BlockExpression(body))
59115909

59125910
BoolAndExpression = ComparisonExpression "and" BoolAndExpression | ComparisonExpression
59135911

@@ -5955,15 +5953,13 @@ StructLiteralField = "." Symbol "=" Expression
59555953

59565954
PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%"
59575955

5958-
PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl
5956+
PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl | ("continue" option(":" Symbol))
59595957

59605958
ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":" Integer ":" Integer) ")")) option("const") option("volatile") TypeExpr
59615959

5962-
GotoExpression = "goto" Symbol
5963-
59645960
GroupedExpression = "(" Expression ")"
59655961

5966-
KeywordLiteral = "true" | "false" | "null" | "continue" | "undefined" | "error" | "this" | "unreachable"
5962+
KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable"
59675963

59685964
ContainerDecl = option("extern" | "packed")
59695965
("struct" option(GroupedExpression) | "union" option("enum" option(GroupedExpression) | GroupedExpression) | ("enum" option(GroupedExpression)))

‎src/all_types.hpp‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,6 @@ enum NodeType {
386386
NodeTypeSwitchExpr,
387387
NodeTypeSwitchProng,
388388
NodeTypeSwitchRange,
389-
NodeTypeLabel,
390-
NodeTypeGoto,
391389
NodeTypeCompTime,
392390
NodeTypeBreak,
393391
NodeTypeContinue,
@@ -452,6 +450,7 @@ struct AstNodeParamDecl {
452450
};
453451

454452
struct AstNodeBlock {
453+
Buf *name;
455454
ZigList<AstNode *> statements;
456455
bool last_statement_is_result_expression;
457456
};
@@ -662,6 +661,7 @@ struct AstNodeTestExpr {
662661
};
663662

664663
struct AstNodeWhileExpr {
664+
Buf *name;
665665
AstNode *condition;
666666
Buf *var_symbol;
667667
bool var_is_ptr;
@@ -673,6 +673,7 @@ struct AstNodeWhileExpr {
673673
};
674674

675675
struct AstNodeForExpr {
676+
Buf *name;
676677
AstNode *array_expr;
677678
AstNode *elem_node; // always a symbol
678679
AstNode *index_node; // always a symbol, might be null
@@ -704,11 +705,6 @@ struct AstNodeLabel {
704705
Buf *name;
705706
};
706707

707-
struct AstNodeGoto {
708-
Buf *name;
709-
bool is_inline;
710-
};
711-
712708
struct AstNodeCompTime {
713709
AstNode *expr;
714710
};
@@ -836,11 +832,14 @@ struct AstNodeBoolLiteral {
836832
};
837833

838834
struct AstNodeBreakExpr {
835+
Buf *name;
839836
AstNode *expr; // may be null
840837
};
841838

842839
struct AstNodeContinueExpr {
840+
Buf *name;
843841
};
842+
844843
struct AstNodeUnreachableExpr {
845844
};
846845

@@ -886,7 +885,6 @@ struct AstNode {
886885
AstNodeSwitchProng switch_prong;
887886
AstNodeSwitchRange switch_range;
888887
AstNodeLabel label;
889-
AstNodeGoto goto_expr;
890888
AstNodeCompTime comptime_expr;
891889
AstNodeAsmExpr asm_expr;
892890
AstNodeFieldAccessExpr field_access_expr;
@@ -1741,6 +1739,7 @@ struct ScopeCImport {
17411739
struct ScopeLoop {
17421740
Scope base;
17431741

1742+
Buf *name;
17441743
IrBasicBlock *break_block;
17451744
IrBasicBlock *continue_block;
17461745
IrInstruction *is_comptime;

‎src/analyze.cpp‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,15 @@ ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent) {
144144
}
145145

146146
ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) {
147-
assert(node->type == NodeTypeWhileExpr || node->type == NodeTypeForExpr);
148147
ScopeLoop *scope = allocate<ScopeLoop>(1);
149148
init_scope(&scope->base, ScopeIdLoop, node, parent);
149+
if (node->type == NodeTypeWhileExpr) {
150+
scope->name = node->data.while_expr.name;
151+
} else if (node->type == NodeTypeForExpr) {
152+
scope->name = node->data.for_expr.name;
153+
} else {
154+
zig_unreachable();
155+
}
150156
return scope;
151157
}
152158

@@ -2916,8 +2922,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
29162922
case NodeTypeSwitchExpr:
29172923
case NodeTypeSwitchProng:
29182924
case NodeTypeSwitchRange:
2919-
case NodeTypeLabel:
2920-
case NodeTypeGoto:
29212925
case NodeTypeBreak:
29222926
case NodeTypeContinue:
29232927
case NodeTypeUnreachable:

‎src/ast_render.cpp‎

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,6 @@ static const char *node_type_str(NodeType node_type) {
215215
return "SwitchProng";
216216
case NodeTypeSwitchRange:
217217
return "SwitchRange";
218-
case NodeTypeLabel:
219-
return "Label";
220-
case NodeTypeGoto:
221-
return "Goto";
222218
case NodeTypeCompTime:
223219
return "CompTime";
224220
case NodeTypeBreak:
@@ -391,7 +387,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
391387
switch (node->type) {
392388
case NodeTypeSwitchProng:
393389
case NodeTypeSwitchRange:
394-
case NodeTypeLabel:
395390
case NodeTypeStructValueField:
396391
zig_unreachable();
397392
case NodeTypeRoot:
@@ -470,6 +465,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
470465
break;
471466
}
472467
case NodeTypeBlock:
468+
if (node->data.block.name != nullptr) {
469+
fprintf(ar->f, "%s: ", buf_ptr(node->data.block.name));
470+
}
473471
if (node->data.block.statements.length == 0) {
474472
fprintf(ar->f, "{}");
475473
break;
@@ -478,13 +476,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
478476
ar->indent += ar->indent_size;
479477
for (size_t i = 0; i < node->data.block.statements.length; i += 1) {
480478
AstNode *statement = node->data.block.statements.at(i);
481-
if (statement->type == NodeTypeLabel) {
482-
ar->indent -= ar->indent_size;
483-
print_indent(ar);
484-
fprintf(ar->f, "%s:\n", buf_ptr(statement->data.label.name));
485-
ar->indent += ar->indent_size;
486-
continue;
487-
}
488479
print_indent(ar);
489480
render_node_grouped(ar, statement);
490481
if (!(i == node->data.block.statements.length - 1 &&
@@ -515,6 +506,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
515506
case NodeTypeBreak:
516507
{
517508
fprintf(ar->f, "break");
509+
if (node->data.break_expr.name != nullptr) {
510+
fprintf(ar->f, " :%s", buf_ptr(node->data.break_expr.name));
511+
}
518512
if (node->data.break_expr.expr) {
519513
fprintf(ar->f, " ");
520514
render_node_grouped(ar, node->data.break_expr.expr);
@@ -828,6 +822,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
828822
}
829823
case NodeTypeWhileExpr:
830824
{
825+
if (node->data.while_expr.name != nullptr) {
826+
fprintf(ar->f, "%s: ", buf_ptr(node->data.while_expr.name));
827+
}
831828
const char *inline_str = node->data.while_expr.is_inline ? "inline " : "";
832829
fprintf(ar->f, "%swhile (", inline_str);
833830
render_node_grouped(ar, node->data.while_expr.condition);
@@ -957,11 +954,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
957954
fprintf(ar->f, "}");
958955
break;
959956
}
960-
case NodeTypeGoto:
961-
{
962-
fprintf(ar->f, "goto %s", buf_ptr(node->data.goto_expr.name));
963-
break;
964-
}
965957
case NodeTypeCompTime:
966958
{
967959
fprintf(ar->f, "comptime ");
@@ -970,6 +962,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
970962
}
971963
case NodeTypeForExpr:
972964
{
965+
if (node->data.for_expr.name != nullptr) {
966+
fprintf(ar->f, "%s: ", buf_ptr(node->data.for_expr.name));
967+
}
973968
const char *inline_str = node->data.for_expr.is_inline ? "inline " : "";
974969
fprintf(ar->f, "%sfor (", inline_str);
975970
render_node_grouped(ar, node->data.for_expr.array_expr);
@@ -995,6 +990,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
995990
case NodeTypeContinue:
996991
{
997992
fprintf(ar->f, "continue");
993+
if (node->data.continue_expr.name != nullptr) {
994+
fprintf(ar->f, " :%s", buf_ptr(node->data.continue_expr.name));
995+
}
998996
break;
999997
}
1000998
case NodeTypeUnreachable:

0 commit comments

Comments
 (0)
Please sign in to comment.