master
1pub const Error = error{ WriteFailed, OutOfMemory };
2
3pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: *Writer) Error!void {
4 assert(!zoir.hasCompileErrors());
5
6 const bytes_per_node = comptime n: {
7 var n: usize = 0;
8 for (@typeInfo(Zoir.Node.Repr).@"struct".fields) |f| {
9 n += @sizeOf(f.type);
10 }
11 break :n n;
12 };
13
14 const node_bytes = zoir.nodes.len * bytes_per_node;
15 const extra_bytes = zoir.extra.len * @sizeOf(u32);
16 const limb_bytes = zoir.limbs.len * @sizeOf(std.math.big.Limb);
17 const string_bytes = zoir.string_bytes.len;
18
19 // zig fmt: off
20 try w.print(
21 \\# Nodes: {} ({Bi})
22 \\# Extra Data Items: {} ({Bi})
23 \\# BigInt Limbs: {} ({Bi})
24 \\# String Table Bytes: {Bi}
25 \\# Total ZON Bytes: {Bi}
26 \\
27 , .{
28 zoir.nodes.len, node_bytes,
29 zoir.extra.len, extra_bytes,
30 zoir.limbs.len, limb_bytes,
31 string_bytes,
32 node_bytes + extra_bytes + limb_bytes + string_bytes,
33 });
34 // zig fmt: on
35 var pz: PrintZon = .{
36 .w = w,
37 .arena = arena,
38 .zoir = zoir,
39 .indent = 0,
40 };
41
42 return pz.renderRoot();
43}
44
45const PrintZon = struct {
46 w: *Writer,
47 arena: Allocator,
48 zoir: Zoir,
49 indent: u32,
50
51 fn renderRoot(pz: *PrintZon) Error!void {
52 try pz.renderNode(.root);
53 try pz.w.writeByte('\n');
54 }
55
56 fn renderNode(pz: *PrintZon, node: Zoir.Node.Index) Error!void {
57 const zoir = pz.zoir;
58 try pz.w.print("%{d} = ", .{@intFromEnum(node)});
59 switch (node.get(zoir)) {
60 .true => try pz.w.writeAll("true"),
61 .false => try pz.w.writeAll("false"),
62 .null => try pz.w.writeAll("null"),
63 .pos_inf => try pz.w.writeAll("inf"),
64 .neg_inf => try pz.w.writeAll("-inf"),
65 .nan => try pz.w.writeAll("nan"),
66 .int_literal => |storage| switch (storage) {
67 .small => |x| try pz.w.print("int({d})", .{x}),
68 .big => |x| {
69 const str = try x.toStringAlloc(pz.arena, 10, .lower);
70 try pz.w.print("int(big {s})", .{str});
71 },
72 },
73 .float_literal => |x| try pz.w.print("float({d})", .{x}),
74 .char_literal => |x| try pz.w.print("char({d})", .{x}),
75 .enum_literal => |x| try pz.w.print("enum_literal({f})", .{std.zig.fmtIdP(x.get(zoir))}),
76 .string_literal => |x| try pz.w.print("str(\"{f}\")", .{std.zig.fmtString(x)}),
77 .empty_literal => try pz.w.writeAll("empty_literal(.{})"),
78 .array_literal => |vals| {
79 try pz.w.writeAll("array_literal({");
80 pz.indent += 1;
81 for (0..vals.len) |idx| {
82 try pz.newline();
83 try pz.renderNode(vals.at(@intCast(idx)));
84 try pz.w.writeByte(',');
85 }
86 pz.indent -= 1;
87 try pz.newline();
88 try pz.w.writeAll("})");
89 },
90 .struct_literal => |s| {
91 try pz.w.writeAll("struct_literal({");
92 pz.indent += 1;
93 for (s.names, 0..s.vals.len) |name, idx| {
94 try pz.newline();
95 try pz.w.print("[{f}] ", .{std.zig.fmtIdP(name.get(zoir))});
96 try pz.renderNode(s.vals.at(@intCast(idx)));
97 try pz.w.writeByte(',');
98 }
99 pz.indent -= 1;
100 try pz.newline();
101 try pz.w.writeAll("})");
102 },
103 }
104 }
105
106 fn newline(pz: *PrintZon) !void {
107 try pz.w.writeByte('\n');
108 try pz.w.splatByteAll(' ', 2 * pz.indent);
109 }
110};
111
112const std = @import("std");
113const assert = std.debug.assert;
114const Allocator = std.mem.Allocator;
115const Zoir = std.zig.Zoir;
116const Writer = std.Io.Writer;