diff options
| -rw-r--r-- | src/zisp/io/Parser.zig | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig index 2bb7624..012080b 100644 --- a/src/zisp/io/Parser.zig +++ b/src/zisp/io/Parser.zig @@ -249,9 +249,8 @@ const Fn = enum { parseDatum, endUnit, returnContext, - endFirstDatum, - endJoinDatum, parseJoin, + endJoinDatum, parseHashDatum, endHashDatum, endRuneDatum, @@ -262,15 +261,14 @@ const Fn = enum { endQuoteExpr, }; -fn call(p: *Parser, f: Fn) !void { +inline fn call(p: *Parser, f: Fn) !void { try switch (f) { .parseUnit => p.parseUnit(), .parseDatum => p.parseDatum(), .endUnit => p.endUnit(), .returnContext => p.returnContext(), - .endFirstDatum => p.endFirstDatum(), - .endJoinDatum => p.endJoinDatum(), .parseJoin => p.parseJoin(), + .endJoinDatum => p.endJoinDatum(), .parseHashDatum => p.parseHashDatum(), .endHashDatum => p.endHashDatum(), .endRuneDatum => p.endRuneDatum(), @@ -373,9 +371,14 @@ fn retval(p: *Parser, val: Value) void { fn parseUnit(p: *Parser) !void { var c1 = p.getUnread() orelse try p.read(); while (c1) |c| : (c1 = try p.read()) { - switch (try p.checkBlanks(c)) { + switch (try p.checkBlank(c)) { .yes => {}, - .skip_unit => try p.push(.parseUnit), + .skip_unit => { + // Queue another parseUnit, but continue the current one, whose + // result will be silently ignored. Simpler alternative to: + // p.subr(.parseUnit, .parseUnit); + try p.push(.parseUnit); + }, .no => { p.unread(c); return p.subr(.parseDatum, .endUnit); @@ -387,35 +390,29 @@ fn parseUnit(p: *Parser) !void { fn endUnit(p: *Parser) !void { const c = p.getUnread() orelse return p.ret(); - switch (try p.checkBlanks(c)) { + switch (try p.checkBlank(c)) { .yes => {}, - .skip_unit => return p.skipUnitAndReturn(), + .skip_unit => { + p.context.val = p.result; + return p.subr(.parseUnit, .returnContext); + }, .no => p.unread(c), } return p.ret(); } -fn skipUnitAndReturn(p: *Parser) !void { - p.context.val = p.result; - return p.subr(.parseUnit, .returnContext); -} - fn returnContext(p: *Parser) !void { return p.retval(p.context.val); } fn parseDatum(p: *Parser) !void { - return p.parseOneDatum(p.getUnread().?, .endFirstDatum); + return p.parseOneDatum(p.getUnread().?, .parseJoin); } -fn endFirstDatum(p: *Parser) !void { +fn parseJoin(p: *Parser) !void { if (p.result.eq(value.none)) { return p.ret(); } - return p.parseJoin(); -} - -fn parseJoin(p: *Parser) !void { const c = p.getUnread() orelse try p.read() orelse return p.ret(); switch (c) { '.', ':' => { @@ -678,7 +675,7 @@ fn parseList(p: *Parser, open: u8, next: Fn) !void { if (c == close) { return p.jump(next, head); } - switch (try p.checkBlanks(c)) { + switch (try p.checkBlank(c)) { .yes => {}, .skip_unit => { try p.listParserSetup(head, close, next); @@ -722,7 +719,7 @@ fn continueList(p: *Parser) !void { if (c == close) { return p.endList(); } - switch (try p.checkBlanks(c)) { + switch (try p.checkBlank(c)) { .yes => {}, .skip_unit => { try p.pushContext(.continueList); @@ -757,7 +754,7 @@ fn closeImproperList(p: *Parser) !void { if (c == close) { return p.retval(result); } - switch (try p.checkBlanks(c)) { + switch (try p.checkBlank(c)) { .yes => {}, .skip_unit => return p.subr(.parseUnit, .closeImproperList), .no => return p.err(.InvalidCharacter, "after list tail"), @@ -789,7 +786,7 @@ fn endQuoteExpr(p: *Parser) !void { // Helpers -fn checkBlanks(p: *Parser, c: u8) !enum { yes, skip_unit, no } { +fn checkBlank(p: *Parser, c: u8) !enum { yes, skip_unit, no } { switch (c) { '\t'...'\r', ' ' => return .yes, ';' => { |
