summaryrefslogtreecommitdiff
path: root/src/test/values.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/values.zig')
-rw-r--r--src/test/values.zig247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/test/values.zig b/src/test/values.zig
new file mode 100644
index 0000000..7339f22
--- /dev/null
+++ b/src/test/values.zig
@@ -0,0 +1,247 @@
+const builtin = @import("builtin");
+const std = @import("std");
+
+const testing = std.testing;
+
+pub const gc = @import("../zisp/gc.zig");
+pub const io = @import("../zisp/io.zig");
+pub const lib = @import("../zisp/lib.zig");
+pub const value = @import("../zisp/value.zig");
+
+pub const Hval = gc.Hval;
+
+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 testing.expect(value.double.check(v1));
+ try testing.expect(value.double.check(v2));
+ try testing.expect(value.double.check(v3));
+
+ try 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 testing.expect(value.fixnum.check(v1));
+ try testing.expect(value.fixnum.check(v2));
+ try testing.expect(value.fixnum.check(v3));
+
+ try testing.expectEqual(int1 + int2, result);
+}
+
+test "ptr" {
+ const ptr = value.ptr;
+
+ const val: *Hval = @ptrFromInt(256);
+ const tag = ptr.Tag.pair;
+
+ const p = ptr.pack(val, tag);
+ try testing.expect(ptr.check(p));
+ try testing.expect(ptr.checkZispTag(p, tag));
+ try testing.expect(ptr.checkStrong(p));
+
+ const pv, const pt = ptr.unpack(p);
+ try testing.expectEqual(val, pv);
+ try testing.expectEqual(tag, pt);
+
+ var w = ptr.makeWeak(p);
+ try testing.expect(ptr.check(w));
+ try testing.expect(ptr.checkZispTag(w, tag));
+ try testing.expect(ptr.checkWeak(w));
+ try testing.expectEqual(true, value.boole.unpack(ptr.predWeak(w)));
+ try testing.expectEqual(false, value.boole.unpack(ptr.predWeakNull(w)));
+
+ const wv, const wt = ptr.unpack(w);
+ try testing.expectEqual(val, wv);
+ try testing.expectEqual(tag, wt);
+
+ const wv2, const wt2 = ptr.unpack(ptr.getWeak(w));
+ try testing.expectEqual(val, wv2);
+ try testing.expectEqual(tag, wt2);
+
+ ptr.setWeakNull(&w);
+ try testing.expect(ptr.check(w));
+ try testing.expect(ptr.checkWeak(w));
+ try testing.expect(ptr.isWeakNull(w));
+ try testing.expectEqual(true, value.boole.unpack(ptr.predWeak(w)));
+ try testing.expectEqual(true, value.boole.unpack(ptr.predWeakNull(w)));
+ try 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 testing.expect(ptr.checkForeign(f1));
+ try testing.expectEqual(int1, ptr.unpackForeign(f1));
+
+ const f2 = ptr.packForeign(int2);
+ try testing.expect(ptr.checkForeign(f2));
+ try testing.expectEqual(int2, ptr.unpackForeign(f2));
+}
+
+test "rune" {
+ const r = value.rune.pack("test");
+ try testing.expect(value.rune.check(r));
+
+ const s = value.rune.unpack(r);
+ try testing.expectEqualStrings("test", s.slice());
+}
+
+const SstrImpl = struct { SstrPack, SstrUnpack };
+const SstrPack = *const fn ([]const u8) Value;
+const SstrUnpack = *const fn (Value) ShortString;
+
+test "sstr" {
+ const impls = [_]SstrImpl{
+ .{ value.sstr.pack, value.sstr.unpack },
+ // .{ value.sstr.pack1, value.sstr.unpack1 },
+ // .{ value.sstr.pack2, value.sstr.unpack2 },
+ // .{ value.sstr.pack3, value.sstr.unpack3 },
+ // .{ value.sstr.pack4, value.sstr.unpack4 },
+ };
+
+ for (impls) |impl| {
+ try testSstr(impl);
+ }
+
+ if (impls.len > 1) {
+ const iters = switch (@import("builtin").mode) {
+ .Debug, .ReleaseSmall => 10_000_000,
+ .ReleaseSafe => 100_000_000,
+ .ReleaseFast => 1_000_000_000,
+ };
+ std.debug.print("Benchmarking sstr with {} iters.\n", .{iters});
+ inline for (impls, 0..) |impl, i| {
+ try benchmarkSstr(impl, i, iters);
+ }
+ }
+}
+
+fn testSstr(impl: SstrImpl) !void {
+ const pack, const unpack = impl;
+
+ const ss1 = pack("1");
+ const ss2 = pack("123");
+ const ss3 = pack("123456");
+
+ const s1 = unpack(ss1);
+ const s2 = unpack(ss2);
+ const s3 = unpack(ss3);
+
+ try testing.expect(value.sstr.check(ss1));
+ try testing.expect(value.sstr.check(ss2));
+ try testing.expect(value.sstr.check(ss3));
+
+ try testing.expectEqualStrings("1", s1.slice());
+ try testing.expectEqualStrings("123", s2.slice());
+ try testing.expectEqualStrings("123456", s3.slice());
+}
+
+fn benchmarkSstr(impl: SstrImpl, id: usize, iters: usize) !void {
+ const pack, const unpack = impl;
+
+ var timer = try std.time.Timer.start();
+ var ns: f64 = undefined;
+ var secs: f64 = undefined;
+
+ var ss1: Value = undefined;
+ var ss2: Value = undefined;
+ var ss3: Value = undefined;
+
+ for (0..iters) |_i| {
+ _ = _i;
+ ss1 = pack("1");
+ ss2 = pack("123");
+ ss3 = pack("123456");
+ }
+
+ ns = @floatFromInt(timer.lap());
+ secs = ns / 1_000_000_000;
+
+ std.debug.print("pack{}: {d:.3}s\t", .{ id, secs });
+
+ for (0..iters) |_i| {
+ _ = _i;
+ std.mem.doNotOptimizeAway(unpack(ss1));
+ std.mem.doNotOptimizeAway(unpack(ss2));
+ std.mem.doNotOptimizeAway(unpack(ss3));
+ }
+
+ ns = @floatFromInt(timer.lap());
+ secs = ns / 1_000_000_000;
+
+ std.debug.print("unpack{}: {d:.3}s\n", .{ id, secs });
+}
+
+test "char" {
+ const c1 = value.char.pack('\x00');
+ try testing.expect(value.char.check(c1));
+ try testing.expectEqual('\x00', value.char.unpack(c1));
+
+ const c2 = value.char.pack('😀');
+ try testing.expect(value.char.check(c2));
+ try testing.expectEqual('😀', value.char.unpack(c2));
+}
+
+test "misc" {
+ const f = value.boole.pack(false);
+ try testing.expect(value.f.eq(f));
+ try testing.expect(value.boole.check(f));
+ try testing.expectEqual(false, value.boole.unpack(f));
+ try testing.expect(value.boole.unpack(value.boole.pred(f)));
+
+ const t = value.boole.pack(true);
+ try testing.expect(value.t.eq(t));
+ try testing.expect(value.boole.check(t));
+ try testing.expectEqual(true, value.boole.unpack(t));
+ try testing.expect(value.boole.unpack(value.boole.pred(t)));
+
+ const nil = value.nil;
+ try testing.expect(value.boole.unpack(value.misc.isNil(nil)));
+
+ const eof = value.eof;
+ try testing.expect(value.boole.unpack(value.misc.isEof(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 testing.expect(value.pair.check(p));
+ try testing.expect(value.boole.unpack(value.pair.pred(p)));
+
+ const car = value.pair.car(p);
+ const cdr = value.pair.cdr(p);
+ try testing.expectEqual(1, value.fixnum.unpack(car));
+ try 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 testing.expectEqual(3, value.fixnum.unpack(car2));
+ try testing.expectEqual(4, value.fixnum.unpack(cdr2));
+}