VM simple execution
parent
0f891e4275
commit
e921a0dda8
|
@ -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});
|
||||
}
|
||||
|
||||
|
|
14
src/main.zig
14
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue