Commit 94e61287e7

Josh Wolfe <thejoshwolfe@gmail.com>
2015-12-07 07:49:20
let is now a statement, not an expression
1 parent 66e3aa0
Changed files (3)
src/parser.cpp
@@ -1214,7 +1214,7 @@ static AstNode *ast_parse_ass_expr(ParseContext *pc, int *token_index, bool mand
 }
 
 /*
-NonBlockExpression : ReturnExpression | VariableDeclaration | AssignmentExpression
+NonBlockExpression : ReturnExpression | AssignmentExpression
 */
 static AstNode *ast_parse_non_block_expr(ParseContext *pc, int *token_index, bool mandatory) {
     Token *token = &pc->tokens->at(*token_index);
@@ -1223,11 +1223,6 @@ static AstNode *ast_parse_non_block_expr(ParseContext *pc, int *token_index, boo
     if (return_expr)
         return return_expr;
 
-    AstNode *variable_declaration_expr = ast_parse_variable_declaration_expr(pc, token_index, false);
-    if (variable_declaration_expr)
-        return variable_declaration_expr;
-
-
     AstNode *ass_expr = ast_parse_ass_expr(pc, token_index, false);
     if (ass_expr)
         return ass_expr;
@@ -1288,8 +1283,8 @@ static AstNode *ast_parse_label(ParseContext *pc, int *token_index, bool mandato
 }
 
 /*
-Statement : Label | NonBlockExpression token(Semicolon) | BlockExpression
 Block : token(LBrace) list(option(Statement), token(Semicolon)) token(RBrace)
+Statement : Label | VariableDeclaration token(Semicolon) | NonBlockExpression token(Semicolon) | BlockExpression
 */
 static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandatory) {
     Token *last_token = &pc->tokens->at(*token_index);
@@ -1316,12 +1311,17 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato
         if (statement_node) {
             semicolon_expected = false;
         } else {
-            statement_node = ast_parse_block_expr(pc, token_index, false);
-            semicolon_expected = !statement_node;
-            if (!statement_node) {
-                statement_node = ast_parse_non_block_expr(pc, token_index, false);
+            statement_node = ast_parse_variable_declaration_expr(pc, token_index, false);
+            if (statement_node) {
+                semicolon_expected = true;
+            } else {
+                statement_node = ast_parse_block_expr(pc, token_index, false);
+                semicolon_expected = !statement_node;
                 if (!statement_node) {
-                    statement_node = ast_create_node(pc, NodeTypeVoid, last_token);
+                    statement_node = ast_parse_non_block_expr(pc, token_index, false);
+                    if (!statement_node) {
+                        statement_node = ast_create_node(pc, NodeTypeVoid, last_token);
+                    }
                 }
             }
         }
test/run_tests.cpp
@@ -514,6 +514,12 @@ fn f() {
     b = 3;
 }
     )SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'");
+
+    add_compile_fail_case("let is a statement, not an expression", R"SOURCE(
+fn f() {
+    (let a = 0);
+}
+    )SOURCE", 1, ".tmp_source.zig:3:6: error: invalid token: 'let'");
 }
 
 static void print_compiler_invocation(TestCase *test_case, Buf *zig_stderr) {
README.md
@@ -150,13 +150,15 @@ PointerType : token(Star) token(Const) Type | token(Star) token(Mut) Type
 
 Block : token(LBrace) list(option(Statement), token(Semicolon)) token(RBrace)
 
-Statement : Label | NonBlockExpression token(Semicolon) | BlockExpression
+Statement : Label | VariableDeclaration token(Semicolon) | NonBlockExpression token(Semicolon) | BlockExpression
 
 Label: token(Symbol) token(Colon)
 
+VariableDeclaration : token(Let) option(token(Mut)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
+
 Expression : BlockExpression | NonBlockExpression
 
-NonBlockExpression : ReturnExpression | VariableDeclaration | AssignmentExpression
+NonBlockExpression : ReturnExpression | AssignmentExpression
 
 AssignmentExpression : BoolOrExpression token(Equal) BoolOrExpression | BoolOrExpression
 
@@ -166,8 +168,6 @@ BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndEx
 
 ReturnExpression : token(Return) option(Expression)
 
-VariableDeclaration : token(Let) option(token(Mut)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
-
 IfExpression : token(If) Expression Block option(Else | ElseIf)
 
 ElseIf : token(Else) IfExpression