diff options
| author | Mel <mel@rnrd.eu> | 2025-06-01 00:47:39 +0200 |
|---|---|---|
| committer | Mel <mel@rnrd.eu> | 2025-06-01 00:47:39 +0200 |
| commit | cea333644191567bcfdd1e24e4606aafbf34e3cb (patch) | |
| tree | 42d50d37059a7f23cd659823fb3fba7695c83615 /boot/parse.c | |
| parent | ef66c99536a631ff2bd1dab4a825ce16d2efa530 (diff) | |
| download | catskill-cea333644191567bcfdd1e24e4606aafbf34e3cb.tar.zst catskill-cea333644191567bcfdd1e24e4606aafbf34e3cb.zip | |
Parse if/else if/else statements
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot/parse.c')
| -rw-r--r-- | boot/parse.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/boot/parse.c b/boot/parse.c index 5bfa006..ed00f94 100644 --- a/boot/parse.c +++ b/boot/parse.c @@ -531,6 +531,55 @@ parser_statement_declaration(struct Parser* p, struct Parser_Error* error) } struct Statement* +parser_statement_conditional(struct Parser* p, struct Parser_Error* error) +{ + struct Statement_Value_Conditional conditional = { 0 }; + struct Token if_token = parser_need(p, TOKEN_WORD_IF, error); + + // primary if condition + block. + struct Expression* if_condition = CHECK(parser_expression(p, error)); + struct Block_Node then_block = CHECK(parser_block_node(p, error)); + conditional.conditions[conditional.condition_count++] = (struct Statement_Conditional_Branch){ + .when = if_condition, + .then = then_block, + }; + + struct Span span = span_merge(if_token.span, then_block.span); + while (parser_probe(p, TOKEN_WORD_ELSE)) { + check(conditional.condition_count < STATEMENT_VALUE_CONDITIONAL_MAX, + "too many conditional branches"); + parser_next(p); + + struct Statement_Conditional_Branch branch = { 0 }; + if (parser_probe(p, TOKEN_WORD_IF)) { + // else if condition + block. + parser_next(p); + struct Expression* else_condition = CHECK(parser_expression(p, error)); + struct Block_Node else_block = CHECK(parser_block_node(p, error)); + + branch = (struct Statement_Conditional_Branch){ + .when = else_condition, + .then = else_block, + }; + } else { + // else block. + struct Block_Node else_block = CHECK(parser_block_node(p, error)); + branch = (struct Statement_Conditional_Branch){ + .when = nil, + .then = else_block, + }; + } + + conditional.conditions[conditional.condition_count++] = branch; + span = span_merge(span, branch.then.span); + } + + return statement_new( + STATEMENT_CONDITIONAL, (union Statement_Value){ .conditional = conditional }, span, + if_token.location); +} + +struct Statement* parser_statement(struct Parser* p, struct Parser_Error* error) { struct Token token = parser_peek(p); @@ -553,6 +602,8 @@ parser_statement(struct Parser* p, struct Parser_Error* error) return parser_statement_declaration(p, error); } + if (token_is(&token, TOKEN_WORD_IF)) return parser_statement_conditional(p, error); + if (token_is(&token, TOKEN_CURLY_OPEN)) { // a block statement. struct Block_Node block = CHECK(parser_block_node(p, error)); |
