From d01cf5790b6b114d61132cdcdce038788b12dc0a Mon Sep 17 00:00:00 2001 From: Lauchmelder Date: Sat, 27 Nov 2021 20:54:04 +0100 Subject: [PATCH] started working on parser --- examples/test.gs | 5 +-- src/geometry.ts | 29 +-------------- src/parser/instruction.ts | 18 +++++++++ src/parser/parameter.ts | 35 ++++++++++++++++++ src/parser/parser.ts | 77 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 134 insertions(+), 30 deletions(-) create mode 100644 src/parser/instruction.ts create mode 100644 src/parser/parameter.ts create mode 100644 src/parser/parser.ts diff --git a/examples/test.gs b/examples/test.gs index 7c0d49b..1b5f447 100644 --- a/examples/test.gs +++ b/examples/test.gs @@ -1,3 +1,2 @@ -point(3 | 4) - -point(6 | 7) \ No newline at end of file +point(3, 4) -> A +line(A, point(7, 8)) \ No newline at end of file diff --git a/src/geometry.ts b/src/geometry.ts index 63f76b6..7443bb0 100644 --- a/src/geometry.ts +++ b/src/geometry.ts @@ -1,5 +1,6 @@ /// /// +/// function loadScript(filepath: string): string { @@ -32,33 +33,7 @@ class Geometry extends HTMLElement let sourceFile = this.getAttribute("src"); let content = loadScript(sourceFile); - let lines = content.split("\n"); - for(let line of lines) - { - if(line === "\r") - { - console.log("empty"); - continue; - } - - let instruction = line.split("(")[0]; - - switch(instruction) - { - case instruction: - { - let coords = line.split("(")[1].split("|"); - console.log(coords); - break; - } - - default: - { - console.log("something else"); - break; - } - } - } + let parser = new Parser(content); this.attachShadow({mode: "open"}); let canvas = document.createElement("canvas"); diff --git a/src/parser/instruction.ts b/src/parser/instruction.ts new file mode 100644 index 0000000..1a381f6 --- /dev/null +++ b/src/parser/instruction.ts @@ -0,0 +1,18 @@ +enum InstructionType +{ + Point, + Line, + Circle +} + +class Instruction +{ + public fn: InstructionType; + public params :Parameter[]; + + constructor(type: InstructionType) + { + this.fn = type; + this.params = []; + } +} \ No newline at end of file diff --git a/src/parser/parameter.ts b/src/parser/parameter.ts new file mode 100644 index 0000000..ec2fd56 --- /dev/null +++ b/src/parser/parameter.ts @@ -0,0 +1,35 @@ +enum ParameterType +{ + Instruction, + Identifier, + Number +} + +abstract class Parameter +{ + public type: ParameterType; + + constructor(type: ParameterType) + { + this.type = type; + } + + abstract eval(); +} + +class NumberParameter extends Parameter +{ + public val: number; + + constructor(val: number) + { + super(ParameterType.Number); + + this.val = val; + } + + eval() + { + return this.val; + } +} diff --git a/src/parser/parser.ts b/src/parser/parser.ts new file mode 100644 index 0000000..9f10096 --- /dev/null +++ b/src/parser/parser.ts @@ -0,0 +1,77 @@ +/// +/// + +class Parser +{ + private instructions: Instruction[]; + + constructor(source: string) + { + this.instructions = []; + let lines = source.split(/\r?\n/); + for(let line of lines) + this.parseInstruction(line); + } + + private parseInstruction(instruction: string): boolean + { + // If the instruction is an empty line, do nothing for now + if(instruction === "") + return false; + + // match the pattern "text(text)" + let matches = instruction.match(/[A-Za-z]*\(.*\)/); + if(matches === null) // no match found + { + console.error("Invalid syntax"); + return false; + } + + if(matches.length > 1) // more than one match + { + console.error("Script may only contain one instruction per line"); + return false; + } + + let instr = matches[0]; // get the instruction + instr = instr.split(" ").join(""); + let paranthesisPos = instr.search(/\(/); // Find the position of the first opening paranthesis + + + let symbol = instr.substr(0, paranthesisPos); // get function name + let paramlist = instr.substring(paranthesisPos + 1, instr.length - 1); // get parameter list + + let match; + let params = []; + while((match = paramlist.search(/,(?![^\(]*\))/)) !== -1) + { + params.push(paramlist.substring(0, match)); + paramlist = paramlist.substring(match + 1, paramlist.length); + } + params.push(paramlist); + + this.instructions.push(new Instruction(InstructionType.Point)); + for(let param of params) + { + if(!this.parseParameter(param)) + { + console.error("Error during parameter parsing"); + return false; + } + } + + return true; + } + + private parseParameter(parameter: string): boolean + { + let match = parameter.search(/\d*\.?\d*$/); + if(match === 0) + { + this.instructions[this.instructions.length - 1].params.push(new NumberParameter(4)); + return true; + } + + return false; + } +}