summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/zisp/value.zig2
-rw-r--r--src/zisp/value/istr.zig51
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()));
}