diff options
Diffstat (limited to 'src/libzisp/value')
| -rw-r--r-- | src/libzisp/value/boole.zig | 33 | ||||
| -rw-r--r-- | src/libzisp/value/char.zig | 31 | ||||
| -rw-r--r-- | src/libzisp/value/double.zig | 38 | ||||
| -rw-r--r-- | src/libzisp/value/eof.zig | 28 | ||||
| -rw-r--r-- | src/libzisp/value/fixnum.zig | 84 | ||||
| -rw-r--r-- | src/libzisp/value/istr.zig | 65 | ||||
| -rw-r--r-- | src/libzisp/value/nil.zig | 28 | ||||
| -rw-r--r-- | src/libzisp/value/pair.zig | 55 | ||||
| -rw-r--r-- | src/libzisp/value/ptr.zig | 174 | ||||
| -rw-r--r-- | src/libzisp/value/rune.zig | 82 | ||||
| -rw-r--r-- | src/libzisp/value/seq.zig | 57 | ||||
| -rw-r--r-- | src/libzisp/value/sstr.zig | 78 |
12 files changed, 0 insertions, 753 deletions
diff --git a/src/libzisp/value/boole.zig b/src/libzisp/value/boole.zig deleted file mode 100644 index 2e94e4d..0000000 --- a/src/libzisp/value/boole.zig +++ /dev/null @@ -1,33 +0,0 @@ -const Value = @import("../value.zig").Value; - -pub const f = Value{ .misc = .{ .value = .f } }; -pub const t = Value{ .misc = .{ .value = .t } }; - -// Zig API - -/// Checks if the value is a boole. -pub fn check(v: Value) bool { - return v.bits == f.bits or v.bits == t.bits; -} - -pub fn assert(v: Value) void { - if (!check(v)) { - v.dump(); - @panic("not bool"); - } -} - -pub fn pack(b: bool) Value { - return if (b) t else f; -} - -pub fn unpack(v: Value) bool { - assert(v); - return v.bits == t.bits; -} - -// Zisp API - -pub fn pred(v: Value) Value { - return pack(check(v)); -} diff --git a/src/libzisp/value/char.zig b/src/libzisp/value/char.zig deleted file mode 100644 index 09a3034..0000000 --- a/src/libzisp/value/char.zig +++ /dev/null @@ -1,31 +0,0 @@ -const value = @import("../value.zig"); - -const Value = value.Value; - -// Zig API - -pub fn check(v: Value) bool { - return v.isOtherTag(.char); -} - -pub fn assert(v: Value) void { - if (!check(v)) { - v.dump(); - @panic("not char"); - } -} - -pub fn pack(c: u21) Value { - return .{ .char = .{ .value = c } }; -} - -pub fn unpack(v: Value) u21 { - assert(v); - return @truncate(v.char.value); -} - -// Zisp API - -pub fn pred(v: Value) Value { - return value.boole.pack(check(v)); -} diff --git a/src/libzisp/value/double.zig b/src/libzisp/value/double.zig deleted file mode 100644 index 5cfe6ee..0000000 --- a/src/libzisp/value/double.zig +++ /dev/null @@ -1,38 +0,0 @@ -const value = @import("../value.zig"); -const Value = value.Value; - -// Zig API - -/// Checks for a Zisp double (double, +inf, -inf, or canonical NaN). -pub fn check(v: Value) bool { - return v.isDouble(); -} - -/// Asserts check(). -pub fn assert(v: Value) void { - if (!check(v)) { - v.dump(); - @panic("not double"); - } -} - -pub fn pack(d: f64) Value { - return .{ .double = d }; -} - -pub fn unpack(v: Value) f64 { - assert(v); - return v.double; -} - -// Zisp API - -pub fn pred(v: Value) Value { - return value.boole.pack(check(v)); -} - -pub fn add(v1: Value, v2: Value) Value { - const d1 = unpack(v1); - const d2 = unpack(v2); - return pack(d1 + d2); -} diff --git a/src/libzisp/value/eof.zig b/src/libzisp/value/eof.zig deleted file mode 100644 index 4b16669..0000000 --- a/src/libzisp/value/eof.zig +++ /dev/null @@ -1,28 +0,0 @@ -const value = @import("../value.zig"); - -const Value = value.Value; - -pub const eof = Value{ .misc = .{ .value = .eof } }; - -// Zig API - -pub fn check(v: Value) bool { - return v.bits == eof.bits; -} - -pub fn assert(v: Value) void { - if (!check(v)) { - v.dump(); - @panic("not bool"); - } -} - -// Zisp API - -pub fn get() Value { - return eof; -} - -pub fn pred(v: Value) Value { - return value.boole.pack(check(v)); -} diff --git a/src/libzisp/value/fixnum.zig b/src/libzisp/value/fixnum.zig deleted file mode 100644 index 80fb4ae..0000000 --- a/src/libzisp/value/fixnum.zig +++ /dev/null @@ -1,84 +0,0 @@ -const std = @import("std"); -const value = @import("../value.zig"); - -const Value = value.Value; - -// Zig API - -/// Checks for a Zisp fixnum. -pub fn check(v: Value) bool { - return v.isFixnum(); -} - -/// Asserts check(). -pub fn assert(v: Value) void { - if (!check(v)) { - v.dump(); - @panic("not fixnum"); - } -} - -// See detailed NaN packing docs for why the +/- 1. -pub const min = std.math.minInt(i52) + 1; -pub const max = std.math.maxInt(i52) - 1; - -fn assertValidRange(int: i64) void { - if (int < min) { - std.debug.print("int too small for fixnum: {}\n", .{int}); - @panic("int too small for fixnum"); - } - if (int > max) { - std.debug.print("int too large for fixnum: {}\n", .{int}); - @panic("int too large for fixnum"); - } -} - -fn packNegative(int: i64) Value { - return @bitCast(int); -} - -fn unpackNegative(v: Value) i64 { - return @bitCast(v); -} - -const positive_mask: u64 = 0xfff7ffffffffffff; - -fn packPositive(int: i64) Value { - const uint: u64 = @bitCast(int); - return @bitCast(uint ^ positive_mask); -} - -fn unpackPositive(v: Value) i64 { - const uint: u64 = @bitCast(v); - return @bitCast(uint ^ positive_mask); -} - -pub fn pack(int: i64) Value { - assertValidRange(int); - if (int < 0) { - return packNegative(int); - } else { - return packPositive(int); - } -} - -pub fn unpack(v: Value) i64 { - assert(v); - if (v.fixnum.negative) { - return unpackNegative(v); - } else { - return unpackPositive(v); - } -} - -// Zisp API - -pub fn pred(v: Value) Value { - return value.boole.pack(check(v)); -} - -pub fn add(v1: Value, v2: Value) Value { - const int1 = unpack(v1); - const int2 = unpack(v2); - return pack(int1 + int2); -} diff --git a/src/libzisp/value/istr.zig b/src/libzisp/value/istr.zig deleted file mode 100644 index abd0447..0000000 --- a/src/libzisp/value/istr.zig +++ /dev/null @@ -1,65 +0,0 @@ -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 Hval = gc.Hval; - -const Value = value.Value; - -// Zig API - -pub fn check(v: Value) bool { - return ptr.checkZispTag(v, .seq); -} - -pub fn assert(v: Value) void { - if (!check(v)) { - v.dump(); - @panic("not istr"); - } -} - -pub fn intern(str: []const u8, quoted: bool) Value { - if (str.len > value.fixnum.max) { - @panic("String length out of fixnum range."); - } - const header: seq.Header = .{ - .type = .string, - .info = .{ .string = .{ - .enc = .utf8, - .quoted = quoted, - .interned = true, - } }, - .size = @intCast(str.len), - }; - const header_ptr = gc.intern(header, str); - return ptr.pack(@ptrCast(header_ptr), .seq); -} - -pub fn getHeader(v: Value) *seq.Header { - assert(v); - const header_ptr, _ = ptr.unpack(v); - return gc.istrHeader(header_ptr); -} - -pub fn getHeaderFromPtr(p: *Hval) *seq.Header { - return gc.istrHeader(p); -} - -// Zisp API - -pub fn pred(v: Value) Value { - return value.boole.pack(check(v)); -} - -pub fn len(v: Value) Value { - const l = getHeader(v).size; - if (l > value.fixnum.max) { - @panic("string length out of range"); - } - return value.fixnum.pack(@intCast(l)); -} diff --git a/src/libzisp/value/nil.zig b/src/libzisp/value/nil.zig deleted file mode 100644 index f95ecad..0000000 --- a/src/libzisp/value/nil.zig +++ /dev/null @@ -1,28 +0,0 @@ -const value = @import("../value.zig"); - -const Value = value.Value; - -pub const nil = Value{ .misc = .{ .value = .nil } }; - -// Zig API - -pub fn check(v: Value) bool { - return v.bits == nil.bits; -} - -pub fn assert(v: Value) void { - if (!check(v)) { - v.dump(); - @panic("not bool"); - } -} - -// Zisp API - -pub fn get() Value { - return nil; -} - -pub fn pred(v: Value) Value { - return value.boole.pack(check(v)); -} diff --git a/src/libzisp/value/pair.zig b/src/libzisp/value/pair.zig deleted file mode 100644 index 6ea1edf..0000000 --- a/src/libzisp/value/pair.zig +++ /dev/null @@ -1,55 +0,0 @@ -const std = @import("std"); - -const value = @import("../value.zig"); -const gc = @import("../gc.zig"); - -const ptr = @import("ptr.zig"); - -const Value = value.Value; - -// Zig API - -pub fn check(v: Value) bool { - return ptr.checkZispTag(v, .pair); -} - -pub fn assert(v: Value) void { - if (!check(v)) { - v.dump(); - @panic("not pair"); - } -} - -// Zisp API - -pub fn pred(v: Value) Value { - return value.boole.pack(check(v)); -} - -pub fn cons(v1: Value, v2: Value) Value { - return ptr.pack(@ptrCast(gc.cons(v1, v2)), .pair); -} - -fn getMem(v: Value) *[2]Value { - return @ptrCast(ptr.unpack(v).@"0"); -} - -pub fn car(v: Value) Value { - assert(v); - return getMem(v)[0]; -} - -pub fn cdr(v: Value) Value { - assert(v); - return getMem(v)[1]; -} - -pub fn setcar(v: Value, new: Value) void { - assert(v); - getMem(v)[0] = new; -} - -pub fn setcdr(v: Value, new: Value) void { - assert(v); - getMem(v)[1] = new; -} diff --git a/src/libzisp/value/ptr.zig b/src/libzisp/value/ptr.zig deleted file mode 100644 index 2ed3765..0000000 --- a/src/libzisp/value/ptr.zig +++ /dev/null @@ -1,174 +0,0 @@ -const std = @import("std"); - -const gc = @import("../gc.zig"); -const value = @import("../value.zig"); - -const Hval = gc.Hval; - -const Value = value.Value; - -// Zig API - -pub fn check(v: Value) bool { - return v.isPtr(); -} - -pub fn assert(v: Value) void { - if (!check(v)) { - v.dump(); - @panic("not a pointer"); - } -} - -// Foreign Pointers - -pub fn checkForeign(v: Value) bool { - return check(v) and v.ptr.is_foreign; -} - -pub fn assertForeign(v: Value) void { - if (!checkForeign(v)) { - v.dump(); - @panic("not foreign pointer"); - } -} - -pub fn packForeign(int: u50) Value { - return .{ .fptr = .{ .value = int } }; -} - -pub fn unpackForeign(v: Value) u50 { - assertForeign(v); - return v.fptr.value; -} - -// Zisp Pointers - -pub fn checkZisp(v: Value) bool { - return check(v) and !v.ptr.is_foreign; -} - -pub fn assertZisp(v: Value) void { - if (!checkZisp(v)) { - v.dump(); - @panic("not zisp pointer"); - } -} - -pub fn checkWeak(v: Value) bool { - return checkZisp(v) and v.zptr.is_weak; -} - -pub fn assertWeak(v: Value) void { - if (!checkWeak(v)) { - v.dump(); - @panic("not zisp weak pointer"); - } -} - -pub fn checkZispTag(v: Value, tag: Tag) bool { - return checkZisp(v) and unpack(v).@"1" == tag; -} - -pub fn assertZispTag(v: Value, tag: Tag) void { - if (!checkZispTag(v, tag)) { - v.dump(); - @panic("not zisp pointer or wrong tag"); - } -} - -pub fn checkStrong(v: Value) bool { - return checkZisp(v) and !v.zptr.is_weak; -} - -pub fn assertStrong(v: Value) void { - if (!checkStrong(v)) { - v.dump(); - @panic("not zisp strong pointer"); - } -} - -pub fn packZisp(ptr: *Hval, tag: Tag, is_weak: bool) Value { - return .{ .zptr = .{ - .tagged_value = tagPtr(ptr, tag), - .is_weak = is_weak, - } }; -} - -pub fn pack(ptr: *Hval, tag: Tag) Value { - return packZisp(ptr, tag, false); -} - -pub fn packWeak(ptr: *Hval, tag: Tag) Value { - return packZisp(ptr, tag, true); -} - -// Unpacks weak as well; no need for a separate fn. -pub fn unpack(v: Value) struct { *Hval, Tag } { - assertZisp(v); - return untagPtr(v.zptr.tagged_value); -} - -pub fn setWeakNull(v: *Value) void { - assertWeak(v.*); - v.zptr.tagged_value = 0; -} - -pub fn isWeakNull(v: Value) bool { - assertWeak(v); - return v.zptr.tagged_value == 0; -} - -fn tagPtr(ptr: *Hval, tag: Tag) u48 { - const int: usize = @intFromPtr(ptr); - const untagged: u48 = @intCast(int); - return untagged | @intFromEnum(tag); -} - -fn untagPtr(tagged: u48) struct { *Hval, Tag } { - const untagged: u48 = tagged & 0xfffffffffff8; - const ptr: *Hval = @ptrFromInt(untagged); - const int: u3 = @truncate(tagged); - const tag: Tag = @enumFromInt(int); - return .{ ptr, tag }; -} - -pub const Tag = enum(u3) { - /// Pair aka cons cell aka *[2]Value - pair, - /// Sequence of various kinds (16-bit meta, 48-bit length, then data) - seq, - /// Procedure - proc, -}; - -// Zisp API - -pub fn predForeign(v: Value) Value { - return value.boole.pack(checkForeign(v)); -} - -pub fn makeWeak(v: Value) Value { - assertStrong(v); - var copy = v; - copy.zptr.is_weak = true; - return copy; -} - -pub fn predWeak(v: Value) Value { - return value.boole.pack(checkWeak(v)); -} - -pub fn predWeakNull(v: Value) Value { - return value.boole.pack(isWeakNull(v)); -} - -pub fn getWeak(v: Value) Value { - if (isWeakNull(v)) { - return value.boole.f; - } else { - var copy = v; - copy.zptr.is_weak = false; - return copy; - } -} diff --git a/src/libzisp/value/rune.zig b/src/libzisp/value/rune.zig deleted file mode 100644 index 195210e..0000000 --- a/src/libzisp/value/rune.zig +++ /dev/null @@ -1,82 +0,0 @@ -const std = @import("std"); - -const value = @import("../value.zig"); - -const ShortString = value.ShortString; -const Value = value.Value; - -// Zig API - -pub fn check(v: Value) bool { - return v.isOtherTag(.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; - } - if (!std.ascii.isAlphabetic(s[0])) { - return false; - } - for (s[1..]) |c| { - if (!std.ascii.isAlphanumeric(c)) { - 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); - return packForced(s); -} - -pub fn packForced(s: []const u8) Value { - var v = Value{ .rune = .{ .name = 0 } }; - const dest: [*]u8 = @ptrCast(&v.rune.name); - @memcpy(dest, s); - return v; -} - -pub fn unpack(v: Value) ShortString { - assert(v); - const s: [6]u8 = @bitCast(v.rune.name); - inline for (0..6) |i| { - if (s[i] == 0) return .{ .buffer = s, .len = i }; - } - return .{ .buffer = s, .len = 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/seq.zig b/src/libzisp/value/seq.zig deleted file mode 100644 index 3418a5a..0000000 --- a/src/libzisp/value/seq.zig +++ /dev/null @@ -1,57 +0,0 @@ -const builtin = @import("builtin"); -const std = @import("std"); - -const value = @import("../value.zig"); -const gc = @import("../gc.zig"); - -const Value = value.Value; - -const Endian = enum(u1) { - little, - big, - - const native: Endian = switch (builtin.target.cpu.arch.endian()) { - .little => .little, - .big => .big, - }; -}; - -pub const Header = packed struct(u64) { - type: enum(u2) { - values, - string, - ints, - floats, - }, - info: packed union { - values: packed struct(u14) { - weak: bool = false, - _: u13 = 0, - }, - string: packed struct(u14) { - enc: enum(u4) { utf8, utf16, utf24, utf32 }, - endian: Endian = .native, - quoted: bool, - interned: bool, - _: u7 = 0, - }, - ints: packed struct(u14) { - signed: bool, - endian: Endian = .native, - size: u12, - }, - floats: packed struct(u14) { - double: bool, - endian: Endian = .native, - _: u12 = 0, - }, - }, - size: u48, - - pub fn bytes(self: *Header) []u8 { - const hs = @sizeOf(Header); - const ptr: [*]u8 = @ptrCast(self); - const end = hs + self.size; - return ptr[hs..end]; - } -}; diff --git a/src/libzisp/value/sstr.zig b/src/libzisp/value/sstr.zig deleted file mode 100644 index b02fd3d..0000000 --- a/src/libzisp/value/sstr.zig +++ /dev/null @@ -1,78 +0,0 @@ -const std = @import("std"); - -const value = @import("../value.zig"); - -const ShortString = value.ShortString; -const OtherTag = value.OtherTag; -const Value = value.Value; - -// Zig API - -pub fn check(v: Value) bool { - return v.isOtherTag(.sstr) or v.isOtherTag(.qstr); -} - -pub fn assert(v: Value) void { - if (!check(v)) { - v.dump(); - @panic("not sstr"); - } -} - -pub fn checkQuoted(v: Value) bool { - return v.isOtherTag(.qstr); -} - -// For now, ignore encoding, just treat it as []u8. - -pub fn isValidSstr(s: []const u8) bool { - if (s.len > 6) { - return false; - } - for (s) |c| { - if (c == 0) { - return false; - } - } - return true; -} - -fn assertValidSstr(s: []const u8) void { - if (!isValidSstr(s)) { - std.debug.print("invalid sstr: {s}\n", .{s}); - @panic("invalid sstr"); - } -} - -// Different ways of doing the following have been tested, including manual -// 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 { - return _pack(s, .sstr); -} - -pub fn packQuoted(s: []const u8) Value { - return _pack(s, .qstr); -} - -fn _pack(s: []const u8, tag: OtherTag) Value { - assertValidSstr(s); - var v = Value{ .sstr = .{ .string = 0, .tag = tag } }; - const dest: [*]u8 = @ptrCast(&v.sstr.string); - @memcpy(dest, s); - return v; -} - -pub fn unpack(v: Value) ShortString { - assert(v); - const s: [6]u8 = @bitCast(v.sstr.string); - inline for (0..6) |i| { - if (s[i] == 0) return .{ .buffer = s, .len = i }; - } - return .{ .buffer = s, .len = 6 }; -} - -// No Zisp API for sstr specifically, since it's a string. See string.zig. |
