feat: added Ir.Inst.Ref, global constant pool, lazy lowering in Sema

This commit is contained in:
Brett Broadhurst 2026-03-11 20:15:52 -06:00
parent ce5385ebac
commit e5e2b7c559
Failed to generate hash of commit
6 changed files with 615 additions and 534 deletions

View file

@ -15,6 +15,7 @@ is_exited: bool = false,
can_advance: bool = false,
choice_index: usize = 0,
current_choices: std.ArrayListUnmanaged(Choice) = .empty,
constants_pool: std.ArrayListUnmanaged(*Object) = .empty,
globals: std.StringHashMapUnmanaged(?*Object) = .empty,
paths: std.ArrayListUnmanaged(*Object) = .empty,
stack: std.ArrayListUnmanaged(?*Object) = .empty,
@ -101,6 +102,7 @@ pub fn deinit(story: *Story) void {
}
story.current_choices.deinit(gpa);
story.constants_pool.deinit(gpa);
story.globals.deinit(gpa);
story.paths.deinit(gpa);
story.stack.deinit(gpa);
@ -109,6 +111,24 @@ pub fn deinit(story: *Story) void {
pub fn dump(story: *Story, writer: *std.Io.Writer) !void {
const story_dumper: Dumper = .{ .story = story, .writer = writer };
try writer.writeAll("=== Constants ===\n");
for (story.constants_pool.items) |global_constant| {
try story_dumper.dumpObject(global_constant);
try writer.writeAll("\n");
}
try writer.writeAll("\n");
try writer.writeAll("=== Globals ===\n");
var global_iter = story.globals.iterator();
while (global_iter.next()) |entry| {
try writer.print("{s} => ...\n", .{entry.key_ptr.*});
}
try writer.writeAll("\n");
try writer.writeAll("=== Knots ===\n");
for (story.paths.items) |path_object| {
try story_dumper.dump(@ptrCast(path_object));
}
@ -152,8 +172,7 @@ fn currentFrame(vm: *Story) *CallFrame {
fn peekStack(vm: *Story, offset: usize) ?*Object {
const stack_top = vm.stack.items.len;
assert(stack_top > offset);
assert(stack_top != 0);
if (stack_top <= offset) return null;
return vm.stack.items[stack_top - offset - 1];
}
@ -171,10 +190,11 @@ fn popStack(vm: *Story) ?*Object {
return vm.stack.pop() orelse unreachable;
}
fn getConstant(_: *Story, frame: *CallFrame, offset: u8) !*Object {
const constant_pool = frame.callee.const_pool;
if (offset >= constant_pool.len) return error.InvalidArgument;
return constant_pool[offset];
fn getConstant(story: *Story, frame: *CallFrame, offset: u8) !*Object {
if (offset >= frame.callee.const_pool.len) return error.InvalidArgument;
const constant_index = frame.callee.const_pool[offset];
return story.constants_pool.items[constant_index];
}
fn getLocal(vm: *Story, frame: *CallFrame, offset: u8) ?*Object {
@ -380,14 +400,17 @@ fn execute(vm: *Story) !std.ArrayListUnmanaged(u8) {
frame.ip += 2;
},
.stream_push => {
const arg_object = vm.popStack();
if (arg_object) |object| {
// FIXME: This should be more strict.
// Its not because theres a bug in when these instructions are
// emitted.
if (vm.peekStack(0)) |object| {
const string_object = try Object.String.fromObject(vm, object);
const string_bytes = string_object.bytes[0..string_object.length];
try stream_writer.writer.writeAll(string_bytes);
} else {
return error.InvalidArgument;
}
_ = vm.popStack();
} //else {
//return error.InvalidArgument;
//}
frame.ip += 1;
},