Skip to content

Commit

Permalink
Fixed parsing bug that prevented complete parsing of the program.
Browse files Browse the repository at this point in the history
  • Loading branch information
amyjko committed Jul 10, 2024
1 parent dfbcd9e commit 14cec6e
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Dates are in `YYYY-MM-DD` format and versions are in [semantic versioning](http:
### Fixed

- [#514](https://github.com/wordplaydev/wordplay/issues/514) Fixed cursor position on hidden language tags.
- Fixed parsing bug that prevented complete parsing of the program.

## 0.10.4 2024-07-08

Expand Down
12 changes: 11 additions & 1 deletion src/parser/Parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import NumberLiteral from '@nodes/NumberLiteral';
import NumberType from '@nodes/NumberType';
import NameType from '@nodes/NameType';
import NoneType from '@nodes/NoneType';
import { toProgram } from './parseProgram';
import parseProgram, { toProgram } from './parseProgram';
import Program from '@nodes/Program';
import StreamType from '@nodes/StreamType';
import TableType from '@nodes/TableType';
Expand Down Expand Up @@ -384,3 +384,13 @@ test('unparsables in docs', () => {
expect(doc.markup.paragraphs[0].segments[2]).toBeInstanceOf(Token);
expect(doc.markup.paragraphs[0].segments.length).toBe(3);
});

test('unparsables in blocks', () => {
const program = parseProgram(toTokens('test: Phrase(\\\\)\ntest'));
expect(program).toBeInstanceOf(Program);
expect(program.expression).toBeInstanceOf(Block);
expect(program.expression.statements[0]).toBeInstanceOf(Bind);
expect(program.expression.statements[1]).toBeInstanceOf(
UnparsableExpression,
);
});
2 changes: 1 addition & 1 deletion src/parser/Tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default class Tokens {
}

peekUnread() {
return this.#unread;
return this.#unread.slice();
}

/** Returns true if the token list isn't empty. */
Expand Down
24 changes: 18 additions & 6 deletions src/parser/parseExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import Spread from '../nodes/Spread';
import Otherwise from '@nodes/Otherwise';
import Match from '@nodes/Match';
import Input from '@nodes/Input';
import type Token from '@nodes/Token';

export function toExpression(code: string): Expression {
return parseExpression(toTokens(code));
Expand Down Expand Up @@ -128,12 +129,23 @@ export function parseBlock(
((root && !doc) ||
(!root && !doc && tokens.nextIsnt(Sym.EvalClose)) ||
(doc && tokens.nextIsnt(Sym.Code))),
() =>
statements.push(
nextIsBind(tokens, true)
? parseBind(tokens)
: parseExpression(tokens),
),
() => {
const next = nextIsBind(tokens, true)
? parseBind(tokens)
: parseExpression(tokens);
statements.push(next);
// Did we get an unparsable expression with no tokens? Read until we get to the block close or the end of the
// program. If we don't do this, the we will stop reading statements and will not parse the remainder of the program.
if (
next instanceof UnparsableExpression &&
next.unparsables.length === 0
) {
const unparsed: Token[] = [];
while (tokens.hasNext() && tokens.nextIsnt(Sym.EvalClose))
unparsed.push(tokens.read());
statements.push(new UnparsableExpression(unparsed));
}
},
);

const close = root
Expand Down
3 changes: 1 addition & 2 deletions src/parser/parseProgram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ export default function parseProgram(tokens: Tokens, doc = false): Program {

const block = parseBlock(tokens, BlockKind.Root, doc);

// If the next token is the end, we're done! Otherwise, read all of the remaining
// tokens and bundle them into an unparsable.
// If the next token is the end, we're done!
const end = tokens.nextIsEnd() ? tokens.read(Sym.End) : undefined;

return new Program(docs, borrows, block, end);
Expand Down

0 comments on commit 14cec6e

Please sign in to comment.