VM simple execution

This commit is contained in:
Araozu 2024-05-27 21:08:29 -05:00
parent 0f891e4275
commit e921a0dda8
3 changed files with 73 additions and 2 deletions

View File

@ -55,6 +55,7 @@ pub const Chunk = struct {
/// Prints the value of a single instruction /// Prints the value of a single instruction
fn dissasemble_instruction(self: *Chunk, offset: usize) usize { fn dissasemble_instruction(self: *Chunk, offset: usize) usize {
// Print the instruction offset
print("{d:0>4} ", .{offset}); print("{d:0>4} ", .{offset});
// Print the line number // Print the line number
@ -65,7 +66,7 @@ pub const Chunk = struct {
} }
const instruction = self.code[offset]; const instruction = self.code[offset];
switch (instruction) { switch (self.code[offset]) {
@intFromEnum(OpCode.OP_RETURN) => return simple_instruction("OP_RETURN", offset), @intFromEnum(OpCode.OP_RETURN) => return simple_instruction("OP_RETURN", offset),
@intFromEnum(OpCode.OP_CONSTANT) => return self.constant_instruction("OP_CONSTANT", offset), @intFromEnum(OpCode.OP_CONSTANT) => return self.constant_instruction("OP_CONSTANT", offset),
else => { else => {
@ -102,7 +103,7 @@ fn simple_instruction(comptime name: []const u8, offset: usize) usize {
return offset + 1; return offset + 1;
} }
fn print_value(v: value.Value) void { pub fn print_value(v: value.Value) void {
print("{d}", .{v}); print("{d}", .{v});
} }

View File

@ -1,6 +1,7 @@
const std = @import("std"); const std = @import("std");
const chunk = @import("./chunk.zig"); const chunk = @import("./chunk.zig");
const OpCode = chunk.OpCode; const OpCode = chunk.OpCode;
const VM = @import("./vm.zig").VM;
pub fn main() !void { pub fn main() !void {
// Prints to stderr (it's a shortcut based on `std.io.getStdErr()`) // 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); try c.write(@intFromEnum(chunk.OpCode.OP_RETURN), 1);
c.dissasemble_chunk("test chunk"); 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" { test "chunk test" {
var c = try chunk.Chunk.init(std.testing.allocator); var c = try chunk.Chunk.init(std.testing.allocator);
defer c.deinit(); 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('a', 0);
try c.write('b', 1); try c.write('b', 1);
try c.write('J', 2); try c.write('J', 2);

56
src/vm.zig Normal file
View File

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