forked from luna/jorts
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 Chunk = chunk.Chunk;
|
||||||
const StdOut = *std.io.OutStream(std.fs.File.WriteError);
|
const StdOut = *std.io.OutStream(std.fs.File.WriteError);
|
||||||
|
|
||||||
|
pub const STACK_MAX = 256;
|
||||||
|
|
||||||
pub const InterpretResult = enum {
|
pub const InterpretResult = enum {
|
||||||
Ok,
|
Ok,
|
||||||
CompileError,
|
CompileError,
|
||||||
|
@ -13,17 +15,31 @@ pub const InterpretResult = enum {
|
||||||
|
|
||||||
pub const VM = struct {
|
pub const VM = struct {
|
||||||
chk: *Chunk,
|
chk: *Chunk,
|
||||||
ip: usize,
|
ip: usize = 0,
|
||||||
|
|
||||||
|
stack: [STACK_MAX]value.Value,
|
||||||
|
stackTop: usize = 0,
|
||||||
|
|
||||||
stdout: StdOut,
|
stdout: StdOut,
|
||||||
debug_flag: bool,
|
debug_flag: bool,
|
||||||
|
|
||||||
|
fn resetStack(self: *VM) void {
|
||||||
|
self.stackTop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init(stdout: StdOut, chk: *Chunk, debug_flag: bool) VM {
|
pub fn init(stdout: StdOut, chk: *Chunk, debug_flag: bool) VM {
|
||||||
return VM{
|
var self = VM{
|
||||||
.stdout = stdout,
|
|
||||||
.chk = chk,
|
.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,
|
.debug_flag = debug_flag,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.resetStack();
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug(self: *VM, comptime fmt: []const u8, args: ...) void {
|
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];
|
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 {
|
fn run(self: *VM) !InterpretResult {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (self.debug_flag) {
|
if (self.debug_flag) {
|
||||||
|
try self.debugStack();
|
||||||
_ = try self.chk.disassembleInstruction(self.stdout, self.ip);
|
_ = try self.chk.disassembleInstruction(self.stdout, self.ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,17 +93,18 @@ pub const VM = struct {
|
||||||
switch (instruction) {
|
switch (instruction) {
|
||||||
chunk.OpCode.Constant => blk: {
|
chunk.OpCode.Constant => blk: {
|
||||||
var constant = self.readConst();
|
var constant = self.readConst();
|
||||||
try value.printValue(self.stdout, constant);
|
self.push(constant);
|
||||||
try self.stdout.write("\n");
|
|
||||||
break :blk;
|
break :blk;
|
||||||
},
|
},
|
||||||
chunk.OpCode.ConstantLong => blk: {
|
chunk.OpCode.ConstantLong => blk: {
|
||||||
var constant = self.readConstLong();
|
var constant = self.readConstLong();
|
||||||
try value.printValue(self.stdout, constant);
|
self.push(constant);
|
||||||
try self.stdout.write("\n");
|
|
||||||
break :blk;
|
break :blk;
|
||||||
},
|
},
|
||||||
|
|
||||||
chunk.OpCode.Return => blk: {
|
chunk.OpCode.Return => blk: {
|
||||||
|
try value.printValue(self.stdout, self.pop());
|
||||||
|
try self.stdout.print("\n");
|
||||||
return InterpretResult.Ok;
|
return InterpretResult.Ok;
|
||||||
},
|
},
|
||||||
else => blk: {
|
else => blk: {
|
||||||
|
@ -93,4 +123,14 @@ pub const VM = struct {
|
||||||
self.debug("VM end\n");
|
self.debug("VM end\n");
|
||||||
return res;
|
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