From 81250ad76bbd336a262da71f4f71d6a37b68bd74 Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Sat, 29 Jan 2022 18:29:45 -0500 Subject: Add for and while loop support (w/o declarations in `for`) We can now loop and do stuff, yay! However, we don't yet allow declarations inside the for-loop initializer, since that is a bit more annoying to implement. --- cup/parser.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'cup/parser.c') diff --git a/cup/parser.c b/cup/parser.c index b3113ea..698002f 100644 --- a/cup/parser.c +++ b/cup/parser.c @@ -334,6 +334,35 @@ Node *parse_statement(Lexer *lexer) Lexer_next(lexer); node->conditional.do_else = parse_statement(lexer); } + } else if (token.type == TOKEN_WHILE) { + Lexer_next(lexer); + node = Node_new(AST_WHILE); + assert_token(Lexer_next(lexer), TOKEN_OPEN_PAREN); + node->loop.cond = parse_expression(lexer); + assert_token(Lexer_next(lexer), TOKEN_CLOSE_PAREN); + node->loop.body = parse_statement(lexer); + } else if (token.type == TOKEN_FOR) { + Lexer_next(lexer); + node = Node_new(AST_FOR); + assert_token(Lexer_next(lexer), TOKEN_OPEN_PAREN); + + // All of the expressions in the for loop are optional + + // TODO: Allow this to be a declaration, need to inject + // the variable into the symbol table for the block + if (Lexer_peek(lexer).type != TOKEN_SEMICOLON) + node->loop.init = parse_expression(lexer); + assert_token(Lexer_next(lexer), TOKEN_SEMICOLON); + + if (Lexer_peek(lexer).type != TOKEN_SEMICOLON) + node->loop.cond = parse_expression(lexer); + assert_token(Lexer_next(lexer), TOKEN_SEMICOLON); + + if (Lexer_peek(lexer).type != TOKEN_CLOSE_PAREN) + node->loop.step = parse_expression(lexer); + assert_token(Lexer_next(lexer), TOKEN_CLOSE_PAREN); + + node->loop.body = parse_statement(lexer); } else if (token.type == TOKEN_OPEN_BRACE) { node = parse_block(lexer); } else { -- cgit v1.2.3