vm: add stack
This commit is contained in:
parent
456bc95138
commit
61e463713c
1 changed files with 48 additions and 8 deletions
56
src/vm.zig
56
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];
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue