fix: broken conditionals

This commit is contained in:
Brett Broadhurst 2026-03-30 05:44:35 -06:00
parent b231e66b49
commit 97a43f63eb
Failed to generate hash of commit
33 changed files with 358 additions and 313 deletions

View file

@ -18,7 +18,7 @@ stack_top: usize = 0,
call_stack_top: usize = 0,
current_choices: std.ArrayListUnmanaged(Choice) = .empty,
code_chunks: std.ArrayListUnmanaged(*Object.Code) = .empty,
globals: std.StringHashMapUnmanaged(?Value) = .empty,
globals: std.StringHashMapUnmanaged(Value) = .empty,
stack: []Value = &.{},
call_stack: []CallFrame = &.{},
/// Global constants pool.
@ -139,18 +139,28 @@ pub const Value = union(enum) {
pub fn eql(lhs: Value, rhs: Value) bool {
return switch (lhs) {
.nil => rhs == .nil,
.bool => |l| rhs == .bool and l == rhs.bool,
.bool => |l| switch (rhs) {
.bool => |r| l == r,
else => false,
},
.int => |l| switch (rhs) {
.int => |r| l == r,
.float => |r| @as(f64, @floatFromInt(l)) == r,
else => false,
},
.float => |l| switch (rhs) {
.int => |r| l == @as(f64, @floatFromInt(r)),
.float => |r| l == r,
else => false,
},
.object => |l| rhs == .object and l == rhs.object,
.object => |lobj| switch (rhs) {
.object => |robj| Object.eql(lobj, robj),
else => false,
},
};
}
@ -350,12 +360,10 @@ fn getConstant(story: *Story, frame: *CallFrame, offset: u8) !Value {
}
fn getLocal(vm: *Story, frame: *CallFrame, offset: u8) ?Value {
assert(vm.stack_top > frame.sp + offset);
return vm.stack[frame.sp + offset];
}
fn setLocal(vm: *Story, frame: *CallFrame, offset: u8, value: Value) void {
assert(vm.stack_top > frame.sp + offset);
vm.stack[frame.sp + offset] = value;
}
@ -366,8 +374,7 @@ fn getGlobal(vm: *Story, key: Value) !Value {
.string => {
const str_object: *Object.String = @ptrCast(object);
if (vm.globals.get(str_object.toSlice())) |value| {
// FIXME: Support for nil
return value.?;
return value;
}
return error.InvalidVariable;
},
@ -578,8 +585,8 @@ fn execute(vm: *Story) !std.ArrayListUnmanaged(u8) {
frame.ip += 2;
},
.store => {
if (vm.peekStack(0)) |arg| {
const arg_offset: u8 = @intFromEnum(code[frame.ip + 1]);
const arg_offset: u8 = @intFromEnum(code[frame.ip + 1]);
if (peekStack(vm, 0)) |arg| {
vm.setLocal(frame, arg_offset, arg);
} else {
return error.InvalidArgument;
@ -696,7 +703,7 @@ pub fn getKnot(vm: *Story, name: []const u8) ?*Object.Knot {
const knot: ?*Object.Knot = blk: {
if (vm.globals.get(name)) |value| {
// TODO: Do a check here.
break :blk @ptrCast(value.?.object);
break :blk @ptrCast(value.object);
}
break :blk null;
};