From 55d68e2d6586606bd0aa8aacf3052e0e7d611d83 Mon Sep 17 00:00:00 2001 From: Eric Jiang <321497+erjiang@users.noreply.github.com> Date: Sat, 14 Jun 2025 21:40:57 -0700 Subject: [PATCH] parser: support comments and ellipsis --- grammar.peg | 10 +++++++++- src/system/parser.ts | 7 ++++++- test/interpreter.js | 13 +++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/grammar.peg b/grammar.peg index 57ab6ac..fe81c61 100644 --- a/grammar.peg +++ b/grammar.peg @@ -18,6 +18,7 @@ Expression / Number / Character / String + / Ellipsis / Symbol List @@ -96,6 +97,9 @@ Character CharacterValue = val:$[^ \t\n\r()]+ { return val; } +Ellipsis + = '...' { return new SymbolObj('...'); } + Symbol = !Boolean ident:Identifier { return new SymbolObj(ident); } @@ -110,4 +114,8 @@ Initial Subsequent = Initial / [0-9] / "." / "+" -_ = [ \t\n\r]* // optional whitespace +_ = (Whitespace / LineComment)* + +Whitespace = [ \t\n\r]+ + +LineComment = ';' (![\n\r] .)* ([\n\r] / !.) diff --git a/src/system/parser.ts b/src/system/parser.ts index b8dcb91..048af23 100644 --- a/src/system/parser.ts +++ b/src/system/parser.ts @@ -16,7 +16,12 @@ export default class Parser { this.error = null; } catch (e) { this.exprs = []; - this.error = new Error((e as Error).message); + const loc = (e as any).location?.start; + if (loc) { + this.error = new Error(`${(e as Error).message} at line ${loc.line} column ${loc.column}`); + } else { + this.error = new Error((e as Error).message); + } } this.i = 0; } diff --git a/test/interpreter.js b/test/interpreter.js index a51f6b3..bfaeba8 100644 --- a/test/interpreter.js +++ b/test/interpreter.js @@ -150,6 +150,19 @@ describe('Parser', function () { const indent = FoxScheme.Parser.calculateIndentation('(display "foo \\"(")'); assert_equals(indent, 0); }); + + it("Ignores semicolon comments", function() { + var p = new $fs.Parser("1 ;comment\n2"); + assert_equals(p.nextObject(), 1); + assert_equals(p.nextObject(), 2); + }); + + it("Parses ellipsis token", function() { + var p = new $fs.Parser("..."); + var o = p.nextObject(); + assert_instanceof(o, FoxScheme.Symbol); + assert_equals(o.name(), "..."); + }); }); /*