build options #compiler
This commit is contained in:
101
src/ir/compiler_hooks.zig
Normal file
101
src/ir/compiler_hooks.zig
Normal file
@@ -0,0 +1,101 @@
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const interp_mod = @import("interp.zig");
|
||||
const Value = interp_mod.Value;
|
||||
const Interpreter = interp_mod.Interpreter;
|
||||
|
||||
// ── BuildConfig ─────────────────────────────────────────────────────────
|
||||
// Mutable build configuration accumulated by #run blocks via #compiler methods.
|
||||
|
||||
pub const BuildConfig = struct {
|
||||
link_flags: std.ArrayList([]const u8) = .empty,
|
||||
output_path: ?[]const u8 = null,
|
||||
|
||||
pub fn deinit(self: *BuildConfig, alloc: Allocator) void {
|
||||
self.link_flags.deinit(alloc);
|
||||
}
|
||||
};
|
||||
|
||||
// ── Hook system ─────────────────────────────────────────────────────────
|
||||
|
||||
pub const HookError = error{
|
||||
CannotEvalComptime,
|
||||
TypeError,
|
||||
};
|
||||
|
||||
/// Hook function signature. Receives the interpreter (for heap/string access),
|
||||
/// resolved argument values, and the mutable build config.
|
||||
pub const HookFn = *const fn (
|
||||
interp: *const Interpreter,
|
||||
args: []const Value,
|
||||
bc: *BuildConfig,
|
||||
alloc: Allocator,
|
||||
) HookError!Value;
|
||||
|
||||
pub const Registry = struct {
|
||||
hooks: std.StringHashMap(HookFn),
|
||||
|
||||
pub fn init(alloc: Allocator) Registry {
|
||||
return .{ .hooks = std.StringHashMap(HookFn).init(alloc) };
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Registry) void {
|
||||
self.hooks.deinit();
|
||||
}
|
||||
|
||||
pub fn get(self: *const Registry, name: []const u8) ?HookFn {
|
||||
return self.hooks.get(name);
|
||||
}
|
||||
|
||||
/// Register all built-in compiler hooks.
|
||||
pub fn registerDefaults(self: *Registry) void {
|
||||
self.hooks.put("build_options", &hookBuildOptions) catch {};
|
||||
self.hooks.put("BuildOptions.add_link_flag", &hookAddLinkFlag) catch {};
|
||||
self.hooks.put("BuildOptions.set_output_path", &hookSetOutputPath) catch {};
|
||||
}
|
||||
};
|
||||
|
||||
// ── build_options() hook ────────────────────────────────────────────────
|
||||
|
||||
fn hookBuildOptions(
|
||||
_: *const Interpreter,
|
||||
_: []const Value,
|
||||
_: *BuildConfig,
|
||||
_: Allocator,
|
||||
) HookError!Value {
|
||||
// build_options() returns a sentinel value; the real work happens
|
||||
// when methods like add_link_flag/set_output_path are called on it.
|
||||
return .void_val;
|
||||
}
|
||||
|
||||
// ── BuildOptions hooks ──────────────────────────────────────────────────
|
||||
|
||||
fn hookAddLinkFlag(
|
||||
interp: *const Interpreter,
|
||||
args: []const Value,
|
||||
bc: *BuildConfig,
|
||||
alloc: Allocator,
|
||||
) HookError!Value {
|
||||
// args: [self (BuildOptions value), flag_string]
|
||||
if (args.len < 2) return .void_val;
|
||||
const str_val = args[1];
|
||||
if (str_val.asString(interp)) |s| {
|
||||
bc.link_flags.append(alloc, alloc.dupe(u8, s) catch return error.CannotEvalComptime) catch return error.CannotEvalComptime;
|
||||
}
|
||||
return .void_val;
|
||||
}
|
||||
|
||||
fn hookSetOutputPath(
|
||||
interp: *const Interpreter,
|
||||
args: []const Value,
|
||||
bc: *BuildConfig,
|
||||
alloc: Allocator,
|
||||
) HookError!Value {
|
||||
// args: [self (BuildOptions value), path_string]
|
||||
if (args.len < 2) return .void_val;
|
||||
const str_val = args[1];
|
||||
if (str_val.asString(interp)) |s| {
|
||||
bc.output_path = alloc.dupe(u8, s) catch return error.CannotEvalComptime;
|
||||
}
|
||||
return .void_val;
|
||||
}
|
||||
Reference in New Issue
Block a user