summaryrefslogtreecommitdiff
path: root/src/test/parse.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/parse.zig')
-rw-r--r--src/test/parse.zig162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/test/parse.zig b/src/test/parse.zig
new file mode 100644
index 0000000..0e83258
--- /dev/null
+++ b/src/test/parse.zig
@@ -0,0 +1,162 @@
+const std = @import("std");
+
+const testing = std.testing;
+
+pub const io = @import("../zisp/io.zig");
+pub const value = @import("../zisp/value.zig");
+
+pub const Value = value.Value;
+
+fn parseString(str: []const u8) Value {
+ var fbs = std.io.fixedBufferStream(str);
+ return io.parser.parse(fbs.reader().any());
+}
+
+test "parse" {
+ const val = parseString("\"foo\"");
+
+ try testing.expect(value.sstr.check(val));
+
+ const s = value.sstr.unpack(val);
+ try testing.expectEqualStrings("foo", s.slice());
+}
+
+test "parse2" {
+ const val = parseString(
+ \\ ;; Testing some crazy datum comments
+ \\ ;~"bar"([x #"y"]{##`,'z}) #"foo"
+ \\ ;; end
+ );
+
+ const r = value.rune.unpack(value.pair.car(val));
+ try testing.expectEqualStrings("HASH", r.slice());
+
+ const s = value.pair.cdr(val);
+ try testing.expect(value.sstr.check(s));
+
+ const f = value.sstr.unpack(s);
+ try testing.expectEqualStrings("foo", f.slice());
+}
+
+test "parse3" {
+ const val = parseString(
+ \\(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 testing.expect(value.sstr.check(e1));
+ try testing.expect(value.rune.check(e2));
+ try testing.expect(value.pair.check(e3));
+ try testing.expect(value.pair.check(e4));
+}
+
+test "parse4" {
+ const val = parseString("(foo . ;~x bar ;~y)");
+
+ const s = value.sstr.unpack(value.pair.car(val));
+ try testing.expectEqualStrings("foo", s.slice());
+
+ const f = value.sstr.unpack(value.pair.cdr(val));
+ try testing.expectEqualStrings("bar", f.slice());
+}
+
+test "unparse" {
+ var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
+ var out: std.ArrayList(u8) = .init(gpa.allocator());
+
+ const w = out.writer();
+ const v = parseString("#foo");
+ try io.unparser.unparse(w, v);
+ try testing.expectEqualStrings("#foo", try out.toOwnedSlice());
+}
+
+test "unparse2" {
+ var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
+ var out: std.ArrayList(u8) = .init(gpa.allocator());
+
+ const w = out.writer();
+ const v = parseString("#{foo bar['x]}");
+ try io.unparser.unparse(w, v);
+ try testing.expectEqualStrings(
+ "(#HASH #BRACE foo (#JOIN bar #SQUARE (#QUOTE . x)))",
+ try out.toOwnedSlice(),
+ );
+}
+
+fn writeParseResult(str: []const u8) !void {
+ const w = std.io.getStdErr().writer();
+ const v = parseString(str);
+ try io.unparser.unparse(w, v);
+ try w.writeByte('\n');
+}
+
+test "unparse3" {
+ try writeParseResult("#{foo bar['x](y)(z)}");
+}
+
+test "unparse4" {
+ try writeParseResult("(foo ;~bar)");
+}
+
+test "unparse5" {
+ try writeParseResult("(;~foo foo ;~bar . ;~bar bar ;~bar)");
+}
+
+test "unparse6" {
+ try writeParseResult("(foo bar ... baz bat.(qux))");
+}
+
+test "unparse7" {
+ try writeParseResult("#`(#,(->keyword (syntax->datum #'sym)) . in)");
+}
+
+fn parseBench(path: []const u8, iters: usize) !void {
+ const file = try std.fs.cwd().openFile(path, .{});
+ defer file.close();
+
+ var sfa = io.parser.DefaultSfa.init(std.heap.smp_allocator);
+ var parser = try io.parser.initSfa(&sfa);
+ defer parser.deinit();
+
+ var timer = try std.time.Timer.start();
+ for (0..iters) |i| {
+ _ = i;
+ var br = std.io.bufferedReader(file.reader());
+ const reader = br.reader().any();
+ // const reader = file.reader().any();
+ var v: Value = undefined;
+ while (true) {
+ // std.debug.print("hihi {s}\n", .{path});
+ v = parser.run(reader) catch |e| {
+ std.debug.print("\nfile pos: {}\n", .{
+ try file.getPos(),
+ });
+ return e;
+ };
+ // try io.unparser.unparse(std.io.getStdOut().writer().any(), v);
+ if (value.eof.eq(v)) {
+ break;
+ }
+ }
+ try file.seekTo(0);
+ }
+ const ns: f64 = @floatFromInt(timer.lap());
+ const secs = ns / 1_000_000_000;
+ std.debug.print(
+ "parse {s} x {}: {d:.3}s\n",
+ .{ path, iters, secs },
+ );
+}
+
+test "parse bench" {
+ try parseBench("src/test/data/parser-test-1.scm", 200);
+ try parseBench("src/test/data/parser-test-2.scm", 800);
+ try parseBench("src/test/data/parser-torture.scm", 1);
+}