From e403475bbf6f70b3e79b6f4503dbadcc3dad504c Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Sat, 29 Jan 2022 13:52:58 -0500 Subject: Allow uninitialized variable declarations --- cup/parser.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'cup/parser.c') 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; -- cgit v1.2.3