summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libzisp.zig431
-rw-r--r--src/libzisp/value/sstr.zig15
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.