improved error handling

This commit is contained in:
Lauchmelder 2021-11-28 15:39:57 +01:00
parent e82de580af
commit b43f547ae5
2 changed files with 34 additions and 25 deletions

View file

@ -34,6 +34,12 @@ class Geometry extends HTMLElement
let content = loadScript(sourceFile); let content = loadScript(sourceFile);
let parser = new Parser(content); let parser = new Parser(content);
if(!parser.good())
{
console.error("Failed to create parser for script " + sourceFile);
return;
}
for(let instr of parser.instructions) for(let instr of parser.instructions)
{ {
console.log(instr.eval()); console.log(instr.eval());

View file

@ -5,22 +5,43 @@ class Parser
{ {
public instructions: Instruction[]; public instructions: Instruction[];
private variables: { [id: string] : InstructionParameter}; private variables: { [id: string] : InstructionParameter};
private success: boolean;
constructor(source: string) constructor(source: string)
{ {
this.instructions = []; this.instructions = [];
this.variables = {}; this.variables = {};
this.success = false;
let lines = source.split(/\r?\n/); let lines = source.split(/\r?\n/);
let currentLine = 1;
for(let line of lines) for(let line of lines)
{ {
let instr = this.parseInstruction(line); let instr;
try
{
instr = this.parseInstruction(line);
}
catch(e)
{
console.error("Error in line " + currentLine);
console.error(e);
return;
}
if(instr !== null) if(instr !== null)
if(!instr[0]) if(!instr[0])
this.instructions.push(instr[1]); this.instructions.push(instr[1]);
currentLine++;
} }
this.success = true;
} }
public good() { return this.success; }
private parseInstruction(instruction: string): [boolean, Instruction] private parseInstruction(instruction: string): [boolean, Instruction]
{ {
// If the instruction is an empty line, do nothing for now // If the instruction is an empty line, do nothing for now
@ -39,16 +60,10 @@ class Parser
// match the pattern "text(text)" // match the pattern "text(text)"
let matches = instruction.match(/[A-Za-z]*\(.*\)/); let matches = instruction.match(/[A-Za-z]*\(.*\)/);
if(matches === null) // no match found if(matches === null) // no match found
{ throw new Error("Line does not contain a valid instruction.");
console.error("Invalid syntax");
return null;
}
if(matches.length > 1) // more than one match if(matches.length > 1) // more than one match
{ throw new Error("Line may only contain one instruction");
console.error("Script may only contain one instruction per line");
return null;
}
let instr = matches[0]; // get the instruction let instr = matches[0]; // get the instruction
let paranthesisPos = instr.search(/\(/); // Find the position of the first opening paranthesis let paranthesisPos = instr.search(/\(/); // Find the position of the first opening paranthesis
@ -68,25 +83,16 @@ class Parser
let newInstruction = InstructionFactory.createInstruction(symbol); let newInstruction = InstructionFactory.createInstruction(symbol);
if(newInstruction === null) if(newInstruction === null)
{ throw new Error("Unknown instruction: \"" + symbol + "\"");
console.error("Unknown instruction: \"" + symbol + "\"");
return null;
}
let expectedArgs = newInstruction.getParameterCount(); let expectedArgs = newInstruction.getParameterCount();
if(expectedArgs !== params.length) if(expectedArgs !== params.length)
{ throw new Error("Wrong number of arguments for instruction \"" + symbol + "\". Expected " + expectedArgs + " arguments but received " + params.length + " instead.");
console.error("Wrong number of arguments for instruction \"" + symbol + "\". Expected " + expectedArgs + " arguments but received " + params.length + " instead.");
return null;
}
for(let param of params) for(let param of params)
{ {
if(!this.parseParameter(newInstruction, param)) if(!this.parseParameter(newInstruction, param))
{ throw new Error("Error during parameter parsing: \"" + param + "\" failed to be parsed.");
console.error("Error during parameter parsing: \"" + param + "\" failed to be parsed.");
return null;
}
} }
let assignment = instruction.search(/->/); let assignment = instruction.search(/->/);
@ -94,10 +100,7 @@ class Parser
{ {
let variableName = instruction.substring(assignment + 2, instruction.length); let variableName = instruction.substring(assignment + 2, instruction.length);
if(variableName in this.variables) if(variableName in this.variables)
{ throw new Error("Redefinition of variable \"" + variableName + "\" is not allowed.");
console.error("Redefinition of variable \"" + variableName + "\" is not allowed.");
return null;
}
this.variables[variableName] = new InstructionParameter(newInstruction); this.variables[variableName] = new InstructionParameter(newInstruction);
} }