diff options
| author | Taylan Kammer <taylan.kammer@gmail.com> | 2025-03-19 16:20:12 +0100 |
|---|---|---|
| committer | Taylan Kammer <taylan.kammer@gmail.com> | 2025-03-19 16:20:12 +0100 |
| commit | dd6f15ce5cb359116d0278771ce14ddc9e3de06f (patch) | |
| tree | c7367e3c999b10671ebbdeaf2a44b3f2e4a8140a | |
| parent | 8a658ca3f9de8a4b3ebf518a034d72e3c0a608ca (diff) | |
* src/libzisp/io/parser.zig: Cleanup & optimize.
| -rw-r--r-- | src/libzisp/io/parser.zig | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/src/libzisp/io/parser.zig b/src/libzisp/io/parser.zig index b79b679..e501462 100644 --- a/src/libzisp/io/parser.zig +++ b/src/libzisp/io/parser.zig @@ -229,6 +229,7 @@ // (foo bar baz)| <- parser reached EOF (assuming no trailing spaces) // +const builtin = @import("builtin"); const std = @import("std"); const lib = @import("../lib.zig"); @@ -268,10 +269,13 @@ const Context = struct { const BUF_SIZE = 16; const POS_TYPE = u4; -const debug_mode = @import("builtin").mode == .Debug; +const is_test = builtin.is_test; +const is_debug = builtin.mode == .Debug; const State = struct { input: std.io.AnyReader, + alloc: std.mem.Allocator, + counter: usize = 0, buf: [BUF_SIZE]u8 = undefined, @@ -279,22 +283,22 @@ const State = struct { write_pos: POS_TYPE = 0, context: Context = .{}, - stack: std.ArrayList(Context), + stack: std.ArrayListUnmanaged(Context) = .{}, retval: Value = undefined, // For debugging. checked_eof: bool = false, fn init(input: std.io.AnyReader, alloc: std.mem.Allocator) State { - return .{ .input = input, .stack = .init(alloc) }; + return .{ .input = input, .alloc = alloc }; } fn deinit(s: *State) void { - s.stack.deinit(); + s.stack.deinit(s.alloc); } fn recurParse(s: *State, start: Fn, end: Fn) void { - s.stack.append(.{ + s.stack.append(s.alloc, .{ .next = end, .val = s.context.val, .char = s.context.char, @@ -320,7 +324,7 @@ const State = struct { } fn eof(s: *State) bool { - if (debug_mode) { + if (is_debug) { s.checked_eof = true; } readNext(s) catch |e| switch (e) { @@ -331,7 +335,7 @@ const State = struct { } fn peek(s: *State) u8 { - if (debug_mode) { + if (is_debug) { if (!s.checked_eof) { @panic("Didn't check EOF before calling peek()!"); } @@ -340,7 +344,7 @@ const State = struct { } fn skip(s: *State) void { - if (debug_mode) { + if (is_debug) { s.checked_eof = false; } // std.debug.print("{c}\n", .{s.buf[s.pos]}); @@ -415,10 +419,28 @@ const Fn = enum { }; pub fn parse(input: std.io.AnyReader) Value { - var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; - defer if (gpa.deinit() == .leak) @panic("leak"); - var s: State = .init(input, gpa.allocator()); + var debug_alloc: std.heap.DebugAllocator(.{}) = undefined; + if (!is_test and is_debug) { + debug_alloc = .init; + } + defer if (!is_test and is_debug) { + if (debug_alloc.deinit() == .leak) { + @panic("leak"); + } + }; + + const alloc = if (is_test) + std.testing.allocator + else if (is_debug) + debug_alloc.allocator() + else + std.heap.smp_allocator; + + var sfa = std.heap.stackFallback(4096, alloc); + + var s: State = .init(input, sfa.get()); defer s.deinit(); + while (s.context.next != .done) call(&s); return s.retval; } @@ -642,7 +664,7 @@ fn readQuotedSstr(s: *State) !?Value { // TODO: Handle escapes. var buf: [6]u8 = undefined; var i: u8 = 0; - while (!s.eof()) { + while (!s.eof()) : (i += 1) { const c = s.getc(); if (c == '"') { // ok, return what we accumulated @@ -655,7 +677,6 @@ fn readQuotedSstr(s: *State) !?Value { } // ok, save this byte and go on buf[i] = c; - i += 1; } return error.Unclosed; } @@ -823,6 +844,6 @@ fn endImproperList(s: *State) void { fn err(s: *State, msg: []const u8) noreturn { std.debug.print("{s}\n", .{msg}); - std.debug.print("pos: {}\n", .{s.counter}); + std.debug.print("position: {}\n", .{s.counter}); @panic("parse error"); } |
