summaryrefslogtreecommitdiff
path: root/src/libzisp/value
diff options
context:
space:
mode:
authorTaylan Kammer <taylan.kammer@gmail.com>2025-02-19 23:29:26 +0100
committerTaylan Kammer <taylan.kammer@gmail.com>2025-02-19 23:29:26 +0100
commit4e88891235664917a2db44b84c0bbeeb13dd71ad (patch)
tree7ed8ac2272ce92054fdf2f4e5e09b156dfc5a4d1 /src/libzisp/value
parent4d0db1a1065f18d879b3ff90da6ecb14e9e1ae31 (diff)
update
Diffstat (limited to 'src/libzisp/value')
-rw-r--r--src/libzisp/value/fixnum.zig4
-rw-r--r--src/libzisp/value/ptr.zig20
-rw-r--r--src/libzisp/value/rune.zig75
-rw-r--r--src/libzisp/value/sstr.zig5
4 files changed, 84 insertions, 20 deletions
diff --git a/src/libzisp/value/fixnum.zig b/src/libzisp/value/fixnum.zig
index 888dd3a..c705880 100644
--- a/src/libzisp/value/fixnum.zig
+++ b/src/libzisp/value/fixnum.zig
@@ -28,11 +28,11 @@ pub fn isValidRange(int: i64) bool {
fn assertValidRange(int: i64) void {
if (int < fixnum_min) {
- std.debug.print("int too small for fixnum: {}", .{int});
+ std.debug.print("int too small for fixnum: {}\n", .{int});
@panic("int too small for fixnum");
}
if (int > fixnum_max) {
- std.debug.print("int too large for fixnum: {}", .{int});
+ std.debug.print("int too large for fixnum: {}\n", .{int});
@panic("int too large for fixnum");
}
}
diff --git a/src/libzisp/value/ptr.zig b/src/libzisp/value/ptr.zig
index fe13af5..e1fadf2 100644
--- a/src/libzisp/value/ptr.zig
+++ b/src/libzisp/value/ptr.zig
@@ -31,27 +31,13 @@ pub fn assertForeign(v: Value) void {
}
}
-pub fn checkForeignRange(ptr: *anyopaque) bool {
- const int = @intFromPtr(ptr);
- return int <= std.math.maxInt(u50);
-}
-
-fn assertForeignRange(ptr: *anyopaque) void {
- if (!checkForeignRange(ptr)) {
- std.debug.print("foreign pointer out of range: {}\n", .{ptr});
- @panic("foreign pointer out of range");
- }
-}
-
-pub fn packForeign(ptr: *anyopaque) Value {
- assertForeignRange(ptr);
- const int: u50 = @intCast(@intFromPtr(ptr));
+pub fn packForeign(int: u50) Value {
return .{ .fptr = .{ .value = int } };
}
-pub fn unpackForeign(v: Value) *anyopaque {
+pub fn unpackForeign(v: Value) u50 {
assertForeign(v);
- return @ptrFromInt(v.fptr.value);
+ return v.fptr.value;
}
// Zisp Pointers
diff --git a/src/libzisp/value/rune.zig b/src/libzisp/value/rune.zig
new file mode 100644
index 0000000..ab251b4
--- /dev/null
+++ b/src/libzisp/value/rune.zig
@@ -0,0 +1,75 @@
+const std = @import("std");
+
+const value = @import("../value.zig");
+
+const Value = value.Value;
+
+// Zig API
+
+pub fn check(v: Value) bool {
+ return v.isOther(.rune);
+}
+
+pub fn assert(v: Value) void {
+ if (!check(v)) {
+ v.dump();
+ @panic("not rune");
+ }
+}
+
+pub fn isValidRune(s: []const u8) bool {
+ if (s.len == 0 or s.len > 6) {
+ return false;
+ }
+ for (s) |c| {
+ switch (c) {
+ 'A'...'Z' => {},
+ 'a'...'z' => {},
+ else => return false,
+ }
+ }
+ return true;
+}
+
+fn assertValidRune(s: []const u8) void {
+ if (!isValidRune(s)) {
+ std.debug.print("invalid rune: '{s}'\n", .{s});
+ @panic("invalid rune");
+ }
+}
+
+// See sstr.zig which uses equivalent code; probably good to keep in sync.
+
+pub fn pack(s: []const u8) Value {
+ assertValidRune(s);
+ var v = Value{ .rune = .{ .name = 0 } };
+ const dest: [*]u8 = @ptrCast(&v.rune.name);
+ @memcpy(dest, s);
+ return v;
+}
+
+pub fn unpack(v: Value) struct { [6]u8, u3 } {
+ const s: [6]u8 = @bitCast(v.rune.name);
+ inline for (0..6) |i| {
+ if (s[i] == 0) return .{ s, i };
+ }
+ return .{ s, 6 };
+}
+
+// Zisp API
+
+pub fn pred(v: Value) Value {
+ return value.boole.pack(check(v));
+}
+
+pub fn make(v: Value) Value {
+ const s, const l = value.sstr.unpack(v);
+ return pack(s[0..l]);
+}
+
+pub fn getName(v: Value) Value {
+ const s, const l = unpack(v);
+ return value.sstr.pack(s[0..l]);
+}
+
+// TODO: Registering decoders
diff --git a/src/libzisp/value/sstr.zig b/src/libzisp/value/sstr.zig
index 896b8d7..2be2647 100644
--- a/src/libzisp/value/sstr.zig
+++ b/src/libzisp/value/sstr.zig
@@ -31,7 +31,7 @@ pub fn isValidSstr(s: []const u8) bool {
fn assertValidSstr(s: []const u8) void {
if (!isValidSstr(s)) {
- std.debug.print("invalid sstr: {s}", .{s});
+ std.debug.print("invalid sstr: {s}\n", .{s});
@panic("invalid sstr");
}
}
@@ -40,6 +40,8 @@ fn assertValidSstr(s: []const u8) void {
// shifting and bit masking, but memcpy always wins easily according to our
// micro-benchmarks, under both ReleaseSafe and ReleaseFast.
+// Note: rune.zig uses equivalent code; probably good to keep in sync.
+
pub fn pack(s: []const u8) Value {
assertValidSstr(s);
var v = Value{ .sstr = .{ .string = 0 } };
@@ -49,6 +51,7 @@ pub fn pack(s: []const u8) Value {
}
pub fn unpack(v: Value) struct { [6]u8, u3 } {
+ assert(v);
const s: [6]u8 = @bitCast(v.sstr.string);
inline for (0..6) |i| {
if (s[i] == 0) return .{ s, i };