summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTaylan Kammer <taylan.kammer@gmail.com>2026-06-23 18:15:04 +0200
committerTaylan Kammer <taylan.kammer@gmail.com>2026-06-23 18:15:04 +0200
commitc577aa7a2e2e1db245d20ca6ae23e4d630c51897 (patch)
treee2e50f8555c200c31a5df765d007cb675b2cad62 /src
parent8794bca597b6c115a0c3b4b1e7a449c45dfeca1d (diff)
Don't alloc or decode for datum comments.
Diffstat (limited to 'src')
-rw-r--r--src/zisp/io/Parser.zig28
1 files 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),
}