diff options
| author | Baitinq <[email protected]> | 2025-05-30 23:05:09 +0200 |
|---|---|---|
| committer | Baitinq <[email protected]> | 2025-05-30 23:05:09 +0200 |
| commit | fbc474a0c619df6bd334d5cde1987f820840c5f3 (patch) | |
| tree | 5e5662dc5463e71574265e230748fd23e4a69891 | |
| parent | Feature: Support structs as pointers (diff) | |
| download | interpreter-fbc474a0c619df6bd334d5cde1987f820840c5f3.tar.gz interpreter-fbc474a0c619df6bd334d5cde1987f820840c5f3.tar.bz2 interpreter-fbc474a0c619df6bd334d5cde1987f820840c5f3.zip | |
Feature: Support recursive structs
| -rw-r--r-- | examples/24.src | 48 | ||||
| -rw-r--r-- | src/codegen.zig | 11 |
2 files changed, 59 insertions, 0 deletions
diff --git a/examples/24.src b/examples/24.src new file mode 100644 index 0000000..e0a3081 --- /dev/null +++ b/examples/24.src @@ -0,0 +1,48 @@ +extern malloc = (i64) => *void; + +import "!stdlib.src"; + +let test = struct { + x: i64, + y: *i8, + z: *test, +}; + +let print_struct = (s: *test) => void { + println("X: %d", (*s).x); + println("Y: %s", (*s).y); + if (*s).z != cast(*test, null) { + print_struct((*s).z); + }; + return; +}; + +let main = () => i64 { + let inst = cast(*test, malloc(sizeof(test))); + let inst2 = cast(*test, malloc(sizeof(test))); + + print_struct(inst); + + (*inst).x = 4; + (*inst).y = "hi"; + (*inst).z = inst2; + + (*inst2).y = "bye"; + + print_struct(inst); + + return 0; +}; + +/* + +Expected stdout: + +X: 0 +Y: (null) +X: 4 +Y: hi + +Expected return: 0 + +*/ diff --git a/src/codegen.zig b/src/codegen.zig index b60ad95..9be065e 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -727,6 +727,17 @@ pub const CodeGen = struct { .STRUCT_TYPE => |t| { const struct_type = llvm.LLVMStructCreateNamed(self.llvm_context, try std.fmt.allocPrintZ(self.arena, "{s}", .{name.?})); + // Needed for recursive structs + if (name != null) { + try self.environment.add_variable(name.?, try self.create_variable(.{ + .value = null, + .type = struct_type, + .stack_level = null, + .node = expression, + .node_type = expression, + })); + } + var llvm_types = std.ArrayList(llvm.LLVMTypeRef).init(self.arena); for (t.fields) |field| { |