From 61e463713c8b5ddc8fa7922cefae3d93b53d83d3 Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 1 Jun 2019 15:23:23 -0300 Subject: [PATCH] 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]; + } };