diff --git a/src/main.zig b/src/main.zig index a1b83b7..f716e1f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -13,7 +13,7 @@ pub fn main() !void { defer _ = debug.assert(gpa.deinit() == .ok); const allocator = gpa.allocator(); - var vm = VM.new(); + var vm = VM.new(allocator); var chunk = Chunk.new(); try chunk.init(allocator); @@ -25,7 +25,7 @@ pub fn main() !void { chunk.dissassemble("test chunk"); - _ = vm.interpret(&chunk); + _ = try vm.interpret(&chunk); vm.free(); chunk.deinit(allocator); diff --git a/src/vm.zig b/src/vm.zig index a2d8154..bfc94ad 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -1,4 +1,7 @@ const std = @import("std"); +const debug = std.debug; +const Allocator = std.mem.Allocator; + const Chunk = @import("./chunk.zig").Chunk; const OpCode = @import("./opcode.zig").OpCode; const Value = @import("./values.zig").Value; @@ -7,6 +10,8 @@ const DEBUG_TRACE_EXECUTION = @import("./main.zig").DEBUG_TRACE_EXECUTION; const print_value = @import("./values.zig").print_value; +const STACK_MAX = 256; + const InterpretResult = enum { OK, COMPILE_ERROR, @@ -16,28 +21,39 @@ const InterpretResult = enum { pub const VM = struct { chunk: ?*Chunk, ip: ?usize, + stack: std.ArrayList(Value), - pub fn new() VM { + pub fn new(allocator: Allocator) VM { return VM{ .chunk = null, .ip = null, + .stack = std.ArrayList(Value).init(allocator), }; } pub fn free(self: *VM) void { - _ = self; + self.stack.deinit(); } - pub fn interpret(self: *VM, chunk: *Chunk) InterpretResult { + pub fn interpret(self: *VM, chunk: *Chunk) !InterpretResult { self.chunk = chunk; self.ip = 0; return self.run(); } - pub fn run(self: *VM) InterpretResult { + pub fn run(self: *VM) !InterpretResult { while (true) { if (DEBUG_TRACE_EXECUTION) { + if (self.stack.items.len > 0) { + debug.print("S: ", .{}); + for (self.stack.items) |item| { + debug.print("[ ", .{}); + print_value(item); + debug.print(" ]", .{}); + } + debug.print("\n", .{}); + } _ = self.chunk.?.dissassemble_instruction(self.ip.?); } @@ -46,14 +62,14 @@ pub const VM = struct { switch (instruction) { @intFromEnum(OpCode.OP_CONSTANT) => { const constant = self.read_constant(); - - // XXX Those should not be std.debug, but stdout. - print_value(constant); - std.debug.print("\n", .{}); + try self.push(constant); + }, + @intFromEnum(OpCode.OP_RETURN) => { + print_value(self.pop()); + return InterpretResult.OK; }, - @intFromEnum(OpCode.OP_RETURN) => return InterpretResult.OK, else => { - std.debug.print("Invalid instruction: {d}\n", .{instruction}); + debug.print("Invalid instruction: {d}\n", .{instruction}); return InterpretResult.RUNTIME_ERROR; }, } @@ -74,4 +90,12 @@ pub const VM = struct { pub fn read_constant(self: *VM) Value { return self.chunk.?.constants.values[read_byte(self)]; } + + pub fn push(self: *VM, value: Value) !void { + try self.stack.append(value); + } + + pub fn pop(self: *VM) Value { + return self.stack.pop(); + } };