From 416feebbf083ccdcab41fa2e0d4fc1bb0242562c Mon Sep 17 00:00:00 2001 From: Taylan Kammer Date: Sat, 6 Jun 2026 19:28:59 +0200 Subject: Label printing. --- src/zisp/io/Parser.zig | 4 ++-- src/zisp/io/print.zig | 49 +++++++++++++++++++++++++++++++++++++----------- src/zisp/value/array.zig | 14 +++++++------- src/zisp/value/istr.zig | 4 ++++ src/zisp/value/sstr.zig | 4 ++++ 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig index 0b1a6c7..3a610dd 100644 --- a/src/zisp/io/Parser.zig +++ b/src/zisp/io/Parser.zig @@ -805,14 +805,14 @@ fn checkBlank(p: *Parser, c: u8) !enum { yes, skip_unit, no } { } } -fn isSpecialBareChar(c: u8) bool { +pub fn isSpecialBareChar(c: u8) bool { return switch (c) { '+', '-', '.', ':', '0'...'9' => true, else => false, }; } -fn isBareChar(c: u8) bool { +pub fn isBareChar(c: u8) bool { return switch (c) { // zig fmt: off 'a'...'z' , 'A'...'Z' , '0'...'9' , '!' , '$' , '%' , '*' , diff --git a/src/zisp/io/print.zig b/src/zisp/io/print.zig index 890befd..56d54f7 100644 --- a/src/zisp/io/print.zig +++ b/src/zisp/io/print.zig @@ -131,28 +131,55 @@ fn getStr(s: *const Value) ![]const u8 { } pub fn label(w: Writer, v: Value) !void { - _ = w; - _ = v; - @panic("not implemented"); + var num: Value = undefined; + var dat: ?Value = undefined; + if (value.pair.check(v)) |p| { + num = p.car; + dat = p.cdr; + } else { + num = v; + dat = null; + } + + const x = value.fixnum.unpack(num); + std.debug.assert(x >= 0); + std.debug.assert(x <= std.math.maxInt(u48)); + var buf: [12]u8 = undefined; + const end = std.fmt.printInt(&buf, x, 16, .lower, .{}); + + try w.writeAll("#%"); + try w.writeAll(buf[0..end]); + if (dat) |d| { + try w.writeByte('='); + try toWriter(w, d); + } else { + try w.writeByte('%'); + } } pub fn istr(w: Writer, p: IstrPtr) !void { - // TODO: This assumes it needs no quoting - try w.writeAll(p.str()); + try string(w, p.str()); } pub fn array(w: Writer, s: ArrayPtr) !void { switch (s.type) { - .string => try string(w, s), + .str => try string(w, s.str()), else => @panic("not implemented"), } } -pub fn string(w: Writer, s: ArrayPtr) !void { - // TODO: Check if pipes/escapes necessary. - try w.writeByte('|'); - try w.writeAll(s.str()); - try w.writeByte('|'); +pub fn string(w: Writer, s: []const u8) !void { + if (s.len == 0) @panic("Empty string must be quoted."); + const no_joins = Parser.isSpecialBareChar(s[0]); + for (s) |c| { + if (Parser.isBareChar(c)) { + try w.writeByte(c); + } else if (no_joins and (c == '.' or c == ':')) { + try w.writeByte(c); + } else { + @panic("String needs quoting."); + } + } } pub fn list(w: Writer, p: PairPtr) !void { diff --git a/src/zisp/value/array.zig b/src/zisp/value/array.zig index 67a5f37..629d31c 100644 --- a/src/zisp/value/array.zig +++ b/src/zisp/value/array.zig @@ -54,23 +54,23 @@ pub const ArrayHeader = packed struct(u64) { len_or_ptr: u48, is_slice: bool = false, is_ptr: bool = false, - type: enum(u2) { int, float, value, string }, + type: enum(u2) { int, flt, val, str }, info: packed union { int: packed struct(u12) { size: u10, signed: bool, endian: Endian = .native, }, - float: packed struct(u12) { + flt: packed struct(u12) { size: u10, _: bool, endian: Endian = .native, }, - value: packed struct(u12) { + val: packed struct(u12) { weak: bool, _: u11, }, - string: packed struct(u12) { + str: packed struct(u12) { encoding: enum(u11) { utf8, utf16, @@ -99,7 +99,7 @@ pub const ArrayHeader = packed struct(u64) { fn eltSize(self: *@This()) u16 { std.debug.assert(!self.is_ptr); return switch (self.type) { - .string => 1, + .str => 1, else => @panic("not implemented"), }; } @@ -172,8 +172,8 @@ pub fn newString(alloc: Alloc, s: []const u8) !Value { const arr: ArrayPtr = @ptrCast(ptr); arr.* = .{ .len_or_ptr = @intCast(s.len), - .type = .string, - .info = .{ .string = .{} }, + .type = .str, + .info = .{ .str = .{} }, }; const buf = arr.bufContent(); @memcpy(buf[0..s.len], s); diff --git a/src/zisp/value/istr.zig b/src/zisp/value/istr.zig index 90eccb6..551ea1e 100644 --- a/src/zisp/value/istr.zig +++ b/src/zisp/value/istr.zig @@ -1,3 +1,7 @@ +//! Intermediate-length String +//! +//! Prefixed with a 1-byte length. Typically interned in an IstrSet. + const std = @import("std"); const gc = @import("../gc.zig"); diff --git a/src/zisp/value/sstr.zig b/src/zisp/value/sstr.zig index edc61a8..59995f3 100644 --- a/src/zisp/value/sstr.zig +++ b/src/zisp/value/sstr.zig @@ -1,3 +1,7 @@ +//! Short String +//! +//! Stored as an immediate in a NaN. Max length 6 bytes, cannot contain NUL. + const std = @import("std"); const value = @import("../value.zig"); -- cgit v1.2.3