diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/zisp/io/Parser.zig | 41 |
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, }; |
