feat(zig): native Arboricx bundle parser and C ABI
This commit is contained in:
92
ext/zig/tools/gen_kernel.zig
Normal file
92
ext/zig/tools/gen_kernel.zig
Normal file
@@ -0,0 +1,92 @@
|
||||
const std = @import("std");
|
||||
|
||||
// Minimal Node definition for the DAG format (no App variant for kernels)
|
||||
const Node = union(enum(u8)) {
|
||||
leaf,
|
||||
stem: struct { child: u32 },
|
||||
fork: struct { left: u32, right: u32 },
|
||||
};
|
||||
|
||||
fn parseLine(line: []const u8) !Node {
|
||||
var it = std.mem.splitScalar(u8, std.mem.trim(u8, line, " \t\n\r"), ' ');
|
||||
const tag = it.next() orelse return error.EmptyLine;
|
||||
if (std.mem.eql(u8, tag, "leaf")) {
|
||||
return .leaf;
|
||||
} else if (std.mem.eql(u8, tag, "stem")) {
|
||||
const child_str = it.next() orelse return error.MissingChild;
|
||||
const child = try std.fmt.parseInt(u32, child_str, 10);
|
||||
return .{ .stem = .{ .child = child } };
|
||||
} else if (std.mem.eql(u8, tag, "fork")) {
|
||||
const left_str = it.next() orelse return error.MissingLeft;
|
||||
const right_str = it.next() orelse return error.MissingRight;
|
||||
const left = try std.fmt.parseInt(u32, left_str, 10);
|
||||
const right = try std.fmt.parseInt(u32, right_str, 10);
|
||||
return .{ .fork = .{ .left = left, .right = right } };
|
||||
} else {
|
||||
return error.UnknownTag;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
const gpa = init.gpa;
|
||||
const io = init.io;
|
||||
|
||||
const args = try init.minimal.args.toSlice(init.arena.allocator());
|
||||
if (args.len != 3) {
|
||||
std.debug.print("Usage: gen_kernel <input.dag> <output.zig>\n", .{});
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
const input_path = args[1];
|
||||
const output_path = args[2];
|
||||
|
||||
const source = try std.Io.Dir.cwd().readFileAlloc(io, input_path, gpa, .limited(10 * 1024 * 1024));
|
||||
defer gpa.free(source);
|
||||
|
||||
var nodes = std.ArrayList(Node).empty;
|
||||
defer nodes.deinit(gpa);
|
||||
|
||||
var it = std.mem.splitScalar(u8, source, '\n');
|
||||
const root_line = it.next() orelse return error.EmptyFile;
|
||||
const root = try std.fmt.parseInt(u32, std.mem.trim(u8, root_line, " \t\n\r"), 10);
|
||||
|
||||
while (it.next()) |line| {
|
||||
const trimmed = std.mem.trim(u8, line, " \t\n\r");
|
||||
if (trimmed.len == 0) continue;
|
||||
const node = try parseLine(trimmed);
|
||||
try nodes.append(gpa, node);
|
||||
}
|
||||
|
||||
const file = try std.Io.Dir.cwd().createFile(io, output_path, .{});
|
||||
defer file.close(io);
|
||||
|
||||
var buf: [4096]u8 = undefined;
|
||||
var writer = file.writer(io, &buf);
|
||||
|
||||
try writer.interface.writeAll("// Auto-generated from ");
|
||||
try writer.interface.writeAll(input_path);
|
||||
try writer.interface.writeAll("\n// Do not edit manually.\n\n");
|
||||
|
||||
try writer.interface.writeAll("pub const NodeTag = enum(u8) { leaf = 0, stem = 1, fork = 2 };\n\n");
|
||||
try writer.interface.writeAll("pub const Node = union(NodeTag) {\n");
|
||||
try writer.interface.writeAll(" leaf,\n");
|
||||
try writer.interface.writeAll(" stem: struct { child: u32 },\n");
|
||||
try writer.interface.writeAll(" fork: struct { left: u32, right: u32 },\n");
|
||||
try writer.interface.writeAll("};\n\n");
|
||||
|
||||
try writer.interface.print("pub const kernel_root: u32 = {d};\n\n", .{root});
|
||||
try writer.interface.writeAll("pub const kernel_nodes = [_]Node{\n");
|
||||
|
||||
for (nodes.items) |node| {
|
||||
switch (node) {
|
||||
.leaf => try writer.interface.writeAll(" .leaf,\n"),
|
||||
.stem => |s| try writer.interface.print(" .{{ .stem = .{{ .child = {d} }} }},\n", .{s.child}),
|
||||
.fork => |f| try writer.interface.print(" .{{ .fork = .{{ .left = {d}, .right = {d} }} }},\n", .{f.left, f.right}),
|
||||
}
|
||||
}
|
||||
|
||||
try writer.interface.writeAll("};\n");
|
||||
try writer.flush();
|
||||
|
||||
std.debug.print("Generated {d} kernel nodes, root={d} -> {s}\n", .{ nodes.items.len, root, output_path });
|
||||
}
|
||||
Reference in New Issue
Block a user