aboutsummaryrefslogtreecommitdiff
path: root/cup/parser.c
diff options
context:
space:
mode:
authorMustafa Quraish <[email protected]>2022-01-29 18:29:45 -0500
committerMustafa Quraish <[email protected]>2022-01-29 18:29:45 -0500
commit81250ad76bbd336a262da71f4f71d6a37b68bd74 (patch)
treeb4f94acfa2f46e0e87e49aca97ba72a76b459a23 /cup/parser.c
parentImplement blocks (lexically scoped) and conditionals (diff)
downloadarchived-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.c29
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 {