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