diff options
| author | Mustafa Quraish <[email protected]> | 2022-02-05 21:26:56 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-02-05 21:26:56 -0500 |
| commit | 0a0050695254411047122a760ca22ad31c6bd9f8 (patch) | |
| tree | 412cf1c7eac92f08ebb38d35fc815687568106a7 /compiler/parser.cup | |
| parent | Update `run.sh2` to not re-make the C compiler (diff) | |
| download | cup-0a0050695254411047122a760ca22ad31c6bd9f8.tar.xz cup-0a0050695254411047122a760ca22ad31c6bd9f8.zip | |
[compiler.cup] Support for+while loops
Diffstat (limited to 'compiler/parser.cup')
| -rw-r--r-- | compiler/parser.cup | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/compiler/parser.cup b/compiler/parser.cup index 1335fba..914c4e6 100644 --- a/compiler/parser.cup +++ b/compiler/parser.cup @@ -413,6 +413,7 @@ fn add_variable_to_current_block(var: Variable*) { } fn parse_var_declaration(lexer: Lexer*): Node* { + let token: Token; lexer_next_assert(lexer, &token, TOKEN_LET); lexer_next_assert(lexer, &token, TOKEN_IDENTIFIER); @@ -486,7 +487,48 @@ fn parse_function_params(lexer: Lexer*, func: Node*) { } fn parse_block(lexer: Lexer*): Node*; +fn parse_statement(lexer: Lexer*): Node*; + +fn parse_for_loop(lexer: Lexer*): Node* { + let token: Token; + lexer_next_assert(lexer, &token, TOKEN_FOR); + + let looop = node_new(AST_FOR); + lexer_next_assert(lexer, &token, TOKEN_OPEN_PAREN); + + // NOTE: We're going to put the for loop in it's own block + // so that any declarations in the init of the loop + // can only be referenced within the loop. + let node = node_new(AST_BLOCK); + node.d.block.children = vector_new_sized(1); + node.d.block.locals = vector_new_sized(1); + block_add_child(node, looop); + block_stack_push(node); + // All of the expressions in the for loop are optional + + lexer_peek(lexer, &token); + if (token.typ == TOKEN_LET) + looop.d.looop.init = parse_var_declaration(lexer); + else if (token.typ != TOKEN_SEMICOLON) + looop.d.looop.init = parse_expression(lexer); + lexer_next_assert(lexer, &token, TOKEN_SEMICOLON); + + lexer_peek(lexer, &token); + if (token.typ != TOKEN_SEMICOLON) + looop.d.looop.cond = parse_expression(lexer); + lexer_next_assert(lexer, &token, TOKEN_SEMICOLON); + + lexer_peek(lexer, &token); + if (token.typ != TOKEN_CLOSE_PAREN) + looop.d.looop.step = parse_expression(lexer); + lexer_next_assert(lexer, &token, TOKEN_CLOSE_PAREN); + + looop.d.looop.body = parse_statement(lexer); + block_stack_pop(); + + return node; +} fn parse_statement(lexer: Lexer*): Node* { let node: Node*; @@ -524,9 +566,16 @@ fn parse_statement(lexer: Lexer*): Node* { node.d.conditional.els = parse_statement(lexer); } } else if (token.typ == TOKEN_WHILE) { - die("while is not implemented yet"); + lexer_next(lexer, &token); + node = node_new(AST_WHILE); + lexer_next_assert(lexer, &token, TOKEN_OPEN_PAREN); + node.d.looop.cond = parse_expression(lexer); + lexer_next_assert(lexer, &token, TOKEN_CLOSE_PAREN); + node.d.looop.body = parse_statement(lexer); + } else if (token.typ == TOKEN_FOR) { - die("for is not implemented yet"); + node = parse_for_loop(lexer); + } else if (token.typ == TOKEN_DEFER) { die("defer is not implemented yet"); } else if (token.typ == TOKEN_LET) { |