diff --git a/libs/dusk/src/IR.zig b/libs/dusk/src/IR.zig index 669b14c2..bf254168 100644 --- a/libs/dusk/src/IR.zig +++ b/libs/dusk/src/IR.zig @@ -445,95 +445,3 @@ pub const Inst = struct { std.debug.assert(@sizeOf(Inst) <= 24); } }; - -pub fn print(self: IR, writer: anytype) !void { - const globals = std.mem.sliceTo(self.refs[self.globals_index..], .none); - for (globals) |ref| { - try self.printInst(writer, 0, ref, false); - } -} - -pub fn printInst(self: IR, writer: anytype, indention: u16, ref: Inst.Ref, as_ref: bool) !void { - switch (ref) { - .none, - .bool_type, - .i32_type, - .u32_type, - .f32_type, - .f16_type, - .sampler_type, - .comparison_sampler_type, - .external_sampled_texture_type, - .true_literal, - .false_literal, - => { - try writer.print("{s}()", .{@tagName(ref)}); - }, - _ => { - const index = ref.toIndex().?; - const inst = self.instructions[index]; - - if (as_ref and inst.tag.isDecl()) { - try writer.print("%{d}", .{index}); - return; - } - - try writer.print("%{d} = {s}{{", .{ index, @tagName(inst.tag) }); - switch (inst.tag) { - .global_variable_decl => { - try writer.writeByte('\n'); - - try printIndent(writer, indention + 1); - try writer.writeAll(".type = "); - try self.printInst(writer, indention + 2, inst.data.global_variable_decl.type, true); - try writer.writeAll(",\n"); - - try printIndent(writer, indention); - try writer.writeAll("},\n"); - }, - .struct_decl => { - try writer.writeByte('\n'); - - try printIndent(writer, indention + 1); - try writer.print(".name = \"{s}\",\n", .{self.getStr(inst.data.struct_decl.name)}); - - const members = std.mem.sliceTo(self.refs[inst.data.struct_decl.members..], .none); - try printIndent(writer, indention + 1); - try writer.writeAll(".members = [\n"); - for (members) |member| { - try printIndent(writer, indention + 2); - try self.printInst(writer, indention + 2, member, false); - } - try printIndent(writer, indention + 1); - try writer.writeAll("],\n"); - - try printIndent(writer, indention); - try writer.writeAll("},\n"); - }, - .struct_member => { - try writer.writeByte('\n'); - - try printIndent(writer, indention + 1); - try writer.print(".name = \"{s}\",\n", .{self.getStr(inst.data.struct_member.name)}); - - try printIndent(writer, indention + 1); - try writer.writeAll(".type = "); - try self.printInst(writer, indention + 2, inst.data.struct_member.type, true); - try writer.writeAll(",\n"); - - try printIndent(writer, indention); - try writer.writeAll("},\n"); - }, - else => { - try writer.print("TODO", .{}); - try writer.writeAll("}"); - }, - } - }, - } -} - -const indention_size = 2; -pub fn printIndent(writer: anytype, indent: u16) !void { - try writer.writeByteNTimes(' ', indent * indention_size); -} diff --git a/libs/dusk/src/main.zig b/libs/dusk/src/main.zig index c2f2859e..729c7fd8 100644 --- a/libs/dusk/src/main.zig +++ b/libs/dusk/src/main.zig @@ -2,6 +2,7 @@ const std = @import("std"); pub const Ast = @import("Ast.zig"); pub const IR = @import("IR.zig"); +pub const printIR = @import("print_ir.zig").printIR; pub const Parser = @import("Parser.zig"); pub const Token = @import("Token.zig"); pub const Tokenizer = @import("Tokenizer.zig"); diff --git a/libs/dusk/src/print_ir.zig b/libs/dusk/src/print_ir.zig new file mode 100644 index 00000000..a0d99ee2 --- /dev/null +++ b/libs/dusk/src/print_ir.zig @@ -0,0 +1,117 @@ +const std = @import("std"); +const IR = @import("IR.zig"); + +const indention_size = 2; + +pub fn printIR(ir: IR, writer: anytype) !void { + var p = Printer(@TypeOf(writer)){ .ir = ir, .writer = writer }; + const globals = std.mem.sliceTo(ir.refs[ir.globals_index..], .none); + for (globals) |ref| { + try p.printInst(0, ref, false); + } +} + +fn Printer(comptime Writer: type) type { + return struct { + ir: IR, + writer: Writer, + + fn printInst(self: @This(), indent: u16, ref: IR.Inst.Ref, decl_scope: bool) !void { + switch (ref) { + .none, + .bool_type, + .i32_type, + .u32_type, + .f32_type, + .f16_type, + .sampler_type, + .comparison_sampler_type, + .external_sampled_texture_type, + .true_literal, + .false_literal, + => { + try self.writer.print("{s}()", .{@tagName(ref)}); + }, + _ => { + const index = ref.toIndex().?; + const inst = self.ir.instructions[index]; + + if (decl_scope and inst.tag.isDecl()) { + try self.writer.print("%{d}", .{index}); + return; + } + + switch (inst.tag) { + .global_variable_decl => try self.printGlobalVariable(indent, index), + .struct_decl => try self.printStructDecl(indent, index), + .struct_member => try self.printStructMember(indent, index), + else => { + try self.writer.print("%{d} = {s}{{TODO}},\n", .{ index, @tagName(inst.tag) }); + }, + } + }, + } + } + + fn printGlobalVariable(self: @This(), indent: u16, index: IR.Inst.Index) anyerror!void { + const inst = self.ir.instructions[index]; + + try self.instStart(index); + defer self.instEnd(indent) catch unreachable; + + try self.printIndent(indent + 1); + try self.writer.writeAll(".type = "); + try self.printInst(indent + 2, inst.data.global_variable_decl.type, true); + try self.writer.writeAll(",\n"); + } + + fn printStructDecl(self: @This(), indent: u16, index: IR.Inst.Index) anyerror!void { + const inst = self.ir.instructions[index]; + + try self.instStart(index); + defer self.instEnd(indent) catch unreachable; + + try self.printIndent(indent + 1); + try self.writer.print(".name = \"{s}\",\n", .{self.ir.getStr(inst.data.struct_decl.name)}); + + const members = std.mem.sliceTo(self.ir.refs[inst.data.struct_decl.members..], .none); + try self.printIndent(indent + 1); + try self.writer.writeAll(".members = [\n"); + for (members) |member| { + try self.printIndent(indent + 2); + try self.printStructMember(indent + 2, member.toIndex().?); + } + try self.printIndent(indent + 1); + try self.writer.writeAll("],\n"); + } + + fn printStructMember(self: @This(), indent: u16, index: IR.Inst.Index) anyerror!void { + const inst = self.ir.instructions[index]; + + try self.instStart(index); + defer self.instEnd(indent) catch unreachable; + + try self.printIndent(indent + 1); + try self.writer.print(".name = \"{s}\",\n", .{self.ir.getStr(inst.data.struct_member.name)}); + + try self.printIndent(indent + 1); + try self.writer.writeAll(".type = "); + try self.printInst(indent + 2, inst.data.struct_member.type, true); + try self.writer.writeAll(",\n"); + } + + fn instStart(self: @This(), index: IR.Inst.Index) !void { + const inst = self.ir.instructions[index]; + try self.writer.print("%{d} = {s}{{\n", .{ index, @tagName(inst.tag) }); + } + + fn instEnd(self: @This(), indent: u16) !void { + try self.printIndent(indent); + try self.writer.writeAll("},\n"); + } + + fn printIndent(self: @This(), indent: u16) !void { + try self.writer.writeByteNTimes(' ', indent * indention_size); + } + }; +} diff --git a/libs/dusk/test/main.zig b/libs/dusk/test/main.zig index bb2dce84..cce90c76 100644 --- a/libs/dusk/test/main.zig +++ b/libs/dusk/test/main.zig @@ -101,7 +101,7 @@ test "boids" { const source = @embedFile("boids.wgsl"); var ir = try expectIR(source); defer ir.deinit(); - // try ir.print(std.io.getStdOut().writer()); + // try dusk.printIR(ir, std.io.getStdOut().writer()); } test "gkurve" {