From d50af2e474281a1e88d191f783c2792824698974 Mon Sep 17 00:00:00 2001 From: hachem Date: Thu, 10 Sep 2026 05:52:08 +0200 Subject: feat: conditional select --- src/parser.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/parser.c') diff --git a/src/parser.c b/src/parser.c index 5379114..b0e049c 100644 --- a/src/parser.c +++ b/src/parser.c @@ -721,6 +721,43 @@ static bool parse_statement(struct Parser* parser, struct Statement* out) if (value == NULL) return false; + // conditional select: target = if_value if else else_value. The `if` + // must share the assignment's line, so a plain assignment followed by an + // `if` statement on the next line stays two statements. + if (op.type == TOKEN_EQUAL && !deref + && check(parser, TOKEN_IF) && parser->current.line == name.line) + { + advance_parser(parser); + + struct Expr* left; + struct Token comparison; + struct Expr* right; + if (!parse_condition(parser, &left, &comparison, &right)) + { + free_expr(value); + return false; + } + + struct Expr* else_value = NULL; + if (!consume(parser, TOKEN_ELSE, "expected 'else' in conditional select") + || (else_value = parse_expression(parser)) == NULL) + { + free_expr(value); + free_expr(left); + free_expr(right); + return false; + } + + out->kind = STATEMENT_SELECT; + out->select.target = name; + out->select.if_value = value; + out->select.left = left; + out->select.comparison = comparison; + out->select.right = right; + out->select.else_value = else_value; + return true; + } + out->kind = STATEMENT_ASSIGN; out->assign.target_deref = deref; out->assign.store_size = store_size; -- cgit v1.3