Tidy up error reporting
This commit is contained in:
parent
a2c8eb66b9
commit
ac1a38e75f
1 changed files with 30 additions and 22 deletions
|
@ -35,6 +35,12 @@ export function parse(
|
||||||
|
|
||||||
// Parser for evaluating Notcl scripts
|
// Parser for evaluating Notcl scripts
|
||||||
|
|
||||||
|
export class ParseError extends Error {
|
||||||
|
constructor(message: string, public pos: number) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type TokenType =
|
type TokenType =
|
||||||
| "newline"
|
| "newline"
|
||||||
| "whitespace"
|
| "whitespace"
|
||||||
|
@ -47,8 +53,7 @@ type TokenType =
|
||||||
| "backslash"
|
| "backslash"
|
||||||
| "comment"
|
| "comment"
|
||||||
| "text"
|
| "text"
|
||||||
| "EOF"
|
| "EOF";
|
||||||
| "ERROR";
|
|
||||||
|
|
||||||
type Token = [TokenType, string, number];
|
type Token = [TokenType, string, number];
|
||||||
|
|
||||||
|
@ -81,9 +86,9 @@ class WipScript {
|
||||||
return this.wipWord.length == 0 && this.wipCommand.length == 0;
|
return this.wipWord.length == 0 && this.wipCommand.length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
addWordPiece(piece: InterpolatedPiece, pos?: number) {
|
addWordPiece(piece: InterpolatedPiece, pos: number) {
|
||||||
if (this.endOfWordError) {
|
if (this.endOfWordError) {
|
||||||
throw new Error(this.endOfWordError);
|
throw new ParseError(this.endOfWordError, pos);
|
||||||
}
|
}
|
||||||
if (this.startOfWord()) {
|
if (this.startOfWord()) {
|
||||||
this.wordPos = pos;
|
this.wordPos = pos;
|
||||||
|
@ -137,13 +142,14 @@ class Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (this.next = ["ERROR", "Token not matched", startPos]);
|
throw new ParseError("Token not matched", startPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(type: TokenType) {
|
expect(type: TokenType) {
|
||||||
if (this.next[0] != type) {
|
if (this.next[0] != type) {
|
||||||
throw new Error(
|
throw new ParseError(
|
||||||
`Expected ${type}, found ${this.next[0]} (${this.next[1]})`
|
`Expected ${type}, found ${this.next[0]} (${this.next[1]})`,
|
||||||
|
this.next[2]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,7 +181,7 @@ class Parser {
|
||||||
case "[": {
|
case "[": {
|
||||||
this.advance();
|
this.advance();
|
||||||
const script = this.parseScript();
|
const script = this.parseScript();
|
||||||
wip.addWordPiece({ script });
|
wip.addWordPiece({ script }, pos);
|
||||||
this.expect("]");
|
this.expect("]");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -200,8 +206,6 @@ class Parser {
|
||||||
case "backslash":
|
case "backslash":
|
||||||
this.advance();
|
this.advance();
|
||||||
continue;
|
continue;
|
||||||
case "ERROR":
|
|
||||||
throw new Error(chars);
|
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -223,10 +227,11 @@ class Parser {
|
||||||
|
|
||||||
case "quote":
|
case "quote":
|
||||||
throw new Error(`Unhandled case: ${type} (${chars})`);
|
throw new Error(`Unhandled case: ${type} (${chars})`);
|
||||||
case "ERROR":
|
|
||||||
throw new Error(chars);
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unhandled case: ${type satisfies never} (${chars})`);
|
throw new ParseError(
|
||||||
|
`Unhandled case: ${type satisfies never} (${chars})`,
|
||||||
|
pos
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.advance();
|
this.advance();
|
||||||
|
@ -261,17 +266,19 @@ class Parser {
|
||||||
wip.addWordPiece({ text: "\n" }, pos);
|
wip.addWordPiece({ text: "\n" }, pos);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown backslash escape: ${chars}`);
|
throw new ParseError(`Unknown backslash escape: ${chars}`, pos);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "EOF":
|
case "EOF":
|
||||||
throw new Error(
|
throw new ParseError(
|
||||||
"Reached end of input while parsing a backslash escape"
|
"Reached end of input while parsing a backslash escape",
|
||||||
|
pos
|
||||||
);
|
);
|
||||||
case "ERROR":
|
|
||||||
throw new Error(chars);
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unhandled case: ${type satisfies never} (${chars})`);
|
throw new ParseError(
|
||||||
|
`Unhandled case: ${type satisfies never} (${chars})`,
|
||||||
|
pos
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,9 +304,10 @@ class Parser {
|
||||||
case "}":
|
case "}":
|
||||||
return wip;
|
return wip;
|
||||||
case "EOF":
|
case "EOF":
|
||||||
throw new Error("Reached end of input while parsing a brace word");
|
throw new ParseError(
|
||||||
case "ERROR":
|
"Reached end of input while parsing a brace word",
|
||||||
throw new Error(chars);
|
pos
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
wip += chars;
|
wip += chars;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue