authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-26 07:06:00+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-26 17:06:14+00:00
log951fc09a7e174f8f7cb7384d1fd56dcae9ac73da
treea9f219a7546a066af433adf3ca8f421d62d81393
parent2a245e3b78890e5d1b65492e51d9fe509ec35b3c
signaturelock-open Commit is signed but in an unrecognized format.

print_value: improve value printing

Notably, this improves string printing from `@as(*[5:0]u8, &@as([5:0]u8, "hello".*))` to `@as(*[5:0]u8, "hello")`, omitting the pointless ref-deref pair.

1 files changed, 49 insertions(+), 12 deletions(-)

src/print_value.zig+49-12
......@@ -102,11 +102,10 @@ pub fn print(
102102 .enum_tag => |enum_tag| {
103103 const enum_type = ip.loadEnumType(val.typeOf(mod).toIntern());
104104 if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
105 try writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
106 return;
105 return writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
107106 }
108107 if (level == 0) {
109 try writer.writeAll("@enumFromInt(...)");
108 return writer.writeAll("@enumFromInt(...)");
110109 }
111110 try writer.writeAll("@enumFromInt(");
112111 try print(Value.fromInterned(enum_tag.int), writer, level - 1, mod, opt_sema);
......@@ -128,7 +127,11 @@ pub fn print(
128127 }
129128 try printPtr(slice.ptr, writer, false, false, 0, level, mod, opt_sema);
130129 try writer.writeAll("[0..");
131 try print(Value.fromInterned(slice.len), writer, level - 1, mod, opt_sema);
130 if (level == 0) {
131 try writer.writeAll("(...)");
132 } else {
133 try print(Value.fromInterned(slice.len), writer, level - 1, mod, opt_sema);
134 }
132135 try writer.writeAll("]");
133136 },
134137 .ptr => {
......@@ -147,7 +150,7 @@ pub fn print(
147150 .none => try writer.writeAll("null"),
148151 else => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),
149152 },
150 .aggregate => |aggregate| try printAggregate(val, aggregate, writer, level, mod, opt_sema),
153 .aggregate => |aggregate| try printAggregate(val, aggregate, writer, level, false, mod, opt_sema),
151154 .un => |un| {
152155 if (level == 0) {
153156 try writer.writeAll(".{ ... }");
......@@ -175,6 +178,7 @@ fn printAggregate(
175178 aggregate: InternPool.Key.Aggregate,
176179 writer: anytype,
177180 level: u8,
181 is_ref: bool,
178182 zcu: *Zcu,
179183 opt_sema: ?*Sema,
180184) (@TypeOf(writer).Error || Module.CompileError)!void {
......@@ -185,6 +189,7 @@ fn printAggregate(
185189 const ty = Type.fromInterned(aggregate.ty);
186190 switch (ty.zigTypeTag(zcu)) {
187191 .Struct => if (!ty.isTuple(zcu)) {
192 if (is_ref) try writer.writeByte('&');
188193 if (ty.structFieldCount(zcu) == 0) {
189194 return writer.writeAll(".{}");
190195 }
......@@ -199,12 +204,29 @@ fn printAggregate(
199204 try writer.writeAll(" }");
200205 return;
201206 },
202 .Array => if (aggregate.storage == .bytes) {
203 return writer.print("\"{}\".*", .{std.zig.fmtEscapes(aggregate.storage.bytes)});
207 .Array => if (aggregate.storage == .bytes and aggregate.storage.bytes.len > 0) {
208 const skip_terminator = aggregate.storage.bytes[aggregate.storage.bytes.len - 1] == 0;
209 const bytes = if (skip_terminator) b: {
210 break :b aggregate.storage.bytes[0 .. aggregate.storage.bytes.len - 1];
211 } else aggregate.storage.bytes;
212 try writer.print("\"{}\"", .{std.zig.fmtEscapes(bytes)});
213 if (!is_ref) try writer.writeAll(".*");
214 return;
204215 } else if (ty.arrayLen(zcu) == 0) {
216 if (is_ref) try writer.writeByte('&');
205217 return writer.writeAll(".{}");
218 } else if (ty.arrayLen(zcu) == 1) one_byte_str: {
219 // The repr isn't `bytes`, but we might still be able to print this as a string
220 if (ty.childType(zcu).toIntern() != .u8_type) break :one_byte_str;
221 const elem_val = Value.fromInterned(aggregate.storage.values()[0]);
222 if (elem_val.isUndef(zcu)) break :one_byte_str;
223 const byte = elem_val.toUnsignedInt(zcu);
224 try writer.print("\"{}\"", .{std.zig.fmtEscapes(&.{@intCast(byte)})});
225 if (!is_ref) try writer.writeAll(".*");
226 return;
206227 },
207228 .Vector => if (ty.arrayLen(zcu) == 0) {
229 if (is_ref) try writer.writeByte('&');
208230 return writer.writeAll(".{}");
209231 },
210232 else => unreachable,
......@@ -212,6 +234,7 @@ fn printAggregate(
212234
213235 const len = ty.arrayLen(zcu);
214236
237 if (is_ref) try writer.writeByte('&');
215238 try writer.writeAll(".{ ");
216239
217240 const max_len = @min(len, max_aggregate_items);
......@@ -246,6 +269,9 @@ fn printPtr(
246269 .ptr => |ptr| ptr,
247270 else => unreachable,
248271 };
272 if (level == 0) {
273 return writer.writeAll("&...");
274 }
249275 switch (ptr.addr) {
250276 .int => |int| {
251277 if (force_addrof) try writer.writeAll("&");
......@@ -265,11 +291,22 @@ fn printPtr(
265291 try zcu.declPtr(index).renderFullyQualifiedName(zcu, writer);
266292 },
267293 .comptime_alloc => try writer.writeAll("&(comptime alloc)"),
268 .anon_decl => |anon| {
269 const ty = Type.fromInterned(ip.typeOf(anon.val));
270 try writer.print("&@as({}, ", .{ty.fmt(zcu)});
271 try print(Value.fromInterned(anon.val), writer, level - 1, zcu, opt_sema);
272 try writer.writeAll(")");
294 .anon_decl => |anon| switch (ip.indexToKey(anon.val)) {
295 .aggregate => |aggregate| try printAggregate(
296 Value.fromInterned(anon.val),
297 aggregate,
298 writer,
299 level - 1,
300 true,
301 zcu,
302 opt_sema,
303 ),
304 else => {
305 const ty = Type.fromInterned(ip.typeOf(anon.val));
306 try writer.print("&@as({}, ", .{ty.fmt(zcu)});
307 try print(Value.fromInterned(anon.val), writer, level - 1, zcu, opt_sema);
308 try writer.writeAll(")");
309 },
273310 },
274311 .comptime_field => |val| {
275312 const ty = Type.fromInterned(ip.typeOf(val));