imports
This commit is contained in:
@@ -172,6 +172,10 @@ pub const CodeGen = struct {
|
||||
diagnostics: ?*errors.DiagnosticList = null,
|
||||
// Current source span (set at genExpr/genStmt/genExprAsType entry)
|
||||
current_span: Span = .{ .start = 0, .end = 0 },
|
||||
// Current source file path (for error reporting in imported files)
|
||||
current_source_file: ?[]const u8 = null,
|
||||
// Import source map (path → source text, for error reporting)
|
||||
import_sources: ?*const std.StringHashMap([:0]const u8) = null,
|
||||
// Loop context: break/continue target basic blocks (null when not in a loop)
|
||||
loop_break_bb: c.LLVMBasicBlockRef = null,
|
||||
loop_continue_bb: c.LLVMBasicBlockRef = null,
|
||||
@@ -238,6 +242,7 @@ pub const CodeGen = struct {
|
||||
fd: ast.FnDecl,
|
||||
name: []const u8, // qualified name (may differ from fd.name for namespaced functions)
|
||||
namespace: ?[]const u8 = null,
|
||||
source_file: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
const TypeCategory = enum {
|
||||
@@ -526,12 +531,18 @@ pub const CodeGen = struct {
|
||||
}
|
||||
|
||||
fn emitError(self: *CodeGen, msg: []const u8) error{CodeGenError} {
|
||||
if (self.diagnostics) |diags| diags.add(.err, msg, self.current_span);
|
||||
if (self.diagnostics) |diags| {
|
||||
diags.current_source_file = self.current_source_file;
|
||||
diags.add(.err, msg, self.current_span);
|
||||
}
|
||||
return error.CodeGenError;
|
||||
}
|
||||
|
||||
fn emitErrorFmt(self: *CodeGen, comptime fmt: []const u8, args: anytype) error{CodeGenError} {
|
||||
if (self.diagnostics) |diags| diags.addFmt(.err, self.current_span, fmt, args);
|
||||
if (self.diagnostics) |diags| {
|
||||
diags.current_source_file = self.current_source_file;
|
||||
diags.addFmt(.err, self.current_span, fmt, args);
|
||||
}
|
||||
return error.CodeGenError;
|
||||
}
|
||||
|
||||
@@ -1235,6 +1246,7 @@ pub const CodeGen = struct {
|
||||
|
||||
// Pre-scan: collect named library constants (handles forward references)
|
||||
for (root.data.root.decls) |decl| {
|
||||
self.current_source_file = decl.source_file;
|
||||
switch (decl.data) {
|
||||
.library_decl => |ld| {
|
||||
try self.library_constants.put(ld.name, ld.lib_name);
|
||||
@@ -1256,6 +1268,7 @@ pub const CodeGen = struct {
|
||||
|
||||
// Pass 1: Register all declarations (signatures only, no bodies)
|
||||
for (root.data.root.decls) |decl| {
|
||||
self.current_source_file = decl.source_file;
|
||||
switch (decl.data) {
|
||||
.fn_decl => |fd| {
|
||||
if (fd.body.data == .builtin_expr) {
|
||||
@@ -1392,13 +1405,14 @@ pub const CodeGen = struct {
|
||||
// Functions with Any parameters (like any_to_string) are deferred to Pass 3
|
||||
// so that all types are registered before their type-match expressions are compiled.
|
||||
for (root.data.root.decls) |decl| {
|
||||
self.current_source_file = decl.source_file;
|
||||
switch (decl.data) {
|
||||
.fn_decl => |fd| {
|
||||
if (fd.body.data == .builtin_expr or fd.body.data == .foreign_expr) {
|
||||
// skip — no body to generate
|
||||
} else if (fd.type_params.len == 0) {
|
||||
if (shouldDeferFnBody(fd)) {
|
||||
try self.deferred_fn_bodies.append(self.allocator, .{ .fd = fd, .name = fd.name });
|
||||
try self.deferred_fn_bodies.append(self.allocator, .{ .fd = fd, .name = fd.name, .source_file = self.current_source_file });
|
||||
} else {
|
||||
try self.genFnBody(fd, fd.name);
|
||||
}
|
||||
@@ -1431,8 +1445,11 @@ pub const CodeGen = struct {
|
||||
// Pass 3: Compile deferred function bodies (after all types are registered)
|
||||
for (self.deferred_fn_bodies.items) |deferred| {
|
||||
const saved_ns = self.current_namespace;
|
||||
const saved_sf = self.current_source_file;
|
||||
self.current_namespace = deferred.namespace;
|
||||
self.current_source_file = deferred.source_file;
|
||||
defer self.current_namespace = saved_ns;
|
||||
defer self.current_source_file = saved_sf;
|
||||
try self.genFnBody(deferred.fd, deferred.name);
|
||||
}
|
||||
|
||||
@@ -2448,7 +2465,7 @@ pub const CodeGen = struct {
|
||||
} else if (fd.type_params.len == 0) {
|
||||
const qualified = try std.fmt.allocPrint(self.allocator, "{s}.{s}", .{ ns.name, fd.name });
|
||||
if (shouldDeferFnBody(fd)) {
|
||||
try self.deferred_fn_bodies.append(self.allocator, .{ .fd = fd, .name = qualified, .namespace = ns.name });
|
||||
try self.deferred_fn_bodies.append(self.allocator, .{ .fd = fd, .name = qualified, .namespace = ns.name, .source_file = self.current_source_file });
|
||||
} else {
|
||||
try self.genFnBody(fd, qualified);
|
||||
}
|
||||
@@ -2483,7 +2500,7 @@ pub const CodeGen = struct {
|
||||
if (fd.type_params.len > 0) continue; // generic methods instantiated on demand
|
||||
const qualified = try std.fmt.allocPrint(self.allocator, "{s}.{s}", .{ sd.name, fd.name });
|
||||
if (shouldDeferFnBody(fd)) {
|
||||
try self.deferred_fn_bodies.append(self.allocator, .{ .fd = fd, .name = qualified, .namespace = sd.name });
|
||||
try self.deferred_fn_bodies.append(self.allocator, .{ .fd = fd, .name = qualified, .namespace = sd.name, .source_file = self.current_source_file });
|
||||
} else {
|
||||
try self.genFnBody(fd, qualified);
|
||||
}
|
||||
@@ -5249,7 +5266,7 @@ pub const CodeGen = struct {
|
||||
if (fd.type_params.len > 0) continue; // generic methods instantiated on demand
|
||||
const qualified = try std.fmt.allocPrint(self.allocator, "{s}.{s}", .{ ib.target_type, fd.name });
|
||||
if (shouldDeferFnBody(fd)) {
|
||||
try self.deferred_fn_bodies.append(self.allocator, .{ .fd = fd, .name = qualified, .namespace = ib.target_type });
|
||||
try self.deferred_fn_bodies.append(self.allocator, .{ .fd = fd, .name = qualified, .namespace = ib.target_type, .source_file = self.current_source_file });
|
||||
} else {
|
||||
try self.genFnBody(fd, qualified);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user