break;
}
- case Token_Type_Keyword_If: {
- AstIfExpression* if_expression = make_node(AstIfExpression, Ast_Kind_If_Expression);
- if_expression->token = expect_token(parser, Token_Type_Keyword_If);
-
- if_expression->true_expr = retval;
- if_expression->cond = parse_expression(parser, 0);
- expect_token(parser, Token_Type_Keyword_Else);
- if_expression->false_expr = parse_expression(parser, 0);
-
- retval = (AstTyped *) if_expression;
- break;
- }
-
case '?': {
AstUnaryOp* unop = make_node(AstUnaryOp, Ast_Kind_Unary_Op);
unop->token = expect_token(parser, '?');
while (1) {
if (parser->hit_unexpected_token) return root;
+ if (parser->curr->type == Token_Type_Keyword_If) {
+ AstIfExpression *ifexpr = make_node(AstIfExpression, Ast_Kind_If_Expression);
+ ifexpr->token = expect_token(parser, Token_Type_Keyword_If);
+
+ ifexpr->true_expr = root;
+ ifexpr->cond = parse_expression(parser, 0);
+ expect_token(parser, Token_Type_Keyword_Else);
+ ifexpr->false_expr = parse_expression(parser, 0);
+
+ // Check for the x = y if cond else z case.
+ // This would parse as (x = 1) if cond else z, but that is incorrect.
+ if (root->kind == Ast_Kind_Binary_Op && binop_is_assignment(((AstBinaryOp *) root)->operation)) {
+ AstBinaryOp *r = (AstBinaryOp *) root;
+ ifexpr->true_expr = r->right;
+ r->right = (AstTyped *) ifexpr;
+
+ } else {
+ root = (AstTyped *) ifexpr;
+ }
+
+ goto expression_done;
+ }
+
bin_op_kind = binary_op_from_token_type(parser->curr->type);
if (bin_op_kind == Binary_Op_Count) goto expression_done;
if (binop_is_assignment(bin_op_kind) && !assignment_allowed) goto expression_done;
--- /dev/null
+use core {printf}
+
+main :: () {
+ printf("cmp(1, 2): {}\n", cmp(1, 2));
+ printf("cmp(2, 2): {}\n", cmp(2, 2));
+ printf("cmp(3, 2): {}\n", cmp(3, 2));
+}
+
+cmp :: (a: i32, b: i32) -> i32 {
+ return 0 if a == b else -1 if a < b else 1;
+}
\ No newline at end of file