about summary refs log tree commit diff
path: root/boot/lower.c
diff options
context:
space:
mode:
Diffstat (limited to 'boot/lower.c')
-rw-r--r--boot/lower.c49
1 files changed, 21 insertions, 28 deletions
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);
 }