feat: code generation and execution for simple choice statements

This commit is contained in:
Brett Broadhurst 2026-03-02 21:16:24 -07:00
parent 55346fcd85
commit 889f678dd8
Failed to generate hash of commit
4 changed files with 389 additions and 179 deletions

View file

@ -38,21 +38,33 @@ fn dumpGlobalInst(
return offset + 2;
}
const Jump = enum {
relative,
absolute,
};
fn dumpJumpInst(
d: Dumper,
context: *const Object.ContentPath,
offset: usize,
op: Opcode,
mode: Jump,
) !usize {
var jump: u16 = @as(u16, context.bytes[offset + 1]) << 8;
jump |= context.bytes[offset + 2];
try d.writer.print("{s} 0x{x:0>4} (0x{x:0>4} -> 0x{x:0>4})\n", .{
@tagName(op),
jump,
offset,
offset + 3 + jump,
});
switch (mode) {
.relative => try d.writer.print("{s} 0x{x:0>4} (0x{x:0>4} -> 0x{x:0>4})\n", .{
@tagName(op),
jump,
offset,
offset + 3 + jump,
}),
.absolute => try d.writer.print("{s} 0x{x:0>4}\n", .{
@tagName(op),
jump,
}),
}
return offset + 3;
}
@ -72,43 +84,41 @@ pub fn dumpInst(
try d.writer.print("0x{x:0>4} | ", .{offset});
}
switch (op) {
.exit,
.ret,
.pop,
.true,
.false,
.add,
.sub,
.mul,
.div,
.mod,
.neg,
.not,
.cmp_eq,
.cmp_lt,
.cmp_lte,
.cmp_gt,
.cmp_gte,
.flush,
.load_choice_id,
.content,
.choice,
.line,
.glue,
=> return d.dumpSimpleInst(offset, op),
.load_const,
.load,
.store,
=> return d.dumpByteInst(path, offset, op),
.load_global,
.store_global,
.call,
.divert,
=> return d.dumpGlobalInst(path, offset, op),
.jmp,
.jmp_t,
.jmp_f,
=> return d.dumpJumpInst(path, offset, op),
.exit => return d.dumpSimpleInst(offset, op),
.ret => return d.dumpSimpleInst(offset, op),
.pop => return d.dumpSimpleInst(offset, op),
.true => return d.dumpSimpleInst(offset, op),
.false => return d.dumpSimpleInst(offset, op),
.add => return d.dumpSimpleInst(offset, op),
.sub => return d.dumpSimpleInst(offset, op),
.mul => return d.dumpSimpleInst(offset, op),
.div => return d.dumpSimpleInst(offset, op),
.mod => return d.dumpSimpleInst(offset, op),
.neg => return d.dumpSimpleInst(offset, op),
.not => return d.dumpSimpleInst(offset, op),
.cmp_eq => return d.dumpSimpleInst(offset, op),
.cmp_lt => return d.dumpSimpleInst(offset, op),
.cmp_lte => return d.dumpSimpleInst(offset, op),
.cmp_gt => return d.dumpSimpleInst(offset, op),
.cmp_gte => return d.dumpSimpleInst(offset, op),
.load_const => return d.dumpByteInst(path, offset, op),
.load => return d.dumpByteInst(path, offset, op),
.store => return d.dumpByteInst(path, offset, op),
.load_global => return d.dumpGlobalInst(path, offset, op),
.store_global => return d.dumpGlobalInst(path, offset, op),
.call => return d.dumpGlobalInst(path, offset, op),
.divert => return d.dumpGlobalInst(path, offset, op),
.jmp => return d.dumpJumpInst(path, offset, op, .relative),
.jmp_t => return d.dumpJumpInst(path, offset, op, .relative),
.jmp_f => return d.dumpJumpInst(path, offset, op, .relative),
.stream_push => return d.dumpSimpleInst(offset, op),
.stream_flush => return d.dumpSimpleInst(offset, op),
.stream_line => return d.dumpSimpleInst(offset, op),
.stream_glue => return d.dumpSimpleInst(offset, op),
.br_push => return d.dumpJumpInst(path, offset, op, .absolute),
.br_table => return d.dumpSimpleInst(offset, op),
.br_dispatch => return d.dumpSimpleInst(offset, op),
.br_select_index => return d.dumpSimpleInst(offset, op),
else => |code| {
try d.writer.print("Unknown opcode 0x{x:0>4}\n", .{@intFromEnum(code)});
return offset + 1;