summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTaylan Kammer <taylan.kammer@gmail.com>2026-06-06 19:28:59 +0200
committerTaylan Kammer <taylan.kammer@gmail.com>2026-06-06 19:28:59 +0200
commit416feebbf083ccdcab41fa2e0d4fc1bb0242562c (patch)
treef521f4601a0b6cf6663184c4cd781f453ecfea51 /src
parenta3f25c0232283a6144646ca758ae2e166681bbb8 (diff)
Label printing.
Diffstat (limited to 'src')
-rw-r--r--src/zisp/io/Parser.zig4
-rw-r--r--src/zisp/io/print.zig49
-rw-r--r--src/zisp/value/array.zig14
-rw-r--r--src/zisp/value/istr.zig4
-rw-r--r--src/zisp/value/sstr.zig4
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");