diff options
| author | hachem <im@hachem.wtf> | 2026-09-10 05:52:08 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-09-10 05:52:08 +0200 |
| commit | d50af2e474281a1e88d191f783c2792824698974 (patch) | |
| tree | 571afdff3ac141bbfcee37bc61dfdb6ea8fda163 /src/parser.c | |
| parent | bf157cf09b8b0888c54a165b887309a4e801f608 (diff) | |
feat: conditional select
Diffstat (limited to 'src/parser.c')
| -rw-r--r-- | src/parser.c | 37 |
1 files changed, 37 insertions, 0 deletions
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 <cond> 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; |
