From 94e61287e708f61d2a9d814bfe7910d13e067ada Mon Sep 17 00:00:00 2001 From: Josh Wolfe Date: Sun, 6 Dec 2015 23:49:20 -0700 Subject: [PATCH] let is now a statement, not an expression --- README.md | 8 ++++---- src/parser.cpp | 24 ++++++++++++------------ test/run_tests.cpp | 6 ++++++ 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 141f0b1de7..f5f6af7c2e 100644 --- a/README.md +++ b/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 diff --git a/src/parser.cpp b/src/parser.cpp index 39b0d61838..fc47c7ad64 100644 --- a/src/parser.cpp +++ b/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); + } } } } diff --git a/test/run_tests.cpp b/test/run_tests.cpp index fac093670d..efb1e5f389 100644 --- a/test/run_tests.cpp +++ b/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) {