diff options
Diffstat (limited to 'src/test/parse.zig')
| -rw-r--r-- | src/test/parse.zig | 162 |
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); +} |
