summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/test/parse.zig8
-rw-r--r--src/zisp/io/Parser.zig40
2 files changed, 25 insertions, 23 deletions
diff --git a/src/test/parse.zig b/src/test/parse.zig
index 94ccbe5..272c92a 100644
--- a/src/test/parse.zig
+++ b/src/test/parse.zig
@@ -44,9 +44,9 @@ test "parse short bare string" {
try expect(parse("|x()|").eq(str("x()")));
try expect(parse("|{\\|}|").eq(str("{|}")));
try expect(parse("foobar").eq(str("foobar")));
- try expect(parse("!$%.*+").eq(str("!$%.*+")));
- try expect(parse("-/<=>?").eq(str("-/<=>?")));
- try expect(parse("@^_~00").eq(str("@^_~00")));
+ try expect(parse("!$%*+-").eq(str("!$%*+-")));
+ try expect(parse("/<=>?@").eq(str("/<=>?@")));
+ try expect(parse("^_~000").eq(str("^_~000")));
}
test "parse long bare string" {
@@ -56,7 +56,7 @@ test "parse long bare string" {
try expect(parse("+foo.bar.baz").eq(str("+foo.bar.baz")));
try expect(parse("-foo.bar.baz").eq(str("-foo.bar.baz")));
try expect(parse("0foo.bar.baz").eq(str("0foo.bar.baz")));
- try expect(parse("!$%*+-./<=>?@^_~").eq(str("!$%*+-./<=>?@^_~")));
+ try expect(parse("!$%*+-/<=>?@^_~").eq(str("!$%*+-/<=>?@^_~")));
try expect(parse("|foo\\x20;bar\\x0a;baz|").eq(str("foo bar\nbaz")));
}
diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig
index 0fea5f3..d18150e 100644
--- a/src/zisp/io/Parser.zig
+++ b/src/zisp/io/Parser.zig
@@ -96,13 +96,14 @@ const real_cons = &value.pair.cons;
const fake_cons = &dummyCons;
pub const Error = enum {
+ ReadError,
+ UnexpectedEof,
InvalidCharacter,
UnclosedString,
- UnexpectedEof,
- OutOfRange,
- ReadError,
UnicodeLengthError,
UnicodeEncodeError,
+ RuneTooLong,
+ OutOfRange,
};
pub const Context = struct {
@@ -410,8 +411,7 @@ fn returnContext(p: *Parser) !void {
fn parseDatum(p: *Parser) !void {
const c = p.getUnread() orelse try p.readNoEof("datum");
if (isBareChar(c) or c == '.') {
- const s = try p.parseBareString(c);
- return p.jump(.parseJoin, s);
+ return p.jump(.parseJoin, try p.getBareString(c));
} else {
return p.parseCladDatum(c, .parseJoin);
}
@@ -456,7 +456,7 @@ fn endJoinDatum(p: *Parser) !void {
return p.jump(.parseJoin, joined);
}
-fn parseBareString(p: *Parser, c1: u8) !Value {
+fn getBareString(p: *Parser, c1: u8) !Value {
const allow_dots = std.ascii.isDigit(c1) or switch (c1) {
'.', '+', '-' => true,
else => false,
@@ -475,8 +475,8 @@ fn parseBareString(p: *Parser, c1: u8) !Value {
fn parseCladDatum(p: *Parser, c: u8, next: Fn) !void {
return switch (c) {
- '|' => p.jump(next, try p.parseString('|')),
- '"' => p.jump(next, try p.parseString('"')),
+ '|' => p.jump(next, try p.getString('|')),
+ '"' => p.jump(next, try p.getString('"')),
'#' => p.parseHashExpr(next),
'(', '[', '{' => p.parseList(c, next),
'\'', '`', ',' => p.parseQuoteExpr(c, next),
@@ -484,7 +484,7 @@ fn parseCladDatum(p: *Parser, c: u8, next: Fn) !void {
};
}
-fn parseString(p: *Parser, comptime close: u8) !Value {
+fn getString(p: *Parser, comptime close: u8) !Value {
while (try p.read()) |c| sw: switch (c) {
close => {
const s = p.getCharsAsString();
@@ -577,12 +577,11 @@ 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)) {
- const r = try p.parseRune(c);
- return p.parseRuneEnd(r, next);
+ 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.parseBareString(c1)));
+ return p.jump(next, p.cons(HASH, try p.getBareString(c1)));
}
if (c == '%') {
return p.parseLabel(next);
@@ -602,14 +601,17 @@ fn endHashDatum(p: *Parser) !void {
return p.retval(p.cons(HASH, p.result));
}
-fn parseRune(p: *Parser, c1: u8) !Value {
+fn getRune(p: *Parser, c1: u8) !Value {
try p.addChar(c1);
var len: usize = 1;
while (try p.read()) |c| : (len += 1) {
- if (len == 6 or !std.ascii.isAlphanumeric(c)) {
+ if (!std.ascii.isAlphanumeric(c)) {
p.unread(c);
return p.getCharsAsRune();
}
+ if (len == 6) {
+ return p.err(.RuneTooLong, "rune");
+ }
try p.addChar(c);
}
return p.getCharsAsRune();
@@ -619,13 +621,13 @@ 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.parseBareString(c1)));
+ return p.jump(next, p.cons(r, try p.getBareString(c1)));
}
if (c == '"') {
- return p.jump(next, p.cons(r, try p.parseString('"')));
+ return p.jump(next, p.cons(r, try p.getString('"')));
}
if (c == '|') {
- return p.jump(next, p.cons(r, try p.parseString('|')));
+ return p.jump(next, p.cons(r, try p.getString('|')));
}
p.unread(c);
switch (c) {
@@ -772,8 +774,8 @@ fn checkBlank(p: *Parser, c: u8) !enum { yes, skip_unit, no } {
fn isBareChar(c: u8) bool {
return switch (c) {
// zig fmt: off
- 'a'...'z' , 'A'...'Z' , '0'...'9' , '!' , '$' , '%' , '*' ,'+' ,
- '-' , '.' , '/' , '<' , '=' , '>' , '?' , '@' , '^' , '_' , '~' => true,
+ 'a'...'z' , 'A'...'Z' , '0'...'9' , '!' , '$' , '%' , '*' , '+' ,
+ '-' , '/' , '<' , '=' , '>' , '?' , '@' , '^' , '_' , '~' , => true,
// zig fmt: on
else => false,
};