refactor: new direction for error reporting
This commit is contained in:
parent
72b686d750
commit
c940374f27
11 changed files with 758 additions and 582 deletions
110
src/Sema.zig
110
src/Sema.zig
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue