This commit is contained in:
agra
2026-02-26 14:46:21 +02:00
parent dd14f1206b
commit 2552882ce6
14 changed files with 6433 additions and 159 deletions

View File

@@ -130,14 +130,38 @@ pub const Builder = struct {
// ── Function setup ──────────────────────────────────────────────
pub fn beginFunction(self: *Builder, name: StringId, params: []const Function.Param, ret_ty: TypeId) FuncId {
// Check if there's an existing extern stub with this name — upgrade it in-place
for (self.module.functions.items, 0..) |*existing, i| {
if (existing.name == name and existing.is_extern) {
existing.is_extern = false;
existing.linkage = .internal;
existing.params = self.module.alloc.dupe(Function.Param, params) catch params;
existing.ret = ret_ty;
const id = FuncId.fromIndex(@intCast(i));
self.func = id;
self.inst_counter = @intCast(params.len);
self.current_block = null;
return id;
}
}
const func = Function.init(name, params, ret_ty);
const id = self.module.addFunction(func);
self.func = id;
self.inst_counter = 0;
// Reserve refs 0..N-1 for function parameters; instructions start at ref N.
self.inst_counter = @intCast(params.len);
self.current_block = null;
return id;
}
/// Declare an extern function (no body, external linkage).
pub fn declareExtern(self: *Builder, name: StringId, params: []const Function.Param, ret_ty: TypeId) FuncId {
var func = Function.init(name, params, ret_ty);
func.is_extern = true;
func.linkage = .external;
const id = self.module.addFunction(func);
return id;
}
pub fn finalize(self: *Builder) void {
self.func = null;
self.current_block = null;
@@ -160,6 +184,24 @@ pub const Builder = struct {
pub fn switchToBlock(self: *Builder, block: BlockId) void {
self.current_block = block;
// Record the starting ref index for this block
const func = self.currentFunc();
const blk = &func.blocks.items[block.index()];
blk.first_ref = self.inst_counter;
}
/// Get the type of a previously emitted instruction Ref.
pub fn getRefType(self: *Builder, ref: Ref) TypeId {
if (self.func == null) return .s64;
const func = self.currentFunc();
const ref_idx = @intFromEnum(ref);
for (func.blocks.items) |*block| {
const first = block.first_ref;
if (ref_idx >= first and ref_idx < first + @as(u32, @intCast(block.insts.items.len))) {
return block.insts.items[ref_idx - first].ty;
}
}
return .s64;
}
// ── Emit helpers ────────────────────────────────────────────────
@@ -405,7 +447,7 @@ pub const Builder = struct {
// ── Internal helpers ────────────────────────────────────────────
fn currentFunc(self: *Builder) *Function {
pub fn currentFunc(self: *Builder) *Function {
return self.module.getFunctionMut(self.func.?);
}