diff options
| author | Mustafa Quraish <[email protected]> | 2022-01-29 18:29:45 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-01-29 18:29:45 -0500 |
| commit | 81250ad76bbd336a262da71f4f71d6a37b68bd74 (patch) | |
| tree | b4f94acfa2f46e0e87e49aca97ba72a76b459a23 /cup/parser.c | |
| parent | Implement blocks (lexically scoped) and conditionals (diff) | |
| download | archived-cup-81250ad76bbd336a262da71f4f71d6a37b68bd74.tar.xz archived-cup-81250ad76bbd336a262da71f4f71d6a37b68bd74.zip | |
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.
Diffstat (limited to 'cup/parser.c')
| -rw-r--r-- | cup/parser.c | 29 |
1 files changed, 29 insertions, 0 deletions
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 { |