about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/codegen.zig64
-rw-r--r--src/parser.zig25
2 files changed, 52 insertions, 37 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 553de77..d6b3e98 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -123,40 +123,48 @@ pub const CodeGen = struct {
     fn generate_assignment_statement(self: *CodeGen, statement: *parser.Node) CodeGenError!void {
         errdefer std.debug.print("Error generating assignment statement\n", .{});
         std.debug.assert(statement.* == parser.Node.ASSIGNMENT_STATEMENT);
-
         const assignment_statement = statement.ASSIGNMENT_STATEMENT;
 
-        if (assignment_statement.is_declaration and self.environment.scope_stack.items.len > 1) {
-            std.debug.assert(assignment_statement.is_dereference == false);
-            // TODO: vv Int64Type is a problem
-            const alloca = llvm.LLVMBuildAlloca(self.builder, llvm.LLVMInt64Type(), try std.fmt.allocPrintZ(self.arena, "{s}", .{assignment_statement.name})); //TODO: Correct type
-            try self.environment.add_variable(assignment_statement.name, try self.create_variable(.{
-                .value = alloca,
-                .type = llvm.LLVMVoidType(), // This gets set to the correct type during the expression type resolution. ALTERNATIVE: Pass the alloca
-                .stack_level = null,
-                .node = statement,
-            }));
-        }
+        if (assignment_statement.lhs.* == .PRIMARY_EXPRESSION) {
+            const identifier = assignment_statement.lhs.PRIMARY_EXPRESSION.IDENTIFIER;
 
-        var undereferenced_variable: ?*Variable = null;
-        if (assignment_statement.is_dereference) {
-            const ptr = self.environment.get_variable(assignment_statement.name) orelse unreachable;
-            undereferenced_variable = ptr;
-            const x = llvm.LLVMBuildLoad2(self.builder, ptr.type, ptr.value, "") orelse return CodeGenError.CompilationError;
-            try self.environment.add_variable(assignment_statement.name, try self.create_variable(.{
-                .value = x,
-                .type = ptr.type,
-                .stack_level = null,
-                .node = statement,
-            }));
-        }
+            if (assignment_statement.is_declaration and self.environment.scope_stack.items.len > 1) {
+                std.debug.assert(assignment_statement.is_dereference == false);
+                // TODO: vv Int64Type is a problem
+                const alloca = llvm.LLVMBuildAlloca(self.builder, llvm.LLVMInt64Type(), try std.fmt.allocPrintZ(self.arena, "{s}", .{identifier.name})); //TODO: Correct type
+                try self.environment.add_variable(identifier.name, try self.create_variable(.{
+                    .value = alloca,
+                    .type = llvm.LLVMVoidType(), // This gets set to the correct type during the expression type resolution. ALTERNATIVE: Pass the alloca
+                    .stack_level = null,
+                    .node = statement,
+                }));
+            }
 
-        const variable = try self.generate_expression_value(assignment_statement.expression, assignment_statement.name);
+            var undereferenced_variable: ?*Variable = null;
+            if (assignment_statement.is_dereference) {
+                const ptr = self.environment.get_variable(identifier.name) orelse unreachable;
+                undereferenced_variable = ptr;
+                const x = llvm.LLVMBuildLoad2(self.builder, ptr.type, ptr.value, "") orelse return CodeGenError.CompilationError;
+                try self.environment.add_variable(identifier.name, try self.create_variable(.{
+                    .value = x,
+                    .type = ptr.type,
+                    .stack_level = null,
+                    .node = statement,
+                }));
+            }
 
-        if (!assignment_statement.is_dereference) {
-            try self.environment.add_variable(assignment_statement.name, variable);
+            const variable = try self.generate_expression_value(assignment_statement.rhs, identifier.name);
+
+            if (!assignment_statement.is_dereference) {
+                try self.environment.add_variable(identifier.name, variable);
+            } else {
+                try self.environment.add_variable(identifier.name, undereferenced_variable.?);
+            }
         } else {
-            try self.environment.add_variable(assignment_statement.name, undereferenced_variable.?);
+            const xd = assignment_statement.lhs.UNARY_EXPRESSION.expression;
+            const a = try self.generate_expression_value(xd, null);
+            const variable = try self.generate_expression_value(assignment_statement.rhs, null);
+            _ = llvm.LLVMBuildStore(self.builder, variable.value, a.value);
         }
     }
 
diff --git a/src/parser.zig b/src/parser.zig
index a40c811..4f607be 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -16,8 +16,8 @@ pub const Node = union(enum) {
     ASSIGNMENT_STATEMENT: struct {
         is_declaration: bool,
         is_dereference: bool,
-        name: []const u8,
-        expression: *Node,
+        lhs: *Node,
+        rhs: *Node,
     },
     FUNCTION_CALL_STATEMENT: struct {
         expression: *Node,
@@ -154,7 +154,7 @@ pub const Parser = struct {
         });
     }
 
-    // AssignmentStatement ::= ("let")? ("*")? IDENTIFIER EQUALS Expression
+    // AssignmentStatement ::= ("let")? ("*")? Expression EQUALS Expression
     fn parse_assignment_statement(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing assignment statement {any}\n", .{self.peek_token()});
 
@@ -168,18 +168,18 @@ pub const Parser = struct {
             is_dereference = true;
         }
 
-        const identifier = try self.parse_token(tokenizer.TokenType.IDENTIFIER);
+        const lhs = try self.parse_expression();
 
         _ = try self.parse_token(tokenizer.TokenType.EQUALS);
 
-        const expression = try self.parse_expression();
+        const rhs = try self.parse_expression();
 
         return self.create_node(.{
             .ASSIGNMENT_STATEMENT = .{
                 .is_declaration = is_declaration,
                 .is_dereference = is_dereference,
-                .name = try self.arena.dupe(u8, identifier.type.IDENTIFIER),
-                .expression = @constCast(expression),
+                .lhs = lhs,
+                .rhs = rhs,
             },
         });
     }
@@ -200,8 +200,15 @@ pub const Parser = struct {
             .ASSIGNMENT_STATEMENT = .{
                 .is_declaration = true,
                 .is_dereference = false,
-                .name = try self.arena.dupe(u8, identifier.type.IDENTIFIER),
-                .expression = @constCast(typ),
+                .lhs = try self.create_node(.{
+                    .PRIMARY_EXPRESSION = .{
+                        .IDENTIFIER = .{
+                            .name = try self.arena.dupe(u8, identifier.type.IDENTIFIER),
+                            .type = null,
+                        },
+                    },
+                }),
+                .rhs = @constCast(typ),
             },
         });
     }