From 61e463713c8b5ddc8fa7922cefae3d93b53d83d3 Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 1 Jun 2019 15:23:23 -0300 Subject: [PATCH 1/2] vm: add stack --- src/vm.zig | 56 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/src/vm.zig b/src/vm.zig index 1765c6c..b4243b8 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -5,6 +5,8 @@ const value = @import("value.zig"); const Chunk = chunk.Chunk; const StdOut = *std.io.OutStream(std.fs.File.WriteError); +pub const STACK_MAX = 256; + pub const InterpretResult = enum { Ok, CompileError, @@ -13,17 +15,31 @@ pub const InterpretResult = enum { pub const VM = struct { chk: *Chunk, - ip: usize, + ip: usize = 0, + + stack: [STACK_MAX]value.Value, + stackTop: usize = 0, + stdout: StdOut, debug_flag: bool, + fn resetStack(self: *VM) void { + self.stackTop = 0; + } + pub fn init(stdout: StdOut, chk: *Chunk, debug_flag: bool) VM { - return VM{ - .stdout = stdout, + var self = VM{ .chk = chk, - .ip = 0, + + // TODO move this to a nil value or something. + .stack = []value.Value{0} ** STACK_MAX, + .stdout = stdout, .debug_flag = debug_flag, }; + + self.resetStack(); + + return self; } pub fn debug(self: *VM, comptime fmt: []const u8, args: ...) void { @@ -53,9 +69,22 @@ pub const VM = struct { return self.chk.constants.values[const_idx]; } + fn debugStack(self: *VM) !void { + try self.stdout.print(" "); + for (self.stack) |val, idx| { + if (idx >= self.stackTop) break; + + try self.stdout.print("[ "); + try value.printValue(self.stdout, val); + try self.stdout.print(" ]"); + } + try self.stdout.print("\n"); + } + fn run(self: *VM) !InterpretResult { while (true) { if (self.debug_flag) { + try self.debugStack(); _ = try self.chk.disassembleInstruction(self.stdout, self.ip); } @@ -64,17 +93,18 @@ pub const VM = struct { switch (instruction) { chunk.OpCode.Constant => blk: { var constant = self.readConst(); - try value.printValue(self.stdout, constant); - try self.stdout.write("\n"); + self.push(constant); break :blk; }, chunk.OpCode.ConstantLong => blk: { var constant = self.readConstLong(); - try value.printValue(self.stdout, constant); - try self.stdout.write("\n"); + self.push(constant); break :blk; }, + chunk.OpCode.Return => blk: { + try value.printValue(self.stdout, self.pop()); + try self.stdout.print("\n"); return InterpretResult.Ok; }, else => blk: { @@ -93,4 +123,14 @@ pub const VM = struct { self.debug("VM end\n"); return res; } + + pub fn push(self: *VM, val: value.Value) void { + self.stack[self.stackTop] = val; + self.stackTop += 1; + } + + pub fn pop(self: *VM) value.Value { + self.stackTop -= 1; + return self.stack[self.stackTop]; + } }; From 282267670714be07f05713191ca91cf31ea09f9e Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 1 Jun 2019 15:27:19 -0300 Subject: [PATCH 2/2] vm: add negate opcode --- src/chunk.zig | 3 +++ src/main.zig | 1 + src/vm.zig | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/chunk.zig b/src/chunk.zig index 491d52b..db17a34 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -8,6 +8,7 @@ const AllOpcodes = struct { pub Constant: u8 = 0, pub ConstantLong: u8 = 1, pub Return: u8 = 2, + pub Negate: u8 = 3, }; pub const OpCode = AllOpcodes{}; @@ -148,6 +149,8 @@ pub const Chunk = struct { self, index, ); + } else if (instruction == OpCode.Negate) { + return try simpleInstruction(stdout, "OP_NEGATE", index); } else { try stdout.print("Unknown opcode: {}\n", instruction); return index + 1; diff --git a/src/main.zig b/src/main.zig index 1d4bdc7..d493e1a 100644 --- a/src/main.zig +++ b/src/main.zig @@ -117,6 +117,7 @@ pub fn main() !void { //try chk.write(chunk.OpCode.Return); var constant = try chk.writeConstant(1.2, 123); + try chk.write(chunk.OpCode.Negate, 123); try chk.write(chunk.OpCode.Return, 123); var vmach = vm.VM.init(stdout, &chk, true); diff --git a/src/vm.zig b/src/vm.zig index b4243b8..5d74853 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -107,6 +107,8 @@ pub const VM = struct { try self.stdout.print("\n"); return InterpretResult.Ok; }, + + chunk.OpCode.Negate => self.push(-self.pop()), else => blk: { std.debug.warn("Unknown instruction: {x}\n", instruction); return InterpretResult.RuntimeError;