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