diff options
| author | Mustafa Quraish <[email protected]> | 2022-01-29 13:52:58 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-01-29 13:53:57 -0500 |
| commit | e403475bbf6f70b3e79b6f4503dbadcc3dad504c (patch) | |
| tree | 40c77638cf96048328358e601c541ab31fb2b23a /cup/parser.c | |
| parent | Add some tests for local variables (diff) | |
| download | archived-cup-e403475bbf6f70b3e79b6f4503dbadcc3dad504c.tar.xz archived-cup-e403475bbf6f70b3e79b6f4503dbadcc3dad504c.zip | |
Allow uninitialized variable declarations
Diffstat (limited to 'cup/parser.c')
| -rw-r--r-- | cup/parser.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/cup/parser.c b/cup/parser.c index ecd12f9..a47116b 100644 --- a/cup/parser.c +++ b/cup/parser.c @@ -119,9 +119,6 @@ Node *parse_var_declaration(Lexer *lexer) node->var_decl.var.name = token.value.as_string; assert_token(Lexer_next(lexer), TOKEN_COLON); node->var_decl.var.type = parse_type(lexer); - assert_token(Lexer_next(lexer), TOKEN_ASSIGN); - node->var_decl.value = parse_expression(lexer); - assert_token(Lexer_next(lexer), TOKEN_SEMICOLON); // Set offset for variable node->var_decl.var.offset = current_function->func.cur_stack_offset; @@ -133,6 +130,14 @@ Node *parse_var_declaration(Lexer *lexer) current_function->func.num_locals++; current_function->func.cur_stack_offset += var_size; + token = Lexer_next(lexer); + if (token.type == TOKEN_ASSIGN) { + node->var_decl.value = parse_expression(lexer); + assert_token(Lexer_next(lexer), TOKEN_SEMICOLON); + } else { + assert_token(token, TOKEN_SEMICOLON); + } + return node; } @@ -203,7 +208,25 @@ bool is_logical_and_token(TokenType type) { return type == TOKEN_AND; } Node *parse_logical_and(Lexer *lexer) { BINOP_PARSER(parse_equality, is_logical_and_token); } bool is_logical_or_token(TokenType type) { return type == TOKEN_OR; } -Node *parse_expression(Lexer *lexer) { BINOP_PARSER(parse_logical_and, is_logical_or_token); } +Node *parse_logical_or(Lexer *lexer) { BINOP_PARSER(parse_logical_and, is_logical_or_token); } + +Node *parse_expression(Lexer *lexer) +{ + Node *node = parse_logical_or(lexer); + // FIXME: This is a hack to handle assignment expressions + // and can probably be done properly. + if (node->type == AST_VAR) { + Token token = Lexer_peek(lexer); + if (token.type == TOKEN_ASSIGN) { + Lexer_next(lexer); + Variable *var = node->variable; + node->type = OP_ASSIGN; + node->assign.var = var; + node->assign.value = parse_expression(lexer); + } + } + return node; +} Node *parse_statement(Lexer *lexer) { @@ -218,8 +241,9 @@ Node *parse_statement(Lexer *lexer) } else if (token.type == TOKEN_LET) { return parse_var_declaration(lexer); } else { - die_location(token.loc, ": Unexpected token in parse_statement: %s\n", token_type_to_str(token.type)); - exit(1); + // Default to trying to handle it as an expression + node = parse_expression(lexer); + assert_token(Lexer_next(lexer), TOKEN_SEMICOLON); } return node; |