From a779b91e730ba68c1f38cfdadbcb0fa3de041597 Mon Sep 17 00:00:00 2001 From: Taylan Kammer Date: Sun, 31 May 2026 16:06:10 +0200 Subject: Parser: Code cleanup; implement shebang parsing. --- src/zisp/io/Parser.zig | 59 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig index f92a308..a57652b 100644 --- a/src/zisp/io/Parser.zig +++ b/src/zisp/io/Parser.zig @@ -52,6 +52,7 @@ const detailed_debug = false; pub const DOT = value.rune.pack("DOT"); pub const COLON = value.rune.pack("COLON"); pub const JOIN = value.rune.pack("JOIN"); +pub const SHBANG = value.rune.pack("SHBANG"); pub const LABEL = value.rune.pack("LABEL"); pub const HASH = value.rune.pack("HASH"); pub const PQSTR = value.rune.pack("PQSTR"); @@ -545,19 +546,23 @@ fn parseStringCharEsc(p: *Parser, c: u8) !void { } fn parseHashExpr(p: *Parser, next: Fn) !void { - const c = try p.readNoEof("hash expression"); - if (std.ascii.isAlphabetic(c)) { - return p.parseRuneEnd(try p.getRune(c), next); - } - if (c == '\\') { - const c1 = try p.readNoEof("bare string after hash"); - return p.jump(next, p.cons(HASH, try p.getBareString(c1))); - } - if (c == '%') { - return p.parseLabel(next); + switch (try p.readNoEof("hash")) { + 'a'...'z', 'A'...'Z' => |c| { + const rune = try p.getRune(c); + return p.parseRuneEnd(rune, next); + }, + '\\' => { + const c1 = try p.readNoEof("hash-backslash"); + const bs = try p.getBareString(c1); + return p.jump(next, p.cons(HASH, bs)); + }, + '!' => return p.parseHashBang(next), + '%' => return p.parseLabel(next), + else => |c| { + p.unread(c); + return p.subr(.parseHashDatum, next); + }, } - p.unread(c); - return p.subr(.parseHashDatum, next); } fn parseHashDatum(p: *Parser) !void { @@ -589,24 +594,24 @@ fn getRune(p: *Parser, c1: u8) !Value { fn parseRuneEnd(p: *Parser, r: Value, next: Fn) !void { const c = p.getUnread() orelse return p.jump(next, r); - if (c == '\\') { - const c1 = try p.readNoEof("bare string at rune end"); - return p.jump(next, p.cons(r, try p.getBareString(c1))); - } - if (c == '"') { - return p.jump(next, p.cons(r, try p.getString('"'))); - } - if (c == '|') { - return p.jump(next, p.cons(r, try p.getString('|'))); - } - p.unread(c); switch (c) { + '\\' => { + const c1 = try p.readNoEof("rune-backslash"); + return p.jump(next, p.cons(r, try p.getBareString(c1))); + }, + '"' => return p.jump(next, p.cons(r, try p.getString('"'))), + '|' => return p.jump(next, p.cons(r, try p.getString('|'))), + '@' => return p.jump(next, p.cons(r, try p.getAtString())), '#', '(', '[', '{', '\'', '`', ',' => { + p.unread(c); try p.push(next); p.context.val = r; return p.subr(.parseDatum, .endRuneDatum); }, - else => return p.jump(next, r), + else => { + p.unread(c); + return p.jump(next, r); + }, } } @@ -614,6 +619,12 @@ fn endRuneDatum(p: *Parser) !void { return p.retval(p.cons(p.context.val, p.result)); } +fn parseHashBang(p: *Parser, next: Fn) !void { + const c = try p.readNoEof("hash-bang"); + const s = try p.getBareString(c); + return p.jump(next, p.cons(SHBANG, s)); +} + fn parseLabel(p: *Parser, next: Fn) !void { const n = try p.parseHex(u48, "datum label"); const l = value.fixnum.pack(n); -- cgit v1.2.3