tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

gen_kernel.zig (3627B)


      1 const std = @import("std");
      2 
      3 // Minimal Node definition for the DAG format (no App variant for kernels)
      4 const Node = union(enum(u8)) {
      5     leaf,
      6     stem: struct { child: u32 },
      7     fork: struct { left: u32, right: u32 },
      8 };
      9 
     10 fn parseLine(line: []const u8) !Node {
     11     var it = std.mem.splitScalar(u8, std.mem.trim(u8, line, " \t\n\r"), ' ');
     12     const tag = it.next() orelse return error.EmptyLine;
     13     if (std.mem.eql(u8, tag, "leaf")) {
     14         return .leaf;
     15     } else if (std.mem.eql(u8, tag, "stem")) {
     16         const child_str = it.next() orelse return error.MissingChild;
     17         const child = try std.fmt.parseInt(u32, child_str, 10);
     18         return .{ .stem = .{ .child = child } };
     19     } else if (std.mem.eql(u8, tag, "fork")) {
     20         const left_str = it.next() orelse return error.MissingLeft;
     21         const right_str = it.next() orelse return error.MissingRight;
     22         const left = try std.fmt.parseInt(u32, left_str, 10);
     23         const right = try std.fmt.parseInt(u32, right_str, 10);
     24         return .{ .fork = .{ .left = left, .right = right } };
     25     } else {
     26         return error.UnknownTag;
     27     }
     28 }
     29 
     30 pub fn main(init: std.process.Init) !void {
     31     const gpa = init.gpa;
     32     const io = init.io;
     33 
     34     const args = try init.minimal.args.toSlice(init.arena.allocator());
     35     if (args.len != 3) {
     36         std.debug.print("Usage: gen_kernel <input.dag> <output.zig>\n", .{});
     37         std.process.exit(1);
     38     }
     39 
     40     const input_path = args[1];
     41     const output_path = args[2];
     42 
     43     const source = try std.Io.Dir.cwd().readFileAlloc(io, input_path, gpa, .limited(10 * 1024 * 1024));
     44     defer gpa.free(source);
     45 
     46     var nodes = std.ArrayList(Node).empty;
     47     defer nodes.deinit(gpa);
     48 
     49     var it = std.mem.splitScalar(u8, source, '\n');
     50     const root_line = it.next() orelse return error.EmptyFile;
     51     const root = try std.fmt.parseInt(u32, std.mem.trim(u8, root_line, " \t\n\r"), 10);
     52 
     53     while (it.next()) |line| {
     54         const trimmed = std.mem.trim(u8, line, " \t\n\r");
     55         if (trimmed.len == 0) continue;
     56         const node = try parseLine(trimmed);
     57         try nodes.append(gpa, node);
     58     }
     59 
     60     const file = try std.Io.Dir.cwd().createFile(io, output_path, .{});
     61     defer file.close(io);
     62 
     63     var buf: [4096]u8 = undefined;
     64     var writer = file.writer(io, &buf);
     65 
     66     try writer.interface.writeAll("// Auto-generated from ");
     67     try writer.interface.writeAll(input_path);
     68     try writer.interface.writeAll("\n// Do not edit manually.\n\n");
     69 
     70     try writer.interface.writeAll("pub const NodeTag = enum(u8) { leaf = 0, stem = 1, fork = 2 };\n\n");
     71     try writer.interface.writeAll("pub const Node = union(NodeTag) {\n");
     72     try writer.interface.writeAll("    leaf,\n");
     73     try writer.interface.writeAll("    stem: struct { child: u32 },\n");
     74     try writer.interface.writeAll("    fork: struct { left: u32, right: u32 },\n");
     75     try writer.interface.writeAll("};\n\n");
     76 
     77     try writer.interface.print("pub const kernel_root: u32 = {d};\n\n", .{root});
     78     try writer.interface.writeAll("pub const kernel_nodes = [_]Node{\n");
     79 
     80     for (nodes.items) |node| {
     81         switch (node) {
     82             .leaf => try writer.interface.writeAll("    .leaf,\n"),
     83             .stem => |s| try writer.interface.print("    .{{ .stem = .{{ .child = {d} }} }},\n", .{s.child}),
     84             .fork => |f| try writer.interface.print("    .{{ .fork = .{{ .left = {d}, .right = {d} }} }},\n", .{f.left, f.right}),
     85         }
     86     }
     87 
     88     try writer.interface.writeAll("};\n");
     89     try writer.flush();
     90 
     91     std.debug.print("Generated {d} kernel nodes, root={d} -> {s}\n", .{ nodes.items.len, root, output_path });
     92 }