let is now a statement, not an expression

This commit is contained in:
Josh Wolfe 2015-12-06 23:49:20 -07:00
parent 66e3aa0910
commit 94e61287e7
3 changed files with 22 additions and 16 deletions

View File

@ -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) 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) 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 Expression : BlockExpression | NonBlockExpression
NonBlockExpression : ReturnExpression | VariableDeclaration | AssignmentExpression NonBlockExpression : ReturnExpression | AssignmentExpression
AssignmentExpression : BoolOrExpression token(Equal) BoolOrExpression | BoolOrExpression AssignmentExpression : BoolOrExpression token(Equal) BoolOrExpression | BoolOrExpression
@ -166,8 +168,6 @@ BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndEx
ReturnExpression : token(Return) option(Expression) 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) IfExpression : token(If) Expression Block option(Else | ElseIf)
ElseIf : token(Else) IfExpression ElseIf : token(Else) IfExpression

View File

@ -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) { static AstNode *ast_parse_non_block_expr(ParseContext *pc, int *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index); 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) if (return_expr)
return 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); AstNode *ass_expr = ast_parse_ass_expr(pc, token_index, false);
if (ass_expr) if (ass_expr)
return 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) 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) { static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandatory) {
Token *last_token = &pc->tokens->at(*token_index); Token *last_token = &pc->tokens->at(*token_index);
@ -1315,6 +1310,10 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato
bool semicolon_expected; bool semicolon_expected;
if (statement_node) { if (statement_node) {
semicolon_expected = false; semicolon_expected = false;
} else {
statement_node = ast_parse_variable_declaration_expr(pc, token_index, false);
if (statement_node) {
semicolon_expected = true;
} else { } else {
statement_node = ast_parse_block_expr(pc, token_index, false); statement_node = ast_parse_block_expr(pc, token_index, false);
semicolon_expected = !statement_node; semicolon_expected = !statement_node;
@ -1325,6 +1324,7 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato
} }
} }
} }
}
node->data.block.statements.append(statement_node); node->data.block.statements.append(statement_node);
last_token = &pc->tokens->at(*token_index); last_token = &pc->tokens->at(*token_index);

View File

@ -514,6 +514,12 @@ fn f() {
b = 3; b = 3;
} }
)SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'"); )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) { static void print_compiler_invocation(TestCase *test_case, Buf *zig_stderr) {