value stack manipulator

This commit is contained in:
Patrick MARIE 2024-08-24 19:18:26 +02:00
parent 1cb8c95fe9
commit a50663cbf2
2 changed files with 36 additions and 12 deletions

View File

@ -13,7 +13,7 @@ pub fn main() !void {
defer _ = debug.assert(gpa.deinit() == .ok); defer _ = debug.assert(gpa.deinit() == .ok);
const allocator = gpa.allocator(); const allocator = gpa.allocator();
var vm = VM.new(); var vm = VM.new(allocator);
var chunk = Chunk.new(); var chunk = Chunk.new();
try chunk.init(allocator); try chunk.init(allocator);
@ -25,7 +25,7 @@ pub fn main() !void {
chunk.dissassemble("test chunk"); chunk.dissassemble("test chunk");
_ = vm.interpret(&chunk); _ = try vm.interpret(&chunk);
vm.free(); vm.free();
chunk.deinit(allocator); chunk.deinit(allocator);

View File

@ -1,4 +1,7 @@
const std = @import("std"); const std = @import("std");
const debug = std.debug;
const Allocator = std.mem.Allocator;
const Chunk = @import("./chunk.zig").Chunk; const Chunk = @import("./chunk.zig").Chunk;
const OpCode = @import("./opcode.zig").OpCode; const OpCode = @import("./opcode.zig").OpCode;
const Value = @import("./values.zig").Value; const Value = @import("./values.zig").Value;
@ -7,6 +10,8 @@ const DEBUG_TRACE_EXECUTION = @import("./main.zig").DEBUG_TRACE_EXECUTION;
const print_value = @import("./values.zig").print_value; const print_value = @import("./values.zig").print_value;
const STACK_MAX = 256;
const InterpretResult = enum { const InterpretResult = enum {
OK, OK,
COMPILE_ERROR, COMPILE_ERROR,
@ -16,28 +21,39 @@ const InterpretResult = enum {
pub const VM = struct { pub const VM = struct {
chunk: ?*Chunk, chunk: ?*Chunk,
ip: ?usize, ip: ?usize,
stack: std.ArrayList(Value),
pub fn new() VM { pub fn new(allocator: Allocator) VM {
return VM{ return VM{
.chunk = null, .chunk = null,
.ip = null, .ip = null,
.stack = std.ArrayList(Value).init(allocator),
}; };
} }
pub fn free(self: *VM) void { pub fn free(self: *VM) void {
_ = self; self.stack.deinit();
} }
pub fn interpret(self: *VM, chunk: *Chunk) InterpretResult { pub fn interpret(self: *VM, chunk: *Chunk) !InterpretResult {
self.chunk = chunk; self.chunk = chunk;
self.ip = 0; self.ip = 0;
return self.run(); return self.run();
} }
pub fn run(self: *VM) InterpretResult { pub fn run(self: *VM) !InterpretResult {
while (true) { while (true) {
if (DEBUG_TRACE_EXECUTION) { if (DEBUG_TRACE_EXECUTION) {
if (self.stack.items.len > 0) {
debug.print("S: ", .{});
for (self.stack.items) |item| {
debug.print("[ ", .{});
print_value(item);
debug.print(" ]", .{});
}
debug.print("\n", .{});
}
_ = self.chunk.?.dissassemble_instruction(self.ip.?); _ = self.chunk.?.dissassemble_instruction(self.ip.?);
} }
@ -46,14 +62,14 @@ pub const VM = struct {
switch (instruction) { switch (instruction) {
@intFromEnum(OpCode.OP_CONSTANT) => { @intFromEnum(OpCode.OP_CONSTANT) => {
const constant = self.read_constant(); const constant = self.read_constant();
try self.push(constant);
// XXX Those should not be std.debug, but stdout. },
print_value(constant); @intFromEnum(OpCode.OP_RETURN) => {
std.debug.print("\n", .{}); print_value(self.pop());
return InterpretResult.OK;
}, },
@intFromEnum(OpCode.OP_RETURN) => return InterpretResult.OK,
else => { else => {
std.debug.print("Invalid instruction: {d}\n", .{instruction}); debug.print("Invalid instruction: {d}\n", .{instruction});
return InterpretResult.RUNTIME_ERROR; return InterpretResult.RUNTIME_ERROR;
}, },
} }
@ -74,4 +90,12 @@ pub const VM = struct {
pub fn read_constant(self: *VM) Value { pub fn read_constant(self: *VM) Value {
return self.chunk.?.constants.values[read_byte(self)]; return self.chunk.?.constants.values[read_byte(self)];
} }
pub fn push(self: *VM, value: Value) !void {
try self.stack.append(value);
}
pub fn pop(self: *VM) Value {
return self.stack.pop();
}
}; };