From a6e5967eb40f9686f1c487b36b38a9a6238ff850 Mon Sep 17 00:00:00 2001 From: Taylan Kammer Date: Fri, 29 May 2026 17:48:21 +0200 Subject: The istr type is now a 1-byte length prefixed heap string. --- src/zisp/value.zig | 2 ++ src/zisp/value/istr.zig | 51 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/zisp/value.zig b/src/zisp/value.zig index e8813eb..96351f2 100644 --- a/src/zisp/value.zig +++ b/src/zisp/value.zig @@ -214,6 +214,8 @@ pub const Zptr = *align(8) anyopaque; pub const PtrTag = enum(u3) { /// Pair aka cons cell aka *[2]Value pair, + /// Interned string buffer (8-bit length, then contents) + istr, /// Array of various types (see `Array` type for details) array, /// Procedure diff --git a/src/zisp/value/istr.zig b/src/zisp/value/istr.zig index c1c7093..f34dbd0 100644 --- a/src/zisp/value/istr.zig +++ b/src/zisp/value/istr.zig @@ -3,32 +3,54 @@ const std = @import("std"); const value = @import("../value.zig"); const gc = @import("../gc.zig"); -const ptr = @import("ptr.zig"); -const seq = @import("seq.zig"); - const Value = value.Value; // Zig API -pub fn check(v: Value) ?*seq.Header { - if (v.getPtr(.seq)) |p| { - const h: *seq.Header = @ptrCast(p); - if (h.type == .string and h.info.string.interned) { - return h; - } +/// Pointer to beginning of an interned string with a 1-byte length prefix. +/// Aligned to 8 bytes like all Zisp heap pointers. +pub const Istr = *align(8) struct { + pub fn buf(self: *@This()) [*]u8 { + return @ptrCast(self); + } + + pub fn len(self: *@This()) u8 { + return buf()[0]; + } + + pub fn str(self: *@This()) []u8 { + return buf()[1 .. 1 + len()]; + } +}; + +pub fn check(v: Value) ?Istr { + if (v.getPtr(.istr)) |p| { + return @ptrCast(p); } return null; } -pub fn assert(v: Value) *seq.Header { +pub fn assert(v: Value) Istr { return check(v) orelse { v.dump(); @panic("not istr"); }; } -pub fn intern(str: []const u8) Value { - return gc.internString(str); +pub fn isValidIstr(s: []const u8) bool { + return s.len <= 255; +} + +fn assertValidIstr(s: []const u8) void { + if (!isValidIstr(s)) { + std.debug.print("invalid istr: {s}\n", .{s}); + @panic("invalid istr"); + } +} + +pub fn intern(s: []const u8) !Value { + assertValidIstr(s); + return gc.internString(s); } // Zisp API @@ -38,7 +60,6 @@ pub fn pred(v: Value) Value { } pub fn len(v: Value) Value { - const l = assert(v).size; - std.debug.assert(l <= value.fixnum.max); - return value.fixnum.pack(@intCast(l)); + const istr = assert(v); + return value.fixnum.pack(@intCast(istr.len())); } -- cgit v1.2.3