diff options
| author | Taylan Kammer <taylan.kammer@gmail.com> | 2025-02-19 23:29:26 +0100 |
|---|---|---|
| committer | Taylan Kammer <taylan.kammer@gmail.com> | 2025-02-19 23:29:26 +0100 |
| commit | 4e88891235664917a2db44b84c0bbeeb13dd71ad (patch) | |
| tree | 7ed8ac2272ce92054fdf2f4e5e09b156dfc5a4d1 /src/libzisp/value | |
| parent | 4d0db1a1065f18d879b3ff90da6ecb14e9e1ae31 (diff) | |
update
Diffstat (limited to 'src/libzisp/value')
| -rw-r--r-- | src/libzisp/value/fixnum.zig | 4 | ||||
| -rw-r--r-- | src/libzisp/value/ptr.zig | 20 | ||||
| -rw-r--r-- | src/libzisp/value/rune.zig | 75 | ||||
| -rw-r--r-- | src/libzisp/value/sstr.zig | 5 |
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 }; |
