From c577aa7a2e2e1db245d20ca6ae23e4d630c51897 Mon Sep 17 00:00:00 2001 From: Taylan Kammer Date: Tue, 23 Jun 2026 18:15:04 +0200 Subject: Don't alloc or decode for datum comments. --- src/zisp/io/Parser.zig | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig index 6e9f87e..1b3808a 100644 --- a/src/zisp/io/Parser.zig +++ b/src/zisp/io/Parser.zig @@ -104,6 +104,7 @@ decoder: ?*Decoder, reader: *Reader = undefined, context: Context = .{}, +comment: bool = false, result: Value = undefined, unread_char: ?u8 = null, err_msg: []const u8 = undefined, @@ -194,10 +195,12 @@ fn getUnread(p: *Parser) ?u8 { // fn addChar(p: *Parser, c: u8) !void { + if (p.comment) return; try p.str_chars.append(p.alloc, c); } fn addUnicode(p: *Parser, uc: u21) !void { + if (p.comment) return; const n = std.unicode.utf8CodepointSequenceLength(uc) catch { return p.err(.UnicodeLengthError, "Unicode/UTF-8 escape"); }; @@ -238,10 +241,12 @@ fn getCharsAsRune(p: *Parser) Value { // fn addListElt(p: *Parser, elt: Value) !void { + if (p.comment) return; try p.list_elts.append(p.alloc, elt); } fn getList(p: *Parser) !Value { + if (p.comment) return value.nil; if (p.list_elts.items.len == p.context.list_start) return value.nil; defer p.list_elts.items.len = p.context.list_start; const vals = p.list_elts.items[p.context.list_start..]; @@ -259,6 +264,7 @@ fn makeList(p: *Parser, vals: []const Value) !Value { const Fn = enum { parseUnit, endUnit, + endSkipUnit, returnContext, parseDatum, endDatum, @@ -275,6 +281,7 @@ inline fn call(p: *Parser, f: Fn) !void { try switch (f) { .parseUnit => p.parseUnit(), .endUnit => p.endUnit(), + .endSkipUnit => p.endSkipUnit(), .returnContext => p.returnContext(), .parseDatum => p.parseDatum(), .endDatum => p.endDatum(), @@ -380,6 +387,7 @@ fn retNoDecode(p: *Parser, val: Value) void { } fn decode(p: *Parser, val: Value) !Value { + if (p.comment) return val; if (p.decoder) |dec| return dec.decodeInPlace(val); return val; } @@ -393,12 +401,7 @@ fn parseUnit(p: *Parser) !void { while (c1) |c| : (c1 = try p.read()) { switch (try p.checkBlank(c)) { .yes => {}, - .skip_unit => { - // Queue another parseUnit, but continue the current one, whose - // result will be silently ignored. Simpler alternative to: - // return p.subr(.parseUnit, .parseUnit); - try p.push(.parseUnit); - }, + .skip_unit => return p.skipUnit(.parseUnit), .no => { p.unread(c); return p.subr(.parseDatum, .endUnit); @@ -408,13 +411,24 @@ fn parseUnit(p: *Parser) !void { return p.retval(value.eof); } +fn skipUnit(p: *Parser, next: Fn) !void { + p.comment = true; + try p.push(next); + return p.subr(.parseUnit, .endSkipUnit); +} + +fn endSkipUnit(p: *Parser) !void { + p.comment = false; + return p.ret(); +} + fn endUnit(p: *Parser) !void { const c = p.getUnread() orelse return p.ret(); switch (try p.checkBlank(c)) { .yes => {}, .skip_unit => { p.context.val = p.result; - return p.subr(.parseUnit, .returnContext); + return p.skipUnit(.returnContext); }, .no => p.unread(c), } -- cgit v1.2.3