about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2026-05-30 23:52:44 +0200
committerMel <mel@rnrd.eu>2026-05-31 00:14:03 +0200
commit8428741c87f4586e98c6649b768bb7b69105b871 (patch)
tree62f0384be48d02b36edae406c6cf77bd6f6f4a67
parentdd9f8fccf405af709c1d655dbec4be1561e990c0 (diff)
downloadcatskill-main.tar.zst
catskill-main.zip
Lower member access, subscription, ++/--/compound assigns on all lvalues HEAD main
Signed-off-by: Mel <mel@rnrd.eu>
-rw-r--r--boot/lower.c57
1 files changed, 25 insertions, 32 deletions
diff --git a/boot/lower.c b/boot/lower.c
index df5fd45..8c588bf 100644
--- a/boot/lower.c
+++ b/boot/lower.c
@@ -1310,6 +1310,23 @@ lower_expression_construct(struct Lower_Context* ctx, struct Tree_Expression* tr
     return ir_make_construct(type->id, fields, tree_expr->span);
 }
 
+struct Expression*
+lower_expression_member(struct Lower_Context* ctx, struct Tree_Expression* tree_expr)
+{
+    struct Tree_Expression_Member* member = &tree_expr->value.member;
+    struct Expression* subject = lower_expression(ctx, member->subject);
+    return ir_make_member(subject, member->name, tree_expr->span);
+}
+
+struct Expression*
+lower_expression_subscript(struct Lower_Context* ctx, struct Tree_Expression* tree_expr)
+{
+    struct Tree_Expression_Subscript* subscript = &tree_expr->value.subscript;
+    struct Expression* subject = lower_expression(ctx, subscript->subject);
+    struct Expression* index = lower_expression(ctx, subscript->index);
+    return ir_make_subscript(subject, index, tree_expr->span);
+}
+
 // type-as-expression is only valid as the right-side of a top-level binding,
 // anywhere else it is an error.
 struct Expression*
@@ -1362,21 +1379,8 @@ 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);
+        lower_expression(ctx, incdec->subject), incdec->operation, incdec->prefix, tree_expr->span);
 }
 
 // turns a source expression into the lowered form.
@@ -1410,11 +1414,13 @@ lower_expression(struct Lower_Context* ctx, struct Tree_Expression* tree_expr)
         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:
+        return lower_expression_member(ctx, tree_expr);
+    case TREE_EXPRESSION_SUBSCRIPT:
+        return lower_expression_subscript(ctx, tree_expr);
     case TREE_EXPRESSION_TRY:
     case TREE_EXPRESSION_MUST:
-        // TODO: implement these
+        // TODO: try/must need maybe/result sentinel handling
     default:
         lower_push_error(
             ctx->unit,
@@ -1650,22 +1656,9 @@ lower_statement_expression(struct Lower_Context* ctx, struct Tree_Statement* tre
         }
         if (op > BINARY_ASSIGN) {
             // compound assigns always synthesize into a basic assignment
-            // to a simple binary operation.
-            if (!lhs_tree || lhs_tree->kind != TREE_EXPRESSION_NAME) {
-                // TODO: implement non-trivial lhs assignments like function
-                // calls for example. not too common but sometimes necessary.
-                lower_push_error(
-                    ctx->unit,
-                    (struct Lower_Error){
-                        .kind = LOWER_ERROR_UNIMPLEMENTED,
-                        .span = tree_stmt->span,
-                        .detail = string_from_static_c_string(
-                            "compound assignment with "
-                            "non-trivial lvalue"),
-                    });
-                return nil;
-            }
-
+            // to a simple binary operation. note that this evaluates the
+            // lhs tree twice, so side effects in the lvalue double.
+            // TODO: handle the double-evaluation once type checker is in.
             enum Binary_Operation simple_op = binary_operation_strip_assign(op);
             if (simple_op == BINARY_NONE) {
                 lower_push_error(