| ... | ... | @@ -48,16 +48,13 @@ pub fn main() !void { |
| 48 | 48 | const a = arena.allocator(); |
| 49 | 49 | |
| 50 | 50 | const args = try std.process.argsAlloc(a); |
| 51 | | if (args.len != 2) { |
| 51 | if (args.len != 3) { |
| 52 | 52 | usageAndExit(args[0], 1); |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | const json_path = try std.fs.path.join(a, &.{ args[1], "include/spirv/unified1/" }); |
| 56 | 56 | const dir = try std.fs.cwd().openDir(json_path, .{ .iterate = true }); |
| 57 | 57 | |
| 58 | | // const spec_path = try std.fs.path.join(a, &.{spirv_headers_dir_path, "spirv.core.grammar.json"}); |
| 59 | | // const core_spec = try std.fs.cwd().readFileAlloc(a, spec_path, std.math.maxInt(usize)); |
| 60 | | |
| 61 | 58 | const core_spec = try readRegistry(CoreRegistry, a, dir, "spirv.core.grammar.json"); |
| 62 | 59 | std.sort.block(Instruction, core_spec.instructions, CmpInst{}, CmpInst.lt); |
| 63 | 60 | |
| ... | ... | @@ -65,24 +62,35 @@ pub fn main() !void { |
| 65 | 62 | |
| 66 | 63 | var it = dir.iterate(); |
| 67 | 64 | while (try it.next()) |entry| { |
| 68 | | if (entry.kind != .file or !std.mem.startsWith(u8, entry.name, "extinst.")) { |
| 65 | if (entry.kind != .file) { |
| 69 | 66 | continue; |
| 70 | 67 | } |
| 71 | 68 | |
| 72 | | std.debug.assert(std.mem.endsWith(u8, entry.name, ".grammar.json")); |
| 73 | | const name = entry.name["extinst.".len .. entry.name.len - ".grammar.json".len]; |
| 74 | | const spec = try readRegistry(ExtensionRegistry, a, dir, entry.name); |
| 75 | | |
| 76 | | std.sort.block(Instruction, spec.instructions, CmpInst{}, CmpInst.lt); |
| 77 | | |
| 78 | | try exts.append(.{ .name = try a.dupe(u8, name), .spec = spec }); |
| 69 | try readExtRegistry(&exts, a, dir, entry.name); |
| 79 | 70 | } |
| 80 | 71 | |
| 72 | try readExtRegistry(&exts, a, std.fs.cwd(), args[2]); |
| 73 | |
| 81 | 74 | var bw = std.io.bufferedWriter(std.io.getStdOut().writer()); |
| 82 | 75 | try render(bw.writer(), a, core_spec, exts.items); |
| 83 | 76 | try bw.flush(); |
| 84 | 77 | } |
| 85 | 78 | |
| 79 | fn readExtRegistry(exts: *std.ArrayList(Extension), a: Allocator, dir: std.fs.Dir, sub_path: []const u8) !void { |
| 80 | const filename = std.fs.path.basename(sub_path); |
| 81 | if (!std.mem.startsWith(u8, filename, "extinst.")) { |
| 82 | return; |
| 83 | } |
| 84 | |
| 85 | std.debug.assert(std.mem.endsWith(u8, filename, ".grammar.json")); |
| 86 | const name = filename["extinst.".len .. filename.len - ".grammar.json".len]; |
| 87 | const spec = try readRegistry(ExtensionRegistry, a, dir, sub_path); |
| 88 | |
| 89 | std.sort.block(Instruction, spec.instructions, CmpInst{}, CmpInst.lt); |
| 90 | |
| 91 | try exts.append(.{ .name = try a.dupe(u8, name), .spec = spec }); |
| 92 | } |
| 93 | |
| 86 | 94 | fn readRegistry(comptime RegistryType: type, a: Allocator, dir: std.fs.Dir, path: []const u8) !RegistryType { |
| 87 | 95 | const spec = try dir.readFileAlloc(a, path, std.math.maxInt(usize)); |
| 88 | 96 | // Required for json parsing. |
| ... | ... | @@ -374,14 +382,19 @@ fn renderInstructionClass(writer: anytype, class: []const u8) !void { |
| 374 | 382 | } |
| 375 | 383 | |
| 376 | 384 | fn renderOperandKind(writer: anytype, operands: []const OperandKind) !void { |
| 377 | | try writer.writeAll("pub const OperandKind = enum {\n"); |
| 385 | try writer.writeAll( |
| 386 | \\pub const OperandKind = enum { |
| 387 | \\ Opcode, |
| 388 | \\ |
| 389 | ); |
| 378 | 390 | for (operands) |operand| { |
| 379 | 391 | try writer.print("{},\n", .{std.zig.fmtId(operand.kind)}); |
| 380 | 392 | } |
| 381 | 393 | try writer.writeAll( |
| 382 | 394 | \\ |
| 383 | 395 | \\pub fn category(self: OperandKind) OperandCategory { |
| 384 | | \\return switch (self) { |
| 396 | \\ return switch (self) { |
| 397 | \\ .Opcode => .literal, |
| 385 | 398 | \\ |
| 386 | 399 | ); |
| 387 | 400 | for (operands) |operand| { |
| ... | ... | @@ -395,10 +408,11 @@ fn renderOperandKind(writer: anytype, operands: []const OperandKind) !void { |
| 395 | 408 | try writer.print(".{} => .{s},\n", .{ std.zig.fmtId(operand.kind), cat }); |
| 396 | 409 | } |
| 397 | 410 | try writer.writeAll( |
| 398 | | \\}; |
| 411 | \\ }; |
| 399 | 412 | \\} |
| 400 | 413 | \\pub fn enumerants(self: OperandKind) []const Enumerant { |
| 401 | | \\return switch (self) { |
| 414 | \\ return switch (self) { |
| 415 | \\ .Opcode => unreachable, |
| 402 | 416 | \\ |
| 403 | 417 | ); |
| 404 | 418 | for (operands) |operand| { |
| ... | ... | @@ -483,7 +497,9 @@ fn renderOpcodes( |
| 483 | 497 | try writer.print("{} = {},\n", .{ std.zig.fmtId(inst.opname), inst.opcode }); |
| 484 | 498 | } |
| 485 | 499 | |
| 486 | | try writer.writeByte('\n'); |
| 500 | try writer.writeAll( |
| 501 | \\ |
| 502 | ); |
| 487 | 503 | |
| 488 | 504 | for (aliases.items) |alias| { |
| 489 | 505 | try writer.print("pub const {} = Opcode.{};\n", .{ |
| ... | ... | @@ -495,7 +511,7 @@ fn renderOpcodes( |
| 495 | 511 | try writer.writeAll( |
| 496 | 512 | \\ |
| 497 | 513 | \\pub fn Operands(comptime self: Opcode) type { |
| 498 | | \\return switch (self) { |
| 514 | \\ return switch (self) { |
| 499 | 515 | \\ |
| 500 | 516 | ); |
| 501 | 517 | |
| ... | ... | @@ -505,10 +521,10 @@ fn renderOpcodes( |
| 505 | 521 | } |
| 506 | 522 | |
| 507 | 523 | try writer.writeAll( |
| 508 | | \\}; |
| 524 | \\ }; |
| 509 | 525 | \\} |
| 510 | 526 | \\pub fn class(self: Opcode) Class { |
| 511 | | \\return switch (self) { |
| 527 | \\ return switch (self) { |
| 512 | 528 | \\ |
| 513 | 529 | ); |
| 514 | 530 | |
| ... | ... | @@ -519,7 +535,12 @@ fn renderOpcodes( |
| 519 | 535 | try writer.writeAll(",\n"); |
| 520 | 536 | } |
| 521 | 537 | |
| 522 | | try writer.writeAll("};\n}\n};\n"); |
| 538 | try writer.writeAll( |
| 539 | \\ }; |
| 540 | \\} |
| 541 | \\}; |
| 542 | \\ |
| 543 | ); |
| 523 | 544 | } |
| 524 | 545 | |
| 525 | 546 | fn renderOperandKinds( |
| ... | ... | @@ -844,7 +865,7 @@ fn parseHexInt(text: []const u8) !u31 { |
| 844 | 865 | |
| 845 | 866 | fn usageAndExit(arg0: []const u8, code: u8) noreturn { |
| 846 | 867 | std.io.getStdErr().writer().print( |
| 847 | | \\Usage: {s} <SPIRV-Headers repository path> |
| 868 | \\Usage: {s} <SPIRV-Headers repository path> <path/to/zig/src/codegen/spirv/extinst.zig.grammar.json> |
| 848 | 869 | \\ |
| 849 | 870 | \\Generates Zig bindings for SPIR-V specifications found in the SPIRV-Headers |
| 850 | 871 | \\repository. The result, printed to stdout, should be used to update |