From cea333644191567bcfdd1e24e4606aafbf34e3cb Mon Sep 17 00:00:00 2001 From: Mel Date: Sun, 1 Jun 2025 00:47:39 +0200 Subject: Parse if/else if/else statements Signed-off-by: Mel --- boot/parse.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'boot/parse.c') diff --git a/boot/parse.c b/boot/parse.c index 5bfa006..ed00f94 100644 --- a/boot/parse.c +++ b/boot/parse.c @@ -530,6 +530,55 @@ parser_statement_declaration(struct Parser* p, struct Parser_Error* error) return statement_new(STATEMENT_DECLARATION, value, span, location); } +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) { @@ -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)); -- cgit 1.4.1