stdlib: relocate modules under library/
- examples/modules/ -> library/modules/ (top-level, no more symlink hacks in consumer projects) - compiler discovers stdlib via _NSGetExecutablePath / readlink /proc/self/exe; searches dev layout (../../library), install layout (../library), and alongside-binary fallback - SX_STDLIB_PATH env var overrides for tests / dev convenience - SX_DEBUG_STDLIB env var dumps the discovery results - build.zig installs library/ alongside the binary - Compilation gains stdlib_paths field threaded through resolveImports - 50 tests pass; consumer projects can now build from any cwd
This commit is contained in:
44
src/main.zig
44
src/main.zig
@@ -6,6 +6,10 @@ pub fn main(init: std.process.Init) !void {
|
||||
const io = init.io;
|
||||
const args = try init.minimal.args.toSlice(allocator);
|
||||
|
||||
// Stdlib discovered from binary location (or $SX_STDLIB_PATH override).
|
||||
// Empty slice on hosts where discovery fails — imports fall back to CWD.
|
||||
const stdlib_paths = sx.imports.discoverStdlibPaths(allocator) catch &[_][]const u8{};
|
||||
|
||||
if (args.len < 2) {
|
||||
printUsage();
|
||||
return;
|
||||
@@ -143,13 +147,13 @@ pub fn main(init: std.process.Init) !void {
|
||||
}
|
||||
break :blk base;
|
||||
};
|
||||
compile(allocator, io, path, output_name, target_config, show_timing, enable_cache) catch std.process.exit(1);
|
||||
compile(allocator, io, path, output_name, target_config, show_timing, enable_cache, stdlib_paths) catch std.process.exit(1);
|
||||
} else if (std.mem.eql(u8, command, "ir")) {
|
||||
emitIR(allocator, io, path, target_config) catch std.process.exit(1);
|
||||
emitIR(allocator, io, path, target_config, stdlib_paths) catch std.process.exit(1);
|
||||
} else if (std.mem.eql(u8, command, "ir-dump")) {
|
||||
dumpSxIR(allocator, io, path) catch std.process.exit(1);
|
||||
dumpSxIR(allocator, io, path, stdlib_paths) catch std.process.exit(1);
|
||||
} else if (std.mem.eql(u8, command, "asm")) {
|
||||
emitAsm(allocator, io, path, target_config) catch std.process.exit(1);
|
||||
emitAsm(allocator, io, path, target_config, stdlib_paths) catch std.process.exit(1);
|
||||
} else if (std.mem.eql(u8, command, "run")) {
|
||||
if (target_config.isWasm()) {
|
||||
std.debug.print("error: 'run' is not supported for wasm targets. Use 'build' instead.\n", .{});
|
||||
@@ -164,7 +168,7 @@ pub fn main(init: std.process.Init) !void {
|
||||
const source = readSource(allocator, io, path) catch std.process.exit(1);
|
||||
timer.record("read");
|
||||
|
||||
var comp = sx.core.Compilation.init(allocator, io, path, source, target_config);
|
||||
var comp = sx.core.Compilation.init(allocator, io, path, source, target_config, stdlib_paths);
|
||||
defer comp.deinit();
|
||||
|
||||
timer.mark();
|
||||
@@ -239,7 +243,7 @@ pub fn main(init: std.process.Init) !void {
|
||||
const exit_code = sx.target.runJITFromObject(obj_buf) catch {
|
||||
// JIT failed — fall back to AOT
|
||||
timer.record("jit-fail");
|
||||
runAOT(allocator, io, path, target_config, &timer, enable_cache) catch std.process.exit(1);
|
||||
runAOT(allocator, io, path, target_config, &timer, enable_cache, stdlib_paths) catch std.process.exit(1);
|
||||
timer.printAll();
|
||||
return;
|
||||
};
|
||||
@@ -363,12 +367,12 @@ fn readSource(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8)
|
||||
return try allocator.dupeZ(u8, source_bytes);
|
||||
}
|
||||
|
||||
fn compilePipeline(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, target_config: sx.target.TargetConfig, timer: *Timing) !sx.core.Compilation {
|
||||
fn compilePipeline(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, target_config: sx.target.TargetConfig, timer: *Timing, stdlib_paths: []const []const u8) !sx.core.Compilation {
|
||||
timer.mark();
|
||||
const source = try readSource(allocator, io, input_path);
|
||||
timer.record("read");
|
||||
|
||||
var comp = sx.core.Compilation.init(allocator, io, input_path, source, target_config);
|
||||
var comp = sx.core.Compilation.init(allocator, io, input_path, source, target_config, stdlib_paths);
|
||||
errdefer comp.deinit();
|
||||
|
||||
timer.mark();
|
||||
@@ -390,9 +394,9 @@ fn compilePipeline(allocator: std.mem.Allocator, io: std.Io, input_path: []const
|
||||
return comp;
|
||||
}
|
||||
|
||||
fn dumpSxIR(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8) !void {
|
||||
fn dumpSxIR(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, stdlib_paths: []const []const u8) !void {
|
||||
const source = try readSource(allocator, io, input_path);
|
||||
var comp = sx.core.Compilation.init(allocator, io, input_path, source, .{});
|
||||
var comp = sx.core.Compilation.init(allocator, io, input_path, source, .{}, stdlib_paths);
|
||||
defer comp.deinit();
|
||||
|
||||
comp.parse() catch { comp.renderErrors(); return error.CompileError; };
|
||||
@@ -408,16 +412,16 @@ fn dumpSxIR(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8) !v
|
||||
std.debug.print("{s}", .{result.items});
|
||||
}
|
||||
|
||||
fn emitIR(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, target_config: sx.target.TargetConfig) !void {
|
||||
fn emitIR(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, target_config: sx.target.TargetConfig, stdlib_paths: []const []const u8) !void {
|
||||
var timer = Timing.init(io, false);
|
||||
var comp = try compilePipeline(allocator, io, input_path, target_config, &timer);
|
||||
var comp = try compilePipeline(allocator, io, input_path, target_config, &timer, stdlib_paths);
|
||||
defer comp.deinit();
|
||||
comp.ir_emitter.?.printIR();
|
||||
}
|
||||
|
||||
fn emitAsm(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, target_config: sx.target.TargetConfig) !void {
|
||||
fn emitAsm(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, target_config: sx.target.TargetConfig, stdlib_paths: []const []const u8) !void {
|
||||
var timer = Timing.init(io, false);
|
||||
var comp = try compilePipeline(allocator, io, input_path, target_config, &timer);
|
||||
var comp = try compilePipeline(allocator, io, input_path, target_config, &timer, stdlib_paths);
|
||||
defer comp.deinit();
|
||||
const asm_path = target_config.output_path orelse blk: {
|
||||
const name = deriveOutputName(input_path);
|
||||
@@ -428,19 +432,19 @@ fn emitAsm(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, tar
|
||||
std.debug.print("emitted: {s}\n", .{asm_path});
|
||||
}
|
||||
|
||||
fn compile(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, output_path: []const u8, target_config: sx.target.TargetConfig, show_timing: bool, enable_cache: bool) !void {
|
||||
fn compile(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, output_path: []const u8, target_config: sx.target.TargetConfig, show_timing: bool, enable_cache: bool, stdlib_paths: []const []const u8) !void {
|
||||
var timer = Timing.init(io, show_timing);
|
||||
try compileWithTimer(allocator, io, input_path, output_path, target_config, &timer, enable_cache);
|
||||
try compileWithTimer(allocator, io, input_path, output_path, target_config, &timer, enable_cache, stdlib_paths);
|
||||
timer.printAll();
|
||||
}
|
||||
|
||||
fn compileWithTimer(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, output_path: []const u8, target_config: sx.target.TargetConfig, timer: *Timing, enable_cache: bool) !void {
|
||||
fn compileWithTimer(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, output_path: []const u8, target_config: sx.target.TargetConfig, timer: *Timing, enable_cache: bool, stdlib_paths: []const []const u8) !void {
|
||||
// Phase A: read + parse + resolveImports (fast: ~0.5ms)
|
||||
timer.mark();
|
||||
const source = try readSource(allocator, io, input_path);
|
||||
timer.record("read");
|
||||
|
||||
var comp = sx.core.Compilation.init(allocator, io, input_path, source, target_config);
|
||||
var comp = sx.core.Compilation.init(allocator, io, input_path, source, target_config, stdlib_paths);
|
||||
defer comp.deinit();
|
||||
|
||||
timer.mark();
|
||||
@@ -584,9 +588,9 @@ fn compileWithTimer(allocator: std.mem.Allocator, io: std.Io, input_path: []cons
|
||||
std.Io.Dir.deleteDir(.cwd(), io, tmp_dir) catch {};
|
||||
}
|
||||
|
||||
fn runAOT(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, target_config: sx.target.TargetConfig, timer: *Timing, enable_cache: bool) !void {
|
||||
fn runAOT(allocator: std.mem.Allocator, io: std.Io, input_path: []const u8, target_config: sx.target.TargetConfig, timer: *Timing, enable_cache: bool, stdlib_paths: []const []const u8) !void {
|
||||
const tmp_bin = if (comptime @import("builtin").os.tag == .windows) "sx_run_tmp.exe" else "/tmp/sx_run_tmp";
|
||||
try compileWithTimer(allocator, io, input_path, tmp_bin, target_config, timer, enable_cache);
|
||||
try compileWithTimer(allocator, io, input_path, tmp_bin, target_config, timer, enable_cache, stdlib_paths);
|
||||
defer {
|
||||
std.Io.Dir.deleteFile(.cwd(), io, tmp_bin) catch {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user