diff options
| -rw-r--r-- | src/main.zig | 14 | ||||
| -rw-r--r-- | src/test/parse.zig | 30 | ||||
| -rw-r--r-- | src/zisp/io/Parser.zig | 83 | ||||
| -rw-r--r-- | src/zisp/io/parse.zig | 52 | ||||
| -rw-r--r-- | src/zisp/io/read.zig | 8 |
5 files changed, 107 insertions, 80 deletions
diff --git a/src/main.zig b/src/main.zig index 55fecdf..a01daa9 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2,20 +2,20 @@ const std = @import("std"); const zisp = @import("zisp"); -const alloc = std.heap.smp_allocator; -const gstio = std.Io.Threaded.global_single_threaded.io(); - pub fn main() !u8 { + const alloc = std.heap.smp_allocator; + const io = std.Io.Threaded.global_single_threaded.io(); + var stdin_buffer: [4096]u8 = undefined; - var stdin_reader = std.Io.File.stdin().reader(gstio, &stdin_buffer); + var stdin_reader = std.Io.File.stdin().reader(io, &stdin_buffer); const reader = &stdin_reader.interface; var stdout_buffer: [4096]u8 = undefined; - var stdout_writer = std.Io.File.stdout().writer(gstio, &stdout_buffer); + var stdout_writer = std.Io.File.stdout().writer(io, &stdout_buffer); const writer = &stdout_writer.interface; - var sfa = zisp.io.Parser.DefaultSfa.withFallback(alloc); - var p = try zisp.io.Parser.initWithSfa(&sfa, gstio); + var p, const sfa = try zisp.io.Parser.init(alloc, io); + defer p.deinit(sfa); while (true) { const datum = p.run(reader) catch { const format = "Parse error: {s}, pos: {d}, unread_char: {s}\n"; diff --git a/src/test/parse.zig b/src/test/parse.zig index 272c92a..61f8fc3 100644 --- a/src/test/parse.zig +++ b/src/test/parse.zig @@ -3,16 +3,17 @@ const std = @import("std"); const testing = std.testing; const expect = testing.expect; -const gst_io = std.Io.Threaded.global_single_threaded.io(); +const alloc = std.heap.smp_allocator; +const io = std.Io.Threaded.global_single_threaded.io(); -pub const io = @import("../zisp/io.zig"); -pub const value = @import("../zisp/value.zig"); +pub const zisp = @import("../zisp.zig"); -pub const Value = value.Value; +pub const value = zisp.value; +pub const Value = zisp.Value; fn parse(str: []const u8) Value { var fbs = std.Io.Reader.fixed(str); - return io.parse.fromReader(&fbs); + return zisp.io.parse.fromReaderNoError(alloc, io, &fbs); } test "parse empty" { @@ -119,7 +120,7 @@ test "print" { var buf: [32]u8 = undefined; var w = std.Io.Writer.fixed(&buf); const v = parse("#foo"); - try io.print.toWriter(&w, v); + try zisp.io.print.toWriter(&w, v); try testing.expectEqualStrings("#foo", buf[0..w.end]); } @@ -127,7 +128,7 @@ test "print2" { var buf: [128]u8 = undefined; var w = std.Io.Writer.fixed(&buf); const v = parse("#{foo bar['x]}"); - try io.print.toWriter(&w, v); + try zisp.io.print.toWriter(&w, v); try testing.expectEqualStrings( "(#HASH #BRACE foo (#JOIN bar #SQUARE (#QUOTE & x)))", buf[0..w.end], @@ -136,11 +137,11 @@ test "print2" { fn parseAndPrint(str: []const u8) !void { var buf: [64]u8 = undefined; - var fw = std.Io.File.stderr().writer(gst_io, &buf); + var fw = std.Io.File.stderr().writer(io, &buf); const w = &fw.interface; const v = parse(str); - try io.print.toWriter(w, v); + try zisp.io.print.toWriter(w, v); try w.writeByte('\n'); try w.flush(); } @@ -166,18 +167,17 @@ test "print7" { } fn parseBench(path: []const u8, iters: usize) !void { - const file = try std.Io.Dir.cwd().openFile(gst_io, path, .{}); - defer file.close(gst_io); + const file = try std.Io.Dir.cwd().openFile(io, path, .{}); + defer file.close(io); - var sfa = io.Parser.DefaultSfa.withFallback(std.heap.smp_allocator); - var parser = try io.Parser.initWithSfa(&sfa, gst_io); - defer parser.deinit(); + var parser, const sfa = try zisp.io.Parser.init(alloc, io); + defer parser.deinit(sfa); var timer = try std.time.Timer.start(); for (0..iters) |i| { _ = i; var buf: [4096]u8 = undefined; - var reader = file.reader(gst_io, &buf); + var reader = file.reader(io, &buf); var v: Value = undefined; while (true) { v = parser.run(&reader.interface) catch |e| { diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig index d18150e..9833baa 100644 --- a/src/zisp/io/Parser.zig +++ b/src/zisp/io/Parser.zig @@ -120,33 +120,23 @@ pub const Alloc = struct { chars: std.mem.Allocator, }; -pub fn Sfa(init_stack: usize, init_chars: usize) type { +pub fn StackFallbackAlloc(ctx_stack_cap: usize, str_chars_cap: usize) type { return struct { - const Self = @This(); + pub const ctx_stack_bytes = ctx_stack_cap * @sizeOf(Context); + pub const str_chars_bytes = str_chars_cap; - pub const init_stack_capacity: usize = init_stack; - pub const init_chars_capacity: usize = init_chars; + stack: std.heap.StackFallbackAllocator(ctx_stack_bytes), + chars: std.heap.StackFallbackAllocator(str_chars_bytes), - pub const init_stack_mem: usize = init_stack * @sizeOf(Context); - pub const init_chars_mem: usize = init_chars; - - stack: std.heap.StackFallbackAllocator(init_stack_mem), - chars: std.heap.StackFallbackAllocator(init_chars_mem), - - pub fn withFallback(fallback: std.mem.Allocator) Self { - return .{ - .stack = std.heap.stackFallback(init_stack_mem, fallback), - .chars = std.heap.stackFallback(init_chars_mem, fallback), - }; - } - - pub fn allocator(s: *Self) Alloc { - return .{ .stack = s.stack.get(), .chars = s.chars.get() }; + pub fn alloc(self: *@This()) Alloc { + return .{ .stack = self.stack.get(), .chars = self.chars.get() }; } }; } -pub const DefaultSfa = Sfa(32, 2048); +const def_ctx_stack_cap = 32; +const def_str_chars_cap = 2048; +const DefaultSfa = StackFallbackAlloc(def_ctx_stack_cap, def_str_chars_cap); alloc: Alloc, io: std.Io, @@ -159,29 +149,54 @@ result: Value = undefined, unread_char: ?u8 = null, err_msg: []const u8 = undefined, -pub fn init( +pub fn init(alloc: std.mem.Allocator, io: std.Io) !struct { + Parser, + DefaultSfa, +} { + return initWithSfa(def_ctx_stack_cap, def_str_chars_cap, alloc, io); +} + +pub fn initWithSfa( + comptime init_ctx_stack_cap: usize, + comptime init_str_chars_cap: usize, + alloc: std.mem.Allocator, + io: std.Io, +) !struct { + Parser, + StackFallbackAlloc(init_ctx_stack_cap, init_str_chars_cap), +} { + const Sfa = StackFallbackAlloc(init_ctx_stack_cap, init_str_chars_cap); + var sfa: Sfa = .{ + .stack = std.heap.stackFallback(Sfa.ctx_stack_bytes, alloc), + .chars = std.heap.stackFallback(Sfa.str_chars_bytes, alloc), + }; + const parser: Parser = try initCustom( + sfa.alloc(), + io, + init_ctx_stack_cap, + init_str_chars_cap, + ); + return .{ parser, sfa }; +} + +pub fn initCustom( alloc: Alloc, io: std.Io, - init_stack_capacity: usize, - init_chars_capacity: usize, + init_ctx_stack_cap: usize, + init_str_chars_cap: usize, ) !Parser { var p: Parser = .{ .alloc = alloc, .io = io }; - p.stack = try .initCapacity(alloc.stack, init_stack_capacity); - p.chars = try .initCapacity(alloc.chars, init_chars_capacity); + p.stack = try .initCapacity(alloc.stack, init_ctx_stack_cap); + p.chars = try .initCapacity(alloc.chars, init_str_chars_cap); return p; } -pub fn initWithSfa(sfa: anytype, io: std.Io) !Parser { - const SfaType = @typeInfo(@TypeOf(sfa)).pointer.child; - return init( - sfa.allocator(), - io, - SfaType.init_stack_capacity, - SfaType.init_chars_capacity, - ); +pub fn deinit(p: *Parser, sfa: anytype) void { + p.deinitCustom(); + _ = sfa; } -pub fn deinit(p: *Parser) void { +pub fn deinitCustom(p: *Parser) void { p.stack.deinit(p.alloc.stack); p.chars.deinit(p.alloc.chars); } diff --git a/src/zisp/io/parse.zig b/src/zisp/io/parse.zig index 4d00ca9..6e84b55 100644 --- a/src/zisp/io/parse.zig +++ b/src/zisp/io/parse.zig @@ -10,30 +10,38 @@ const Value = value.Value; const is_test = builtin.is_test; const is_debug = builtin.mode == .Debug; -pub fn fromReader(input: *std.Io.Reader) Value { - return _fromReader(input, true); +const ParserErrors = error{ + ParseError, + OutOfMemory, +}; + +pub fn fromReader( + alloc: std.mem.Allocator, + io: std.Io, + input: *std.Io.Reader, +) ParserErrors!Value { + var p, const sfa = try Parser.init(alloc, io); + defer p.deinit(sfa); + return p.run(input); } -pub fn _fromReader( +pub fn fromReaderNoError( + alloc: std.mem.Allocator, + io: std.Io, input: *std.Io.Reader, - comptime panic: bool, -) if (panic) Value else error{ ParseError, OutOfMemory }!Value { - const alloc = std.heap.smp_allocator; - const io = std.Io.Threaded.global_single_threaded.io(); - var sfa = Parser.DefaultSfa.withFallback(alloc); - var p = Parser.initWithSfa(&sfa, io) catch |e| { - if (panic) @panic("OOM") else return e; - }; - defer p.deinit(); - return p.run(input) catch |e| if (panic) { - const format = "Parse error: {s}, unread_char: {s}\n"; - const unread: [4]u8 = - if (p.unread_char) |c| - "0x".* ++ std.fmt.hex(c) - else - "none".*; - std.debug.panic(format, .{ p.err_msg, unread }); - } else { - return e; +) Value { + var p, const sfa = Parser.init(alloc, io) catch @panic("OOM"); + defer p.deinit(sfa); + return p.run(input) catch |e| switch (e) { + error.OutOfMemory => @panic("OOM"), + error.ParseError => { + const format = "Parse error: {s}, unread_char: {s}\n"; + const unread: [4]u8 = + if (p.unread_char) |c| + "0x".* ++ std.fmt.hex(c) + else + "none".*; + std.debug.panic(format, .{ p.err_msg, unread }); + }, }; } diff --git a/src/zisp/io/read.zig b/src/zisp/io/read.zig index 5fa647e..23f0ea8 100644 --- a/src/zisp/io/read.zig +++ b/src/zisp/io/read.zig @@ -5,6 +5,10 @@ const decode = @import("decode.zig"); const Value = @import("../value.zig").Value; -pub fn fromReader(reader: *std.Io.Reader) Value { - return decode.decode(parse.fromReader(reader)); +pub fn fromReader( + alloc: std.mem.Allocator, + io: std.Io, + reader: *std.Io.Reader, +) Value { + return decode.decode(parse.fromReader(alloc, io, reader)); } |
