added comments

This commit is contained in:
Lauchmelder 2021-11-28 15:46:47 +01:00
parent b43f547ae5
commit ee6fc7b02d
2 changed files with 27 additions and 8 deletions

View file

@ -10,19 +10,20 @@ enum InstructionType
abstract class Instruction abstract class Instruction
{ {
public fn: InstructionType; private type: InstructionType;
public params :Parameter[]; public params :Parameter[];
private argc: number; private argc: number;
constructor(type: InstructionType, argc: number) constructor(type: InstructionType, argc: number)
{ {
this.fn = type; this.type = type;
this.argc = argc; this.argc = argc;
this.params = []; this.params = [];
} }
abstract eval(); abstract eval();
public getParameterCount(): number { return this.argc; } public getParameterCount(): number { return this.argc; }
public getType(): InstructionType { return this.type; }
} }
class PointInstruction extends Instruction class PointInstruction extends Instruction

View file

@ -1,16 +1,24 @@
/// <reference path="parameter.ts" /> /// <reference path="parameter.ts" />
/// <reference path="instructionFactory.ts" /> /// <reference path="instructionFactory.ts" />
/**
* @brief Turns a .gs script into a list of instructions to be passed to the renderer
*/
class Parser class Parser
{ {
public instructions: Instruction[]; public instructions: Instruction[];
private variables: { [id: string] : InstructionParameter}; private macros: { [id: string] : InstructionParameter};
private success: boolean; private success: boolean;
/**
* Parses each line of the script and turns them into instructions or adds them to the macro list
*
* @param source The source code of the script
*/
constructor(source: string) constructor(source: string)
{ {
this.instructions = []; this.instructions = [];
this.variables = {}; this.macros = {};
this.success = false; this.success = false;
let lines = source.split(/\r?\n/); let lines = source.split(/\r?\n/);
@ -30,6 +38,7 @@ class Parser
return; return;
} }
// If the instruction is null it means that the instruction was a function and not a primitive
if(instr !== null) if(instr !== null)
if(!instr[0]) if(!instr[0])
this.instructions.push(instr[1]); this.instructions.push(instr[1]);
@ -48,6 +57,7 @@ class Parser
if(instruction === "") if(instruction === "")
return null; return null;
// Handle [] syntax. Lines in [] will be processed but not rendered
let hidden = false; let hidden = false;
if(instruction[0] === "[" && instruction[instruction.length - 1] === "]") if(instruction[0] === "[" && instruction[instruction.length - 1] === "]")
{ {
@ -72,6 +82,7 @@ class Parser
let symbol = instr.substr(0, paranthesisPos); // get function name let symbol = instr.substr(0, paranthesisPos); // get function name
let paramlist = instr.substring(paranthesisPos + 1, instr.length - 1); // get parameter list let paramlist = instr.substring(paranthesisPos + 1, instr.length - 1); // get parameter list
// Construct the parameter list
let match; let match;
let params = []; let params = [];
while((match = paramlist.search(/,(?![^\(]*\))/)) !== -1) while((match = paramlist.search(/,(?![^\(]*\))/)) !== -1)
@ -81,28 +92,32 @@ class Parser
} }
params.push(paramlist); params.push(paramlist);
// Create appropriate instruction
let newInstruction = InstructionFactory.createInstruction(symbol); let newInstruction = InstructionFactory.createInstruction(symbol);
if(newInstruction === null) if(newInstruction === null)
throw new Error("Unknown instruction: \"" + symbol + "\""); throw new Error("Unknown instruction: \"" + symbol + "\"");
// Check that the number of arguments passed to the function is correct
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."); throw new Error("Wrong number of arguments for instruction \"" + symbol + "\". Expected " + expectedArgs + " arguments but received " + params.length + " instead.");
// Parse the individual parameters
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."); throw new Error("Error during parameter parsing: \"" + param + "\" failed to be parsed.");
} }
// In case there is an assignment, add the instruction to the macro list
let assignment = instruction.search(/->/); let assignment = instruction.search(/->/);
if(assignment !== -1) if(assignment !== -1)
{ {
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.macros)
throw new Error("Redefinition of variable \"" + variableName + "\" is not allowed."); throw new Error("Redefinition of variable \"" + variableName + "\" is not allowed.");
this.variables[variableName] = new InstructionParameter(newInstruction); this.macros[variableName] = new InstructionParameter(newInstruction);
} }
return [hidden, newInstruction]; return [hidden, newInstruction];
@ -110,6 +125,7 @@ class Parser
private parseParameter(instr: Instruction, parameter: string): boolean private parseParameter(instr: Instruction, parameter: string): boolean
{ {
// Parameter is a number
let match = parameter.match(/-?\d*\.?\d*$/); let match = parameter.match(/-?\d*\.?\d*$/);
if(match !== null && match[0] === parameter && match.index === 0) if(match !== null && match[0] === parameter && match.index === 0)
{ {
@ -120,10 +136,11 @@ class Parser
return true; return true;
} }
// Parameter is an identifier (macro)
match = parameter.match(/[A-Za-z]*/) match = parameter.match(/[A-Za-z]*/)
if(match !== null && match[0] === parameter && match.index === 0) if(match !== null && match[0] === parameter && match.index === 0)
{ {
let paramObj = this.variables[parameter]; let paramObj = this.macros[parameter];
if(paramObj === undefined) if(paramObj === undefined)
{ {
console.error("Variable \"" + parameter + "\" is not defined"); console.error("Variable \"" + parameter + "\" is not defined");
@ -134,6 +151,7 @@ class Parser
return true; return true;
} }
// Parameter is another instruction
match = parameter.match(/[A-Za-z]*\(.*\)/) match = parameter.match(/[A-Za-z]*\(.*\)/)
if(match !== null && match[0] === parameter && match.index === 0) if(match !== null && match[0] === parameter && match.index === 0)
{ {