Repair comment reading and trailing comments in pexprs
This commit is contained in:
parent
f18ba9c9d4
commit
58ebc93eb5
|
@ -165,37 +165,34 @@ export class Reader extends ReaderBase<never> {
|
||||||
}
|
}
|
||||||
|
|
||||||
readCompound(c: Compound, terminator: string): Compound {
|
readCompound(c: Compound, terminator: string): Compound {
|
||||||
while (true) {
|
while (this.readExpr(c, terminator)) {}
|
||||||
this.state.skipws();
|
return c;
|
||||||
if (this.state.peek() === terminator) {
|
|
||||||
this.state.advance();
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (!this.readExpr(c)) {
|
|
||||||
this.state.error(`Missing "${terminator}"`, this.state.copyPos());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readSimpleExpr(c: BaseCompound<SimpleExpr>): boolean {
|
readSimpleExpr(c: BaseCompound<SimpleExpr>): boolean {
|
||||||
return this._readInto(c, false);
|
return this._readInto(c, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
readExpr(c: BaseCompound<Expr>): boolean {
|
readExpr(c: BaseCompound<Expr>, terminator: string | null = null): boolean {
|
||||||
return this._readInto(c as BaseCompound<SimpleExpr> /* yuck */, true);
|
return this._readInto(c as BaseCompound<SimpleExpr> /* yuck */, true, terminator);
|
||||||
}
|
}
|
||||||
|
|
||||||
_readInto(c: BaseCompound<SimpleExpr>, acceptPunct: boolean): boolean {
|
_checkTerminator(actual: string, expected: string | null, startPos: Position): false {
|
||||||
|
if (actual === expected) return false;
|
||||||
|
this.state.error('Unexpected ' + actual, startPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
_readInto(c: BaseCompound<SimpleExpr>, acceptPunct: boolean, terminator: string | null = null): boolean {
|
||||||
while (true) {
|
while (true) {
|
||||||
this.state.skipws();
|
this.state.skipws();
|
||||||
if (this.state.atEnd()) return false;
|
if (this.state.atEnd() && terminator === null) return false;
|
||||||
const startPos = this.state.copyPos();
|
const startPos = this.state.copyPos();
|
||||||
const ch = this.state.nextchar();
|
const ch = this.state.nextchar();
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '"':
|
case '"':
|
||||||
return c.push(this.state.readString('"'), startPos);
|
return c.push(this.state.readString('"'), startPos);
|
||||||
case '|':
|
case '|':
|
||||||
return c.push(Symbol.for(this.state.readString('|')), startPos); return true;
|
return c.push(Symbol.for(this.state.readString('|')), startPos);
|
||||||
case ';':
|
case ';':
|
||||||
if (acceptPunct) {
|
if (acceptPunct) {
|
||||||
return (c as BaseCompound<Expr>).push(new Punct(';'), startPos);
|
return (c as BaseCompound<Expr>).push(new Punct(';'), startPos);
|
||||||
|
@ -264,9 +261,10 @@ export class Reader extends ReaderBase<never> {
|
||||||
case '<': return c.push(this.readCompound(new Record(), '>'), startPos);
|
case '<': return c.push(this.readCompound(new Record(), '>'), startPos);
|
||||||
case '[': return c.push(this.readCompound(new Sequence(), ']'), startPos);
|
case '[': return c.push(this.readCompound(new Sequence(), ']'), startPos);
|
||||||
case '{': return c.push(this.readCompound(new Block(), '}'), startPos);
|
case '{': return c.push(this.readCompound(new Block(), '}'), startPos);
|
||||||
case '>': this.state.error('Unexpected >', startPos);
|
case ')': return this._checkTerminator(ch, terminator, startPos);
|
||||||
case ']': this.state.error('Unexpected ]', startPos);
|
case '>': return this._checkTerminator(ch, terminator, startPos);
|
||||||
case '}': this.state.error('Unexpected }', startPos);
|
case ']': return this._checkTerminator(ch, terminator, startPos);
|
||||||
|
case '}': return this._checkTerminator(ch, terminator, startPos);
|
||||||
case ',':
|
case ',':
|
||||||
if (acceptPunct) {
|
if (acceptPunct) {
|
||||||
return (c as BaseCompound<Expr>).push(new Punct(','), startPos);
|
return (c as BaseCompound<Expr>).push(new Punct(','), startPos);
|
||||||
|
|
|
@ -254,10 +254,9 @@ export class ReaderState {
|
||||||
readCommentLine(): string {
|
readCommentLine(): string {
|
||||||
let acc = '';
|
let acc = '';
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (this.atEnd()) return acc;
|
||||||
const c = this.nextchar();
|
const c = this.nextchar();
|
||||||
if (c === '\n' || c === '\r') {
|
if (c === '\n' || c === '\r') return acc;
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
acc = acc + c;
|
acc = acc + c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,3 +25,21 @@ describe('basics', () => {
|
||||||
expect(v).is(P(s));
|
expect(v).is(P(s));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('trailing comments', () => {
|
||||||
|
it('basics 1', () => {
|
||||||
|
const d = new Pexpr.Reader('# a comment with nothing after').nextDocument();
|
||||||
|
expect(d.annotations?.[d.exprs.length].get(0)?.item).toBe('a comment with nothing after');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('basics 2', () => {
|
||||||
|
const d = new Pexpr.Reader('# a comment with nothing after\n').nextDocument();
|
||||||
|
expect(d.annotations?.[d.exprs.length].get(0)?.item).toBe('a comment with nothing after');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('inside a sequence', () => {
|
||||||
|
const d = new Pexpr.Reader('[\n1\n# a comment with nothing after\n]\n').nextDocument();
|
||||||
|
const seq = d.get(0)?.item as Pexpr.Compound;
|
||||||
|
expect(seq.annotations?.[seq.exprs.length].get(0)?.item).toBe('a comment with nothing after');
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue