From 40b08e6beffb7726d03f90823574a4690ff326ab Mon Sep 17 00:00:00 2001 From: BalaM314 <71201189+BalaM314@users.noreply.github.com> Date: Thu, 23 Nov 2023 16:01:58 +0530 Subject: [PATCH] Fix crash --- src/parser.ts | 2 +- src/statements.js | 24 +++++++++++++++--------- src/statements.ts | 16 ++++++++++------ 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 320b182..fbe7da3 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -9,7 +9,7 @@ export type ExpressionASTTreeNode = { nodes: ExpressionASTNode[]; } -export type TokenMatcher = (TokenType | ".*" | ".+"); +export type TokenMatcher = (TokenType | ".*" | ".+" | "expr"); export type ProgramAST = ProgramASTNode[]; export type ProgramASTLeafNode = Statement; diff --git a/src/statements.js b/src/statements.js index 7374dec..3f1b9d2 100644 --- a/src/statements.js +++ b/src/statements.js @@ -88,23 +88,29 @@ export class Statement { if (i == this.tokens.length - 1) return true; //Last token is a wildcard else { + if (j >= input.length && !allowEmpty) + return [`Unexpected end of line`, 4]; let anyTokensSkipped = false; while (this.tokens[i + 1] != input[j].type) { j++; anyTokensSkipped = true; - if (j == input.length) + if (j >= input.length) return [`Expected a ${this.tokens[i + 1]}, but none were found`, 4]; } if (!anyTokensSkipped && !allowEmpty) return [`Expected one or more tokens, but found zero`, 6]; } } - else if (this.tokens[i] == "#") - throw new Error(`absurd`); - else if (this.tokens[i] == input[j].type) - j++; //Token matches, move to next one - else - return [`Expected a ${this.tokens[i]}, got "${input[j].text}" (${input[j].type})`, 5]; + else { + if (j >= input.length) + return [`Unexpected end of line`, 4]; + if (this.tokens[i] == "#") + throw new Error(`absurd`); + else if (this.tokens[i] == input[j].type) + j++; //Token matches, move to next one + else + return [`Expected a ${this.tokens[i]}, got "${input[j].text}" (${input[j].type})`, 5]; + } } return true; } @@ -129,13 +135,13 @@ export class Statement { } } Statement.tokens = null; -makeStatement("declaration", "keyword.declare"); +makeStatement("declaration", "keyword.declare", "name", "punctuation.colon", "name"); makeStatement("assignment", "#", "name", "operator.assignment", ".+"); makeStatement("output", "keyword.output", ".+"); makeStatement("input", "keyword.input", "name"); makeStatement("return", "keyword.return"); makeStatement("if", "block", "auto", "keyword.if", ".+", "keyword.then"); -makeStatement("for", "block", "auto", "keyword.for", "name", "operator.assignment", "number.decimal", "keyword.to", "number.decimal"); //TODO fix endfor: should be `NEXT i`, not `NEXT` +makeStatement("for", "block", "auto", "keyword.for", "name", "operator.assignment", "number.decimal", "keyword.to", "number.decimal"); //TODO fix endfor: should be `NEXT i`, not `NEXT` //TODO "number": accept names also makeStatement("while", "block", "auto", "keyword.while", ".+"); makeStatement("dowhile", "block", "auto", "keyword.dowhile"); let FunctionStatement = (() => { diff --git a/src/statements.ts b/src/statements.ts index 7cfa982..62e0f22 100644 --- a/src/statements.ts +++ b/src/statements.ts @@ -80,17 +80,21 @@ export class Statement { const allowEmpty = this.tokens[i] == ".*"; if(i == this.tokens.length - 1) return true; //Last token is a wildcard else { + if(j >= input.length && !allowEmpty) return [`Unexpected end of line`, 4]; let anyTokensSkipped = false; while(this.tokens[i + 1] != input[j].type){ j ++; anyTokensSkipped = true; - if(j == input.length) return [`Expected a ${this.tokens[i + 1]}, but none were found`, 4]; + if(j >= input.length) return [`Expected a ${this.tokens[i + 1]}, but none were found`, 4]; } if(!anyTokensSkipped && !allowEmpty) return [`Expected one or more tokens, but found zero`, 6]; } - } else if(this.tokens[i] == "#") throw new Error(`absurd`); - else if(this.tokens[i] == input[j].type) j++; //Token matches, move to next one - else return [`Expected a ${this.tokens[i]}, got "${input[j].text}" (${input[j].type})`, 5]; + } else { + if(j >= input.length) return [`Unexpected end of line`, 4]; + if(this.tokens[i] == "#") throw new Error(`absurd`); + else if(this.tokens[i] == input[j].type) j++; //Token matches, move to next one + else return [`Expected a ${this.tokens[i]}, got "${input[j].text}" (${input[j].type})`, 5]; + } } return true; } @@ -113,7 +117,7 @@ export class Statement { } } -makeStatement("declaration", "keyword.declare"); +makeStatement("declaration", "keyword.declare", "name", "punctuation.colon", "name"); makeStatement("assignment", "#", "name", "operator.assignment", ".+"); makeStatement("output", "keyword.output", ".+"); makeStatement("input", "keyword.input", "name"); @@ -121,7 +125,7 @@ makeStatement("return", "keyword.return"); makeStatement("if", "block", "auto", "keyword.if", ".+", "keyword.then"); -makeStatement("for", "block", "auto", "keyword.for", "name", "operator.assignment", "number.decimal", "keyword.to", "number.decimal"); //TODO fix endfor: should be `NEXT i`, not `NEXT` +makeStatement("for", "block", "auto", "keyword.for", "name", "operator.assignment", "number.decimal", "keyword.to", "number.decimal"); //TODO fix endfor: should be `NEXT i`, not `NEXT` //TODO "number": accept names also makeStatement("while", "block", "auto", "keyword.while", ".+"); makeStatement("dowhile", "block", "auto", "keyword.dowhile");