summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/zisp/io/Parser.zig59
1 files 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);