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(...@@ -102,11 +102,10 @@ pub fn print(
102 .enum_tag => |enum_tag| {102 .enum_tag => |enum_tag| {
103 const enum_type = ip.loadEnumType(val.typeOf(mod).toIntern());103 const enum_type = ip.loadEnumType(val.typeOf(mod).toIntern());
104 if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {104 if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
105 try writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});105 return writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
106 return;
107 }106 }
108 if (level == 0) {107 if (level == 0) {
109 try writer.writeAll("@enumFromInt(...)");108 return writer.writeAll("@enumFromInt(...)");
110 }109 }
111 try writer.writeAll("@enumFromInt(");110 try writer.writeAll("@enumFromInt(");
112 try print(Value.fromInterned(enum_tag.int), writer, level - 1, mod, opt_sema);111 try print(Value.fromInterned(enum_tag.int), writer, level - 1, mod, opt_sema);
...@@ -128,7 +127,11 @@ pub fn print(...@@ -128,7 +127,11 @@ pub fn print(
128 }127 }
129 try printPtr(slice.ptr, writer, false, false, 0, level, mod, opt_sema);128 try printPtr(slice.ptr, writer, false, false, 0, level, mod, opt_sema);
130 try writer.writeAll("[0..");129 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 }
132 try writer.writeAll("]");135 try writer.writeAll("]");
133 },136 },
134 .ptr => {137 .ptr => {
...@@ -147,7 +150,7 @@ pub fn print(...@@ -147,7 +150,7 @@ pub fn print(
147 .none => try writer.writeAll("null"),150 .none => try writer.writeAll("null"),
148 else => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),151 else => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema),
149 },152 },
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),
151 .un => |un| {154 .un => |un| {
152 if (level == 0) {155 if (level == 0) {
153 try writer.writeAll(".{ ... }");156 try writer.writeAll(".{ ... }");
...@@ -175,6 +178,7 @@ fn printAggregate(...@@ -175,6 +178,7 @@ fn printAggregate(
175 aggregate: InternPool.Key.Aggregate,178 aggregate: InternPool.Key.Aggregate,
176 writer: anytype,179 writer: anytype,
177 level: u8,180 level: u8,
181 is_ref: bool,
178 zcu: *Zcu,182 zcu: *Zcu,
179 opt_sema: ?*Sema,183 opt_sema: ?*Sema,
180) (@TypeOf(writer).Error || Module.CompileError)!void {184) (@TypeOf(writer).Error || Module.CompileError)!void {
...@@ -185,6 +189,7 @@ fn printAggregate(...@@ -185,6 +189,7 @@ fn printAggregate(
185 const ty = Type.fromInterned(aggregate.ty);189 const ty = Type.fromInterned(aggregate.ty);
186 switch (ty.zigTypeTag(zcu)) {190 switch (ty.zigTypeTag(zcu)) {
187 .Struct => if (!ty.isTuple(zcu)) {191 .Struct => if (!ty.isTuple(zcu)) {
192 if (is_ref) try writer.writeByte('&');
188 if (ty.structFieldCount(zcu) == 0) {193 if (ty.structFieldCount(zcu) == 0) {
189 return writer.writeAll(".{}");194 return writer.writeAll(".{}");
190 }195 }
...@@ -199,12 +204,29 @@ fn printAggregate(...@@ -199,12 +204,29 @@ fn printAggregate(
199 try writer.writeAll(" }");204 try writer.writeAll(" }");
200 return;205 return;
201 },206 },
202 .Array => if (aggregate.storage == .bytes) {207 .Array => if (aggregate.storage == .bytes and aggregate.storage.bytes.len > 0) {
203 return writer.print("\"{}\".*", .{std.zig.fmtEscapes(aggregate.storage.bytes)});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;
204 } else if (ty.arrayLen(zcu) == 0) {215 } else if (ty.arrayLen(zcu) == 0) {
216 if (is_ref) try writer.writeByte('&');
205 return writer.writeAll(".{}");217 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;
206 },227 },
207 .Vector => if (ty.arrayLen(zcu) == 0) {228 .Vector => if (ty.arrayLen(zcu) == 0) {
229 if (is_ref) try writer.writeByte('&');
208 return writer.writeAll(".{}");230 return writer.writeAll(".{}");
209 },231 },
210 else => unreachable,232 else => unreachable,
...@@ -212,6 +234,7 @@ fn printAggregate(...@@ -212,6 +234,7 @@ fn printAggregate(
212234
213 const len = ty.arrayLen(zcu);235 const len = ty.arrayLen(zcu);
214236
237 if (is_ref) try writer.writeByte('&');
215 try writer.writeAll(".{ ");238 try writer.writeAll(".{ ");
216239
217 const max_len = @min(len, max_aggregate_items);240 const max_len = @min(len, max_aggregate_items);
...@@ -246,6 +269,9 @@ fn printPtr(...@@ -246,6 +269,9 @@ fn printPtr(
246 .ptr => |ptr| ptr,269 .ptr => |ptr| ptr,
247 else => unreachable,270 else => unreachable,
248 };271 };
272 if (level == 0) {
273 return writer.writeAll("&...");
274 }
249 switch (ptr.addr) {275 switch (ptr.addr) {
250 .int => |int| {276 .int => |int| {
251 if (force_addrof) try writer.writeAll("&");277 if (force_addrof) try writer.writeAll("&");
...@@ -265,11 +291,22 @@ fn printPtr(...@@ -265,11 +291,22 @@ fn printPtr(
265 try zcu.declPtr(index).renderFullyQualifiedName(zcu, writer);291 try zcu.declPtr(index).renderFullyQualifiedName(zcu, writer);
266 },292 },
267 .comptime_alloc => try writer.writeAll("&(comptime alloc)"),293 .comptime_alloc => try writer.writeAll("&(comptime alloc)"),
268 .anon_decl => |anon| {294 .anon_decl => |anon| switch (ip.indexToKey(anon.val)) {
269 const ty = Type.fromInterned(ip.typeOf(anon.val));295 .aggregate => |aggregate| try printAggregate(
270 try writer.print("&@as({}, ", .{ty.fmt(zcu)});296 Value.fromInterned(anon.val),
271 try print(Value.fromInterned(anon.val), writer, level - 1, zcu, opt_sema);297 aggregate,
272 try writer.writeAll(")");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 },
273 },310 },
274 .comptime_field => |val| {311 .comptime_field => |val| {
275 const ty = Type.fromInterned(ip.typeOf(val));312 const ty = Type.fromInterned(ip.typeOf(val));