diff options
| -rw-r--r-- | src/libzisp.zig | 431 | ||||
| -rw-r--r-- | src/libzisp/value/sstr.zig | 15 |
2 files changed, 216 insertions, 230 deletions
diff --git a/src/libzisp.zig b/src/libzisp.zig index 17264a8..be3f683 100644 --- a/src/libzisp.zig +++ b/src/libzisp.zig @@ -13,107 +13,107 @@ pub const value = @import("libzisp/value.zig"); pub const ShortString = value.ShortString; pub const Value = value.Value; -// test "double" { -// const d1: f64 = 0.123456789; -// const d2: f64 = -0.987654321; -// const v1 = value.double.pack(d1); -// const v2 = value.double.pack(d2); -// const v3 = value.double.add(v1, v2); -// const result = value.double.unpack(v3); - -// try std.testing.expect(value.double.check(v1)); -// try std.testing.expect(value.double.check(v2)); -// try std.testing.expect(value.double.check(v3)); - -// try std.testing.expectEqual(d1 + d2, result); -// } - -// test "fixnum" { -// const int1: i64 = 123456789; -// const int2: i64 = -987654321; -// const v1 = value.fixnum.pack(int1); -// const v2 = value.fixnum.pack(int2); -// const v3 = value.fixnum.add(v1, v2); -// const result = value.fixnum.unpack(v3); - -// try std.testing.expect(value.fixnum.check(v1)); -// try std.testing.expect(value.fixnum.check(v2)); -// try std.testing.expect(value.fixnum.check(v3)); - -// try std.testing.expectEqual(int1 + int2, result); -// } - -// test "ptr" { -// const ptr = value.ptr; - -// const val: [*]gc.Bucket = @ptrFromInt(256); -// const tag = ptr.Tag.string; - -// const p = ptr.pack(val, tag); -// try std.testing.expect(ptr.check(p)); -// try std.testing.expect(ptr.checkZisp(p, tag)); -// try std.testing.expect(ptr.checkStrong(p)); - -// const pv, const pt = ptr.unpack(p); -// try std.testing.expectEqual(val, pv); -// try std.testing.expectEqual(tag, pt); - -// var w = ptr.makeWeak(p); -// try std.testing.expect(ptr.check(w)); -// try std.testing.expect(ptr.checkZisp(w, tag)); -// try std.testing.expect(ptr.checkWeak(w)); -// try std.testing.expectEqual(true, value.boole.unpack(ptr.predWeak(w))); -// try std.testing.expectEqual(false, value.boole.unpack(ptr.predWeakNull(w))); - -// const wv, const wt = ptr.unpack(w); -// try std.testing.expectEqual(val, wv); -// try std.testing.expectEqual(tag, wt); - -// const wv2, const wt2 = ptr.unpack(ptr.getWeak(w)); -// try std.testing.expectEqual(val, wv2); -// try std.testing.expectEqual(tag, wt2); - -// ptr.setWeakNull(&w); -// try std.testing.expect(ptr.check(w)); -// try std.testing.expect(ptr.checkWeak(w)); -// try std.testing.expect(ptr.isWeakNull(w)); -// try std.testing.expectEqual(true, value.boole.unpack(ptr.predWeak(w))); -// try std.testing.expectEqual(true, value.boole.unpack(ptr.predWeakNull(w))); -// try std.testing.expectEqual(false, value.boole.unpack(ptr.getWeak(w))); -// } - -// test "fptr" { -// const ptr = value.ptr; - -// const int1: u50 = 0; -// const int2: u50 = std.math.maxInt(u50); - -// const f1 = ptr.packForeign(int1); -// try std.testing.expect(ptr.checkForeign(f1)); -// try std.testing.expectEqual(int1, ptr.unpackForeign(f1)); - -// const f2 = ptr.packForeign(int2); -// try std.testing.expect(ptr.checkForeign(f2)); -// try std.testing.expectEqual(int2, ptr.unpackForeign(f2)); -// } - -// test "rune" { -// const r = value.rune.pack("test"); -// try std.testing.expect(value.rune.check(r)); - -// const s = value.rune.unpack(r); -// try std.testing.expectEqualStrings("test", s.slice()); -// } +test "double" { + const d1: f64 = 0.123456789; + const d2: f64 = -0.987654321; + const v1 = value.double.pack(d1); + const v2 = value.double.pack(d2); + const v3 = value.double.add(v1, v2); + const result = value.double.unpack(v3); + + try std.testing.expect(value.double.check(v1)); + try std.testing.expect(value.double.check(v2)); + try std.testing.expect(value.double.check(v3)); + + try std.testing.expectEqual(d1 + d2, result); +} + +test "fixnum" { + const int1: i64 = 123456789; + const int2: i64 = -987654321; + const v1 = value.fixnum.pack(int1); + const v2 = value.fixnum.pack(int2); + const v3 = value.fixnum.add(v1, v2); + const result = value.fixnum.unpack(v3); + + try std.testing.expect(value.fixnum.check(v1)); + try std.testing.expect(value.fixnum.check(v2)); + try std.testing.expect(value.fixnum.check(v3)); + + try std.testing.expectEqual(int1 + int2, result); +} + +test "ptr" { + const ptr = value.ptr; + + const val: [*]gc.Bucket = @ptrFromInt(256); + const tag = ptr.Tag.string; + + const p = ptr.pack(val, tag); + try std.testing.expect(ptr.check(p)); + try std.testing.expect(ptr.checkZisp(p, tag)); + try std.testing.expect(ptr.checkStrong(p)); + + const pv, const pt = ptr.unpack(p); + try std.testing.expectEqual(val, pv); + try std.testing.expectEqual(tag, pt); + + var w = ptr.makeWeak(p); + try std.testing.expect(ptr.check(w)); + try std.testing.expect(ptr.checkZisp(w, tag)); + try std.testing.expect(ptr.checkWeak(w)); + try std.testing.expectEqual(true, value.boole.unpack(ptr.predWeak(w))); + try std.testing.expectEqual(false, value.boole.unpack(ptr.predWeakNull(w))); + + const wv, const wt = ptr.unpack(w); + try std.testing.expectEqual(val, wv); + try std.testing.expectEqual(tag, wt); + + const wv2, const wt2 = ptr.unpack(ptr.getWeak(w)); + try std.testing.expectEqual(val, wv2); + try std.testing.expectEqual(tag, wt2); + + ptr.setWeakNull(&w); + try std.testing.expect(ptr.check(w)); + try std.testing.expect(ptr.checkWeak(w)); + try std.testing.expect(ptr.isWeakNull(w)); + try std.testing.expectEqual(true, value.boole.unpack(ptr.predWeak(w))); + try std.testing.expectEqual(true, value.boole.unpack(ptr.predWeakNull(w))); + try std.testing.expectEqual(false, value.boole.unpack(ptr.getWeak(w))); +} + +test "fptr" { + const ptr = value.ptr; + + const int1: u50 = 0; + const int2: u50 = std.math.maxInt(u50); + + const f1 = ptr.packForeign(int1); + try std.testing.expect(ptr.checkForeign(f1)); + try std.testing.expectEqual(int1, ptr.unpackForeign(f1)); + + const f2 = ptr.packForeign(int2); + try std.testing.expect(ptr.checkForeign(f2)); + try std.testing.expectEqual(int2, ptr.unpackForeign(f2)); +} + +test "rune" { + const r = value.rune.pack("test"); + try std.testing.expect(value.rune.check(r)); + + const s = value.rune.unpack(r); + try std.testing.expectEqualStrings("test", s.slice()); +} const SstrImpl = struct { SstrPack, SstrUnpack }; const SstrPack = *const fn ([]const u8) Value; -const SstrUnpack = *const fn (Value) struct { [6]u8, u3 }; +const SstrUnpack = *const fn (Value) ShortString; test "sstr" { const impls = [_]SstrImpl{ .{ value.sstr.pack, value.sstr.unpack }, - .{ value.sstr.pack, value.sstr.unpack1 }, - // .{ value.sstr.pack, value.sstr.unpack2 }, + // .{ value.sstr.pack1, value.sstr.unpack1 }, + // .{ value.sstr.pack2, value.sstr.unpack2 }, // .{ value.sstr.pack3, value.sstr.unpack3 }, // .{ value.sstr.pack4, value.sstr.unpack4 }, }; @@ -126,7 +126,7 @@ test "sstr" { const iters = switch (@import("builtin").mode) { .Debug, .ReleaseSmall => 10_000_000, .ReleaseSafe => 100_000_000, - .ReleaseFast => 100_000_000, + .ReleaseFast => 1_000_000_000, }; std.debug.print("Benchmarking with {} iters.\n", .{iters}); inline for (impls, 0..) |impl, i| { @@ -142,22 +142,17 @@ fn testSstr(impl: SstrImpl) !void { const ss2 = pack("123"); const ss3 = pack("123456"); + const s1 = unpack(ss1); + const s2 = unpack(ss2); + const s3 = unpack(ss3); + try std.testing.expect(value.sstr.check(ss1)); try std.testing.expect(value.sstr.check(ss2)); try std.testing.expect(value.sstr.check(ss3)); - const s1, const l1 = unpack(ss1); - const s2, const l2 = unpack(ss2); - const s3, const l3 = unpack(ss3); - - try std.testing.expectEqual(1, l1); - try std.testing.expectEqualStrings("1", s1[0..l1]); - - try std.testing.expectEqual(3, l2); - try std.testing.expectEqualStrings("123", s2[0..l2]); - - try std.testing.expectEqual(6, l3); - try std.testing.expectEqualStrings("123456", s3[0..l3]); + try std.testing.expectEqualStrings("1", s1.slice()); + try std.testing.expectEqualStrings("123", s2.slice()); + try std.testing.expectEqualStrings("123456", s3.slice()); } fn benchmarkSstr(impl: SstrImpl, id: usize, iters: usize) !void { @@ -196,116 +191,116 @@ fn benchmarkSstr(impl: SstrImpl, id: usize, iters: usize) !void { std.debug.print("unpack{}: {d:.3}s\n", .{ id, secs }); } -// test "char" { -// const c1 = value.char.pack('\x00'); -// try std.testing.expect(value.char.check(c1)); -// try std.testing.expectEqual('\x00', value.char.unpack(c1)); +test "char" { + const c1 = value.char.pack('\x00'); + try std.testing.expect(value.char.check(c1)); + try std.testing.expectEqual('\x00', value.char.unpack(c1)); + + const c2 = value.char.pack('😀'); + try std.testing.expect(value.char.check(c2)); + try std.testing.expectEqual('😀', value.char.unpack(c2)); +} + +test "misc" { + const f = value.boole.pack(false); + try std.testing.expect(value.boole.check(f)); + try std.testing.expectEqual(false, value.boole.unpack(f)); + try std.testing.expect(value.boole.unpack(value.boole.pred(f))); + + const t = value.boole.pack(true); + try std.testing.expect(value.boole.check(t)); + try std.testing.expectEqual(true, value.boole.unpack(t)); + try std.testing.expect(value.boole.unpack(value.boole.pred(t))); + + const nil = value.nil.get(); + try std.testing.expect(value.nil.check(nil)); + try std.testing.expect(value.boole.unpack(value.nil.pred(nil))); + + const eof = value.eof.get(); + try std.testing.expect(value.eof.check(eof)); + try std.testing.expect(value.boole.unpack(value.eof.pred(eof))); +} -// const c2 = value.char.pack('😀'); -// try std.testing.expect(value.char.check(c2)); -// try std.testing.expectEqual('😀', value.char.unpack(c2)); -// } +test "pair" { + const v1 = value.fixnum.pack(1); + const v2 = value.fixnum.pack(2); -// test "misc" { -// const f = value.boole.pack(false); -// try std.testing.expect(value.boole.check(f)); -// try std.testing.expectEqual(false, value.boole.unpack(f)); -// try std.testing.expect(value.boole.unpack(value.boole.pred(f))); - -// const t = value.boole.pack(true); -// try std.testing.expect(value.boole.check(t)); -// try std.testing.expectEqual(true, value.boole.unpack(t)); -// try std.testing.expect(value.boole.unpack(value.boole.pred(t))); - -// const nil = value.nil.get(); -// try std.testing.expect(value.nil.check(nil)); -// try std.testing.expect(value.boole.unpack(value.nil.pred(nil))); - -// const eof = value.eof.get(); -// try std.testing.expect(value.eof.check(eof)); -// try std.testing.expect(value.boole.unpack(value.eof.pred(eof))); -// } - -// test "pair" { -// const v1 = value.fixnum.pack(1); -// const v2 = value.fixnum.pack(2); - -// const v3 = value.fixnum.pack(3); -// const v4 = value.fixnum.pack(4); - -// const p = value.pair.cons(v1, v2); -// try std.testing.expect(value.pair.check(p)); -// try std.testing.expect(value.boole.unpack(value.pair.pred(p))); - -// const car = value.pair.car(p); -// const cdr = value.pair.cdr(p); -// try std.testing.expectEqual(1, value.fixnum.unpack(car)); -// try std.testing.expectEqual(2, value.fixnum.unpack(cdr)); - -// value.pair.setcar(p, v3); -// value.pair.setcdr(p, v4); - -// const car2 = value.pair.car(p); -// const cdr2 = value.pair.cdr(p); -// try std.testing.expectEqual(3, value.fixnum.unpack(car2)); -// try std.testing.expectEqual(4, value.fixnum.unpack(cdr2)); -// } - -// test "parse" { -// const val = io.parser.parseCode("\"foo\""); - -// try std.testing.expect(value.sstr.check(val)); - -// const s = value.sstr.unpack(val); -// try std.testing.expectEqualStrings("foo", s.slice()); -// } - -// test "parse2" { -// const val = io.parser.parseCode( -// \\ ;; Testing some crazy datum comments -// \\ ##;"bar"#;([x #"y"]{##`,'z})"foo" -// \\ ;; end -// ); - -// const r = value.rune.unpack(value.pair.car(val)); -// try std.testing.expectEqualStrings("HASH", r.slice()); - -// const s = value.pair.cdr(val); -// try std.testing.expect(value.sstr.check(s)); - -// const f = value.sstr.unpack(s); -// try std.testing.expectEqualStrings("foo", f.slice()); -// } - -// test "parse3" { -// const val = io.parser.parseCode( -// \\(foo #;x #;(x y) #;x #bar [#x #"baz"] 'bat) -// ); - -// const car = value.pair.car; -// const cdr = value.pair.cdr; - -// // const e1 = car(val); -// const e2 = car(cdr(val)); -// // const e3 = car(cdr(cdr(val))); -// // const e4 = car(cdr(cdr(cdr(val)))); - -// try std.testing.expect(value.rune.check(e2)); -// } - -// test "parse4" { -// const val = io.parser.parseCode("(foo . #;x bar #;y)"); - -// const s = value.sstr.unpack(value.pair.car(val)); -// try std.testing.expectEqualStrings("foo", s.slice()); - -// const f = value.sstr.unpack(value.pair.cdr(val)); -// try std.testing.expectEqualStrings("bar", f.slice()); -// } - -// test "unparse" { -// try std.testing.expectEqualStrings( -// "#foo", -// io.unparser.unparse(io.parser.parseCode("#foo")), -// ); -// } + const v3 = value.fixnum.pack(3); + const v4 = value.fixnum.pack(4); + + const p = value.pair.cons(v1, v2); + try std.testing.expect(value.pair.check(p)); + try std.testing.expect(value.boole.unpack(value.pair.pred(p))); + + const car = value.pair.car(p); + const cdr = value.pair.cdr(p); + try std.testing.expectEqual(1, value.fixnum.unpack(car)); + try std.testing.expectEqual(2, value.fixnum.unpack(cdr)); + + value.pair.setcar(p, v3); + value.pair.setcdr(p, v4); + + const car2 = value.pair.car(p); + const cdr2 = value.pair.cdr(p); + try std.testing.expectEqual(3, value.fixnum.unpack(car2)); + try std.testing.expectEqual(4, value.fixnum.unpack(cdr2)); +} + +test "parse" { + const val = io.parser.parseCode("\"foo\""); + + try std.testing.expect(value.sstr.check(val)); + + const s = value.sstr.unpack(val); + try std.testing.expectEqualStrings("foo", s.slice()); +} + +test "parse2" { + const val = io.parser.parseCode( + \\ ;; Testing some crazy datum comments + \\ ##;"bar"#;([x #"y"]{##`,'z})"foo" + \\ ;; end + ); + + const r = value.rune.unpack(value.pair.car(val)); + try std.testing.expectEqualStrings("HASH", r.slice()); + + const s = value.pair.cdr(val); + try std.testing.expect(value.sstr.check(s)); + + const f = value.sstr.unpack(s); + try std.testing.expectEqualStrings("foo", f.slice()); +} + +test "parse3" { + const val = io.parser.parseCode( + \\(foo #;x #;(x y) #;x #bar [#x #"baz"] 'bat) + ); + + const car = value.pair.car; + const cdr = value.pair.cdr; + + // const e1 = car(val); + const e2 = car(cdr(val)); + // const e3 = car(cdr(cdr(val))); + // const e4 = car(cdr(cdr(cdr(val)))); + + try std.testing.expect(value.rune.check(e2)); +} + +test "parse4" { + const val = io.parser.parseCode("(foo . #;x bar #;y)"); + + const s = value.sstr.unpack(value.pair.car(val)); + try std.testing.expectEqualStrings("foo", s.slice()); + + const f = value.sstr.unpack(value.pair.cdr(val)); + try std.testing.expectEqualStrings("bar", f.slice()); +} + +test "unparse" { + try std.testing.expectEqualStrings( + "#foo", + io.unparser.unparse(io.parser.parseCode("#foo")), + ); +} diff --git a/src/libzisp/value/sstr.zig b/src/libzisp/value/sstr.zig index a2f6bf8..1c9812e 100644 --- a/src/libzisp/value/sstr.zig +++ b/src/libzisp/value/sstr.zig @@ -62,22 +62,13 @@ fn _pack(s: []const u8, tag: OtherTag) Value { return v; } -pub fn unpack(v: Value) struct { [6]u8, u3 } { +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 .{ s, i }; + if (s[i] == 0) return .{ .buffer = s, .len = i }; } - return .{ s, 6 }; -} - -pub fn unpack1(v: Value) struct { [6]u8, u3 } { - assert(v); - const s: [6]u8 = @bitCast(v.sstr.string); - for (0..6) |i| { - if (s[i] == 0) return .{ s, @intCast(i) }; - } - return .{ s, 6 }; + return .{ .buffer = s, .len = 6 }; } // No Zisp API for sstr specifically, since it's a string. See string.zig. |
