refactor: new direction for error reporting

This commit is contained in:
Brett Broadhurst 2026-03-18 17:52:07 -06:00
parent 72b686d750
commit c940374f27
Failed to generate hash of commit
11 changed files with 758 additions and 582 deletions

View file

@ -1,16 +1,16 @@
const std = @import("std");
const Ir = @import("Ir.zig");
const Story = @import("Story.zig");
const Object = Story.Object;
const Compilation = @import("compile.zig").Compilation;
const assert = std.debug.assert;
const Sema = @This();
gpa: std.mem.Allocator,
ir: *const Ir,
constants: std.ArrayListUnmanaged(CompiledStory.Constant) = .empty,
constant_map: std.AutoHashMapUnmanaged(CompiledStory.Constant, u32) = .empty,
constants: std.ArrayListUnmanaged(Compilation.Constant) = .empty,
constant_map: std.AutoHashMapUnmanaged(Compilation.Constant, u32) = .empty,
knots: std.ArrayListUnmanaged(Compilation.Knot) = .empty,
globals: std.ArrayListUnmanaged(u32) = .empty,
knots: std.ArrayListUnmanaged(CompiledStory.Knot) = .empty,
const InnerError = error{
OutOfMemory,
@ -28,7 +28,7 @@ const Ref = union(enum) {
local: u32,
};
fn deinit(sema: *Sema) void {
pub fn deinit(sema: *Sema) void {
const gpa = sema.gpa;
sema.constants.deinit(gpa);
sema.constant_map.deinit(gpa);
@ -41,7 +41,7 @@ fn fail(_: *Sema, message: []const u8) InnerError {
@panic(message);
}
fn getConstant(sema: *Sema, data: CompiledStory.Constant) !Ref {
fn getConstant(sema: *Sema, data: Compilation.Constant) !Ref {
const gpa = sema.gpa;
if (sema.constant_map.get(data)) |index| {
@ -343,7 +343,7 @@ fn irDeclKnot(
const data = sema.ir.instructions[@intFromEnum(inst)].data.payload;
const extra = sema.ir.extraData(Ir.Inst.Knot, data.payload_index);
var knot: CompiledStory.Knot = .{
var knot: Compilation.Knot = .{
.name = name_ref,
.arity = 0,
.stack_size = 0,
@ -505,7 +505,7 @@ fn blockBodyInner(sema: *Sema, chunk: *Chunk, body: []const Ir.Inst.Index) Inner
}
}
fn file(sema: *Sema, inst: Ir.Inst.Index) !void {
pub fn analyzeFile(sema: *Sema, inst: Ir.Inst.Index) !void {
const data = sema.ir.instructions[@intFromEnum(inst)].data.payload;
const extra = sema.ir.extraData(Ir.Inst.Block, data.payload_index);
const body = sema.ir.bodySlice(extra.end, extra.data.body_len);
@ -520,7 +520,7 @@ fn file(sema: *Sema, inst: Ir.Inst.Index) !void {
const Chunk = struct {
sema: *Sema,
knot: *CompiledStory.Knot,
knot: *Compilation.Knot,
labels: std.ArrayListUnmanaged(Label) = .empty,
fixups: std.ArrayListUnmanaged(Fixup) = .empty,
inst_map: std.AutoHashMapUnmanaged(Ir.Inst.Index, Ref) = .empty,
@ -666,95 +666,3 @@ const Chunk = struct {
}
}
};
pub const CompiledStory = struct {
knots: []Knot,
constants: []Constant,
globals: []u32,
pub const Knot = struct {
name: Ir.NullTerminatedString,
arity: u32,
stack_size: u32,
constants: std.ArrayListUnmanaged(u32) = .empty,
bytecode: std.ArrayListUnmanaged(u8) = .empty,
};
pub const Constant = union(enum) {
integer: u64,
string: Ir.NullTerminatedString,
};
pub fn deinit(self: *CompiledStory, gpa: std.mem.Allocator) void {
for (self.knots) |*knot| {
knot.constants.deinit(gpa);
knot.bytecode.deinit(gpa);
}
gpa.free(self.knots);
gpa.free(self.globals);
gpa.free(self.constants);
self.* = undefined;
}
pub fn buildRuntime(
self: *CompiledStory,
gpa: std.mem.Allocator,
ir: *Ir,
story: *Story,
) !void {
const globals_len = self.globals.len + self.knots.len;
const constants_pool = &story.constants_pool;
try constants_pool.ensureUnusedCapacity(gpa, self.constants.len);
try story.globals.ensureUnusedCapacity(gpa, @intCast(globals_len));
for (self.constants) |constant| {
switch (constant) {
.integer => |value| {
const object: *Object.Number = try .create(story, .{
.integer = @intCast(value),
});
constants_pool.appendAssumeCapacity(&object.base);
},
.string => |ref| {
const bytes = ir.nullTerminatedString(ref);
const object: *Object.String = try .create(story, bytes);
constants_pool.appendAssumeCapacity(&object.base);
},
}
}
for (self.globals) |global_index| {
const str = self.constants[global_index];
const name_bytes = ir.nullTerminatedString(str.string);
story.globals.putAssumeCapacity(name_bytes, null);
}
for (self.knots) |*knot| {
const knot_name = ir.nullTerminatedString(knot.name);
const runtime_chunk: *Object.ContentPath = try .create(story, .{
.name = try .create(story, knot_name),
.arity = @intCast(knot.arity),
.locals_count = @intCast(knot.stack_size - knot.arity),
.const_pool = try knot.constants.toOwnedSlice(gpa),
.bytes = try knot.bytecode.toOwnedSlice(gpa),
});
story.globals.putAssumeCapacity(knot_name, &runtime_chunk.base);
}
story.string_bytes = ir.string_bytes;
ir.string_bytes = &.{};
}
};
pub fn compile(gpa: std.mem.Allocator, ir: *const Ir) !CompiledStory {
var sema: Sema = .{
.gpa = gpa,
.ir = ir,
};
defer sema.deinit();
try file(&sema, .file_inst);
return .{
.constants = try sema.constants.toOwnedSlice(gpa),
.globals = try sema.globals.toOwnedSlice(gpa),
.knots = try sema.knots.toOwnedSlice(gpa),
};
}