about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-05-30 00:22:33 +0200
committerBaitinq <[email protected]>2025-05-30 00:23:34 +0200
commit5af4a54e9c5f6481c3ba0bfe045855832974ab4f (patch)
tree6407ec823a2e5ca29db36f450a3cd5f9f373ded6 /src
parentFeature: Support custom types in llvm_get_type (diff)
downloadpry-lang-5af4a54e9c5f6481c3ba0bfe045855832974ab4f.tar.gz
pry-lang-5af4a54e9c5f6481c3ba0bfe045855832974ab4f.tar.bz2
pry-lang-5af4a54e9c5f6481c3ba0bfe045855832974ab4f.zip
Feature: Support structs as pointers
Diffstat (limited to 'src')
-rw-r--r--src/codegen.zig39
1 files changed, 28 insertions, 11 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 3ab3a5c..b60ad95 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -211,9 +211,8 @@ pub const CodeGen = struct {
             .FIELD_ACCESS => |field_access| {
                 const xd = assignment_statement.lhs.FIELD_ACCESS.expression;
                 const name = field_access.name;
-                const ptr = self.environment.get_variable(xd.PRIMARY_EXPRESSION.IDENTIFIER.name).?;
 
-                const x = try self.get_struct_field(ptr, name);
+                const x = try self.get_struct_field(xd, name);
 
                 const variable = try self.generate_expression_value(assignment_statement.rhs, null);
                 _ = llvm.LLVMBuildStore(self.builder, variable.value, x.value);
@@ -391,7 +390,7 @@ pub const CodeGen = struct {
         try self.generate(import_declaration.program);
     }
 
-    fn generate_expression_value(self: *CodeGen, expression: *parser.Node, name: ?[]const u8) !*Variable {
+    fn generate_expression_value(self: *CodeGen, expression: *parser.Node, name: ?[]const u8) CodeGenError!*Variable {
         errdefer std.debug.print("Error generating statement value\n", .{});
         return switch (expression.*) {
             .FUNCTION_DEFINITION => |function_definition| {
@@ -777,9 +776,7 @@ pub const CodeGen = struct {
                 });
             },
             .FIELD_ACCESS => |exp| {
-                const ptr = self.environment.get_variable(exp.expression.PRIMARY_EXPRESSION.IDENTIFIER.name).?;
-
-                const x = try self.get_struct_field(ptr, exp.name);
+                const x = try self.get_struct_field(exp.expression, exp.name);
                 const loaded = llvm.LLVMBuildLoad2(self.builder, try self.get_llvm_type(x.type), x.value, "");
 
                 return try self.create_variable(.{
@@ -816,10 +813,30 @@ pub const CodeGen = struct {
         });
     }
 
-    fn get_struct_field(self: *CodeGen, ptr: *Variable, name: []const u8) !struct { value: llvm.LLVMValueRef, type: *parser.Node } {
+    fn get_struct_field(self: *CodeGen, node: *parser.Node, name: []const u8) !struct { value: llvm.LLVMValueRef, type: *parser.Node } {
+        var ptr: *Variable = undefined;
+        switch (node.*) {
+            .PRIMARY_EXPRESSION => {
+                ptr = self.environment.get_variable(node.PRIMARY_EXPRESSION.IDENTIFIER.name).?;
+            },
+            .UNARY_EXPRESSION => {
+                ptr = try self.generate_expression_value(node.UNARY_EXPRESSION.expression, "");
+            },
+            else => unreachable,
+        }
+
+        var typ: *parser.Node = undefined;
+        if (ptr.node_type.TYPE == .STRUCT_TYPE) {
+            typ = ptr.node_type;
+        } else if (ptr.node_type.TYPE == .POINTER_TYPE) {
+            typ = self.environment.get_variable(ptr.node_type.TYPE.POINTER_TYPE.type.TYPE.SIMPLE_TYPE.name).?.node_type;
+        } else if (ptr.node_type.TYPE == .SIMPLE_TYPE) {
+            typ = self.environment.get_variable(ptr.node_type.TYPE.SIMPLE_TYPE.name).?.node_type;
+        } else {
+            unreachable;
+        }
         var fieldIndex: ?usize = null;
-        for (0.., ptr.node_type.TYPE.STRUCT_TYPE.fields) |i, field| {
-            std.debug.print("STRUCT: {s}\n", .{name});
+        for (0.., typ.TYPE.STRUCT_TYPE.fields) |i, field| {
             if (std.mem.eql(u8, name, field.PRIMARY_EXPRESSION.IDENTIFIER.name)) {
                 fieldIndex = i;
                 break;
@@ -832,8 +849,8 @@ pub const CodeGen = struct {
         const indices = @constCast(&[_]llvm.LLVMValueRef{ zero, llvmFieldIndex });
 
         return .{
-            .value = llvm.LLVMBuildGEP2(self.builder, try self.get_llvm_type(ptr.node_type), ptr.value, indices, indices.len, try std.fmt.allocPrintZ(self.arena, "{s}", .{name})),
-            .type = ptr.node_type.TYPE.STRUCT_TYPE.fields[fieldIndex.?].PRIMARY_EXPRESSION.IDENTIFIER.type.?,
+            .value = llvm.LLVMBuildGEP2(self.builder, try self.get_llvm_type(typ), ptr.value, indices, indices.len, try std.fmt.allocPrintZ(self.arena, "{s}", .{name})),
+            .type = typ.TYPE.STRUCT_TYPE.fields[fieldIndex.?].PRIMARY_EXPRESSION.IDENTIFIER.type.?,
         };
     }