summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/zisp/io/Parser.zig41
1 files changed, 28 insertions, 13 deletions
diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig
index 8d16b93..2c7b332 100644
--- a/src/zisp/io/Parser.zig
+++ b/src/zisp/io/Parser.zig
@@ -73,6 +73,9 @@ const COLON = value.rune.pack("COLON");
const JOIN = value.rune.pack("JOIN");
const LABEL = value.rune.pack("LABEL");
const HASH = value.rune.pack("HASH");
+const DQSTR = value.rune.pack("DQSTR");
+const PQSTR = value.rune.pack("PQSTR");
+const ATSTR = value.rune.pack("ATSTR");
const QUOTE = value.rune.pack("QUOTE");
const GRAVE = value.rune.pack("GRAVE");
const COMMA = value.rune.pack("COMMA");
@@ -371,7 +374,8 @@ fn returnContext(p: *Parser) !void {
fn parseDatum(p: *Parser) !void {
const c = p.getUnread() orelse try p.readNoEof("datum");
- if (isBareChar(c) or c == '.') {
+
+ if (isBareChar(c) or isSpecialBareChar(c)) {
return p.jump(.parseJoin, try p.getBareString(c));
} else {
return p.parseCladDatum(c, .parseJoin);
@@ -418,13 +422,12 @@ fn endJoinDatum(p: *Parser) !void {
}
fn getBareString(p: *Parser, c1: u8) !Value {
- const allow_dots = std.ascii.isDigit(c1) or switch (c1) {
- '.', '+', '-' => true,
- else => false,
- };
+ const swallow_joins = isSpecialBareChar(c1);
try p.addChar(c1);
while (try p.read()) |c| {
- if (isBareChar(c) or (allow_dots and c == '.')) {
+ if (isBareChar(c)) {
+ try p.addChar(c);
+ } else if (swallow_joins and (c == '.' or c == ':')) {
try p.addChar(c);
} else {
p.unread(c);
@@ -438,7 +441,7 @@ fn parseCladDatum(p: *Parser, c: u8, next: Fn) !void {
return switch (c) {
'|' => p.jump(next, try p.getString('|')),
'"' => p.jump(next, try p.getString('"')),
- '~' => p.jump(next, try p.getTildeString()),
+ '@' => p.jump(next, try p.getAtString()),
'#' => p.parseHashExpr(next),
'(', '[', '{' => p.parseList(c, next),
'\'', '`', ',' => p.parseQuoteExpr(c, next),
@@ -450,7 +453,11 @@ fn getString(p: *Parser, comptime close: u8) !Value {
while (try p.read()) |c| sw: switch (c) {
close => {
const s = p.getCharsAsString();
- return if (close == '"') p.cons(QUOTE, s) else s;
+ return switch (close) {
+ '|' => p.cons(PQSTR, s),
+ '"' => p.cons(DQSTR, s),
+ else => unreachable,
+ };
},
'\\' => switch (try p.readNoEof("string backslash escape")) {
'\\', '|', '"' => |c2| try p.addChar(c2),
@@ -473,16 +480,16 @@ fn getString(p: *Parser, comptime close: u8) !Value {
return p.err(.UnclosedString, .{close} ++ " string");
}
-fn getTildeString(p: *Parser) !Value {
- const sentinel = try p.readNoEof("tilde");
+fn getAtString(p: *Parser) !Value {
+ const sentinel = try p.readNoEof("at-string");
while (try p.read()) |c| {
if (c == sentinel) {
const s = p.getCharsAsString();
- return p.cons(TILDE, s);
+ return p.cons(ATSTR, s);
}
try p.addChar(c);
}
- return p.err(.UnclosedString, "tilde string");
+ return p.err(.UnclosedString, "at-string");
}
fn skipStringLfEscape(p: *Parser) !u8 {
@@ -536,6 +543,7 @@ fn parseStringUniHexEsc(p: *Parser) !void {
fn parseStringCharEsc(p: *Parser, c: u8) !void {
try p.addChar(switch (c) {
+ '0' => 0,
'a' => 7,
'b' => 8,
't' => 9,
@@ -745,11 +753,18 @@ fn checkBlank(p: *Parser, c: u8) !enum { yes, skip_unit, no } {
}
}
+fn isSpecialBareChar(c: u8) bool {
+ return switch (c) {
+ '+', '-', '.', ':', '0'...'9' => true,
+ else => false,
+ };
+}
+
fn isBareChar(c: u8) bool {
return switch (c) {
// zig fmt: off
'a'...'z' , 'A'...'Z' , '0'...'9' , '!' , '$' , '%' , '*' ,
- '+' , '-' , '/' , '<' , '=' , '>' , '?' , '@' , '^' , '_' , => true,
+ '+' , '-' , '/' , '<' , '=' , '>' , '?' , '^' , '_' , '~' , => true,
// zig fmt: on
else => false,
};