value stack manipulator
This commit is contained in:
parent
1cb8c95fe9
commit
a50663cbf2
@ -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);
|
||||||
|
44
src/vm.zig
44
src/vm.zig
@ -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();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user