VM simple execution
This commit is contained in:
parent
0f891e4275
commit
e921a0dda8
@ -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});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
src/main.zig
14
src/main.zig
@ -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
56
src/vm.zig
Normal 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;
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user