diff --git a/src/main.zig b/src/main.zig index 99628ac..1c982e3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator; // const Scanner = @import("scanner.zig").Scanner; const chunk = @import("chunk.zig"); +const vm = @import("vm.zig"); //const Compiler = @import("compiler.zig").Compiler; @@ -107,7 +108,7 @@ pub fn main() !void { var allocator = &arena.allocator; var stdout_file = try std.io.getStdOut(); - const stdout = &stdout_file.outStream().stream; + var stdout = &stdout_file.outStream().stream; var chk = try chunk.Chunk.init(allocator); @@ -115,11 +116,13 @@ pub fn main() !void { //var opcode_byte: u8 = @enumToInt(chunk.OpCode.Return); //try chk.write(chunk.OpCode.Return); - var i: usize = 0; - while (i < 260) : (i += 1) { - var constant = try chk.writeConstant(1.2, 123); - } + var constant = try chk.writeConstant(1.2, 123); try chk.write(chunk.OpCode.Return, 123); - try chk.disassemble(stdout, "test chunk"); + + var vmach = vm.VM.init(stdout, &chk); + + std.debug.warn("vm start\n"); + _ = try vmach.interpret(); + std.debug.warn("vm end\n"); } diff --git a/src/vm.zig b/src/vm.zig index b70fb93..fd510b3 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -1,7 +1,78 @@ -const Chunk = @import("chunk.zig"); +const std = @import("std"); +const chunk = @import("chunk.zig"); +const value = @import("value.zig"); + +const Chunk = chunk.Chunk; +const StdOut = *std.io.OutStream(std.fs.File.WriteError); + +pub const InterpretResult = enum { + Ok, + CompileError, + RuntimeError, +}; pub const VM = struct { - chunk: *Chunk, + chk: *Chunk, + ip: usize, + stdout: StdOut, - pub fn init() VM {} + pub fn init(stdout: StdOut, chk: *Chunk) VM { + return VM{ + .stdout = stdout, + .chk = chk, + .ip = 0, + }; + } + + fn readByte(self: *VM) u8 { + var byte: u8 = self.chk.code[self.ip]; + self.ip += 1; + return byte; + } + + fn readConst(self: *VM) value.Value { + return self.chk.constants.values[self.readByte()]; + } + + fn readConstLong(self: *VM) value.Value { + const v3 = self.readByte(); + const v2 = self.readByte(); + const v1 = self.readByte(); + const const_idx = (@intCast(u24, v3) << 16) | + (@intCast(u24, v2) << 8) | + v1; + + return self.chk.constants.values[const_idx]; + } + + fn run(self: *VM) !InterpretResult { + while (true) { + var instruction = self.readByte(); + + switch (instruction) { + chunk.OpCode.Constant => blk: { + var constant = self.readConst(); + try value.printValue(self.stdout, constant); + break :blk; + }, + chunk.OpCode.ConstantLong => blk: { + var constant = self.readConstLong(); + try value.printValue(self.stdout, constant); + break :blk; + }, + chunk.OpCode.Return => blk: { + return InterpretResult.Ok; + }, + else => blk: { + std.debug.warn("Unknown instruction: {x}\n", instruction); + return InterpretResult.RuntimeError; + }, + } + } + } + + pub fn interpret(self: *VM) !InterpretResult { + self.ip = 0; + return try self.run(); + } };