aboutsummaryrefslogtreecommitdiff
path: root/cup/parser.c
diff options
context:
space:
mode:
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 {