From e921a0dda85ec80bfdae61e2e203848f7e24a978 Mon Sep 17 00:00:00 2001 From: Araozu Date: Mon, 27 May 2024 21:08:29 -0500 Subject: [PATCH] VM simple execution --- src/chunk.zig | 5 +++-- src/main.zig | 14 +++++++++++++ src/vm.zig | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/vm.zig diff --git a/src/chunk.zig b/src/chunk.zig index bf1257e..1c50b84 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -55,6 +55,7 @@ pub const Chunk = struct { /// Prints the value of a single instruction fn dissasemble_instruction(self: *Chunk, offset: usize) usize { + // Print the instruction offset print("{d:0>4} ", .{offset}); // Print the line number @@ -65,7 +66,7 @@ pub const Chunk = struct { } const instruction = self.code[offset]; - switch (instruction) { + switch (self.code[offset]) { @intFromEnum(OpCode.OP_RETURN) => return simple_instruction("OP_RETURN", offset), @intFromEnum(OpCode.OP_CONSTANT) => return self.constant_instruction("OP_CONSTANT", offset), else => { @@ -102,7 +103,7 @@ fn simple_instruction(comptime name: []const u8, offset: usize) usize { return offset + 1; } -fn print_value(v: value.Value) void { +pub fn print_value(v: value.Value) void { print("{d}", .{v}); } diff --git a/src/main.zig b/src/main.zig index 9679336..01d2576 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,6 +1,7 @@ const std = @import("std"); const chunk = @import("./chunk.zig"); const OpCode = chunk.OpCode; +const VM = @import("./vm.zig").VM; pub fn main() !void { // Prints to stderr (it's a shortcut based on `std.io.getStdErr()`) @@ -19,12 +20,25 @@ pub fn main() !void { try c.write(@intFromEnum(chunk.OpCode.OP_RETURN), 1); c.dissasemble_chunk("test chunk"); + + std.debug.print("\n=== end of chunk creation ===\n\n", .{}); + + var vm = VM.init(alloc, &c); + defer vm.deinit(); + + _ = vm.run(); } test "chunk test" { var c = try chunk.Chunk.init(std.testing.allocator); defer c.deinit(); + const constant_idx = try c.add_constant(1.2); + try c.write(@intFromEnum(OpCode.OP_CONSTANT), 1); + try c.write(@truncate(constant_idx), 1); + + try c.write(@intFromEnum(chunk.OpCode.OP_RETURN), 1); + try c.write('a', 0); try c.write('b', 1); try c.write('J', 2); diff --git a/src/vm.zig b/src/vm.zig new file mode 100644 index 0000000..452fb8d --- /dev/null +++ b/src/vm.zig @@ -0,0 +1,56 @@ +const std = @import("std"); +const chunk_mod = @import("./chunk.zig"); +const Chunk = chunk_mod.Chunk; +const OpCode = chunk_mod.OpCode; +const print = std.debug.print; + +const InterpretResult = enum { + Ok, + CompileError, + RuntimeError, +}; + +pub const VM = struct { + chunk: *Chunk, + ip: [*]const u8, + allocator: std.mem.Allocator, + + // Takes ownership of the passed Chunk. This chunk will be deinitialized + // when this VM is deinitialized + pub fn init(allocator: std.mem.Allocator, chunk: *Chunk) VM { + return .{ + .allocator = allocator, + .chunk = chunk, + .ip = chunk.code.ptr, + }; + } + + // Executes the instructions in the bytecode + pub fn run(self: *VM) InterpretResult { + while (true) { + const next = self.ip[0]; + self.ip += 1; + switch (next) { + @intFromEnum(OpCode.OP_RETURN) => { + return InterpretResult.Ok; + }, + @intFromEnum(OpCode.OP_CONSTANT) => { + const constant = self.chunk.constants.values[self.ip[0]]; + self.ip += 1; + chunk_mod.print_value(constant); + print("\n", .{}); + }, + else => { + std.debug.print("Not implemented!\n", .{}); + unreachable; + }, + } + } + + return null; + } + + pub fn deinit(self: VM) void { + _ = self; + } +};