Compare commits

...

2 Commits

Author SHA1 Message Date
Luna 2822676707 vm: add negate opcode 2019-06-01 15:27:19 -03:00
Luna 61e463713c vm: add stack 2019-06-01 15:23:23 -03:00
3 changed files with 54 additions and 8 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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,19 +93,22 @@ 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;
},
chunk.OpCode.Negate => self.push(-self.pop()),
else => blk: {
std.debug.warn("Unknown instruction: {x}\n", instruction);
return InterpretResult.RuntimeError;
@ -93,4 +125,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];
}
};