diff --git a/src/compiler.zig b/src/compiler.zig index 81fe6be..8666e11 100644 --- a/src/compiler.zig +++ b/src/compiler.zig @@ -121,6 +121,7 @@ pub const Compiler = struct { scanr: Scanner = undefined, chunk: *chunks.Chunk, debug_flag: bool = false, + vmach: *vm.VM, pub fn init( allocator: *Allocator, @@ -128,6 +129,7 @@ pub const Compiler = struct { stdout: vm.StdOut, source: []const u8, debug_flag: bool, + vmach: *vm.VM, ) Compiler { return Compiler{ .src = source, @@ -136,6 +138,7 @@ pub const Compiler = struct { .stdout = stdout, .parser = Parser{}, .debug_flag = debug_flag, + .vmach = vmach, }; } @@ -231,8 +234,9 @@ pub const Compiler = struct { fn string(self: *Compiler) !void { const lexeme_len = self.parser.previous.lexeme.len; + try self.emitConstant(values.ObjVal(try objects.copyString( - self.allocator, + self.vmach, self.parser.previous.lexeme[1 .. lexeme_len - 1], ))); } diff --git a/src/main.zig b/src/main.zig index 660a9e7..8451723 100644 --- a/src/main.zig +++ b/src/main.zig @@ -17,6 +17,7 @@ fn run(allocator: *Allocator, data: []u8) !void { const stdout = &stdout_file.outStream().stream; var vmach = try vm.VM.init(allocator, stdout, data, true); + defer vmach.deinit(); try vmach.interpret(); } diff --git a/src/object.zig b/src/object.zig index c47cf65..17418df 100644 --- a/src/object.zig +++ b/src/object.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const vm = @import("vm.zig"); const Allocator = std.mem.Allocator; @@ -13,25 +14,36 @@ pub const ObjValue = struct { pub const Object = struct { otype: ObjType, value: ObjValue, + next: ?*Object = null, }; -fn createString(allocator: *Allocator, data: []u8) !*Object { - var obj = try allocator.create(Object); - obj.otype = ObjType.String; - obj.value = ObjValue{ .String = data }; +pub fn allocateObject( + vmach: *vm.VM, + otype: ObjType, + value: ObjValue, +) !*Object { + var obj = try vmach.allocator.create(Object); + obj.otype = otype; + obj.value = value; + + obj.next = vmach.objs; + vmach.objs = obj; return obj; } -pub fn copyString(allocator: *Allocator, data: []const u8) !*Object { - var str = try allocator.alloc(u8, data.len); - std.mem.copy(u8, str, data); +fn createString(vmach: *vm.VM, data: []u8) !*Object { + return allocateObject(vmach, ObjType.String, ObjValue{ .String = data }); +} - return try createString(allocator, str); +pub fn copyString(vmach: *vm.VM, data: []const u8) !*Object { + var str = try vmach.allocator.alloc(u8, data.len); + std.mem.copy(u8, str, data); + return try createString(vmach, str); } /// Assumes it can take ownership of the given data. -pub fn takeString(allocator: *Allocator, data: []u8) !*Object { - return try createString(allocator, data); +pub fn takeString(vmach: *vm.VM, data: []u8) !*Object { + return try createString(vmach, data); } pub fn printObject(stdout: var, obj: Object) !void { diff --git a/src/vm.zig b/src/vm.zig index 40c1ac6..197ba46 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -46,7 +46,9 @@ pub const VM = struct { stdout: StdOut, debug_flag: bool, - allocator: *std.mem.Allocator, + pub allocator: *std.mem.Allocator, + + objs: ?*objects.Object = null, fn resetStack(self: *VM) void { self.stackTop = 0; @@ -72,6 +74,36 @@ pub const VM = struct { return self; } + fn deinitObject(self: *VM, obj: *objects.Object) void { + switch (obj.otype) { + .String => blk: { + self.allocator.free(obj.value.String); + self.allocator.destroy(obj); + break :blk; + }, + else => unreachable, + } + } + + fn deinitObjects(self: *VM) void { + var obj_opt: ?*objects.Object = self.objs; + + // doing a while(obj != null) but with optionals + while (true) { + if (obj_opt) |obj| { + var next = obj.next; + self.deinitObject(obj); + obj_opt = next; + } else { + break; + } + } + } + + pub fn deinit(self: *VM) void { + self.deinitObjects(); + } + pub fn debug(self: *VM, comptime fmt: []const u8, args: ...) void { if (self.debug_flag) { std.debug.warn(fmt, args); @@ -135,7 +167,7 @@ pub const VM = struct { [][]u8{ a, b }, ); - var val = values.ObjVal(try objects.takeString(self.allocator, res_str)); + var val = values.ObjVal(try objects.takeString(self, res_str)); try self.push(val); } @@ -273,6 +305,7 @@ pub const VM = struct { self.stdout, self.src, self.debug_flag, + self, ); if (!try cmpr.compile(&chk)) { return InterpretResult.CompileError;