From 2a893246711442dd8407264c05991b44d1d1f66f Mon Sep 17 00:00:00 2001 From: Mel Date: Sun, 24 May 2026 20:14:29 +0200 Subject: Emit IR/C increment/decrement in expression position Signed-off-by: Mel --- boot/lower.c | 49 +++++++++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) (limited to 'boot/lower.c') diff --git a/boot/lower.c b/boot/lower.c index f36a124..696f3e4 100644 --- a/boot/lower.c +++ b/boot/lower.c @@ -1203,6 +1203,25 @@ lower_expression_function(struct Lower_Context* ctx, struct Tree_Expression* tre return ir_make_name(name, tree_expr->span); } +struct Expression* +lower_expression_increment_decrement(struct Lower_Context* ctx, struct Tree_Expression* tree_expr) +{ + struct Tree_Expression_Increment_Decrement* incdec = &tree_expr->value.increment_decrement; + struct Tree_Expression* subject = incdec->subject; + if (!subject || subject->kind != TREE_EXPRESSION_NAME) { + lower_push_error( + ctx->unit, + (struct Lower_Error){ + .kind = LOWER_ERROR_UNIMPLEMENTED, + .span = tree_expr->span, + .detail = string_from_static_c_string("increment/decrement on non-trivial lvalue"), + }); + return nil; + } + return ir_make_increment_decrement( + lower_expression(ctx, subject), incdec->operation, incdec->prefix, tree_expr->span); +} + // turns a source expression into the lowered form. struct Expression* lower_expression(struct Lower_Context* ctx, struct Tree_Expression* tree_expr) @@ -1232,9 +1251,10 @@ lower_expression(struct Lower_Context* ctx, struct Tree_Expression* tree_expr) return lower_expression_type(ctx, tree_expr); case TREE_EXPRESSION_FUNCTION: return lower_expression_function(ctx, tree_expr); + case TREE_EXPRESSION_INCREMENT_DECREMENT: + return lower_expression_increment_decrement(ctx, tree_expr); case TREE_EXPRESSION_SUBSCRIPT: case TREE_EXPRESSION_MEMBER: - case TREE_EXPRESSION_INCREMENT_DECREMENT: case TREE_EXPRESSION_TRY: case TREE_EXPRESSION_MUST: // TODO: implement these @@ -1403,33 +1423,6 @@ lower_statement_expression(struct Lower_Context* ctx, struct Tree_Statement* tre return ir_make_assign(lower_expression(ctx, lhs_tree), binary, tree_stmt->span); } } - if (inner && inner->kind == TREE_EXPRESSION_INCREMENT_DECREMENT) { - // synthesize into assignment and binary operation - struct Tree_Expression_Increment_Decrement* incdec = &inner->value.increment_decrement; - struct Tree_Expression* subject = incdec->subject; - if (!subject || subject->kind != TREE_EXPRESSION_NAME) { - // TODO: handle this too, like compound assignments - lower_push_error( - ctx->unit, - (struct Lower_Error){ - .kind = LOWER_ERROR_UNIMPLEMENTED, - .span = tree_stmt->span, - .detail = string_from_static_c_string( - "increment/decrement on non-trivial " - "lvalue"), - }); - return nil; - } - - enum Binary_Operation simple_op = - incdec->operation == INCREMENT_DECREMENT_INCREMENT ? BINARY_PLUS : BINARY_MINUS; - - struct Expression* one = ir_make_integer(1, inner->span); - struct Expression* binary = - ir_make_binary(simple_op, lower_expression(ctx, subject), one, inner->span); - return ir_make_assign(lower_expression(ctx, subject), binary, tree_stmt->span); - } - return ir_make_expression_statement(lower_expression(ctx, inner), tree_stmt->span); } -- cgit 1.4.1