diff --git a/examples/test.gs b/examples/test.gs index fa68652..291c48a 100644 --- a/examples/test.gs +++ b/examples/test.gs @@ -1,2 +1,9 @@ -[point(3, 4) -> A] -line(A, point(7, 8)) \ No newline at end of file +point(0.2378, -34.389) -> A +point(2.5, 0) -> B +[point(-1, 3) -> C] + +line(A, B) -> AB +line(B, C) +line(C, A) + +circle(A, len(AB)) \ No newline at end of file diff --git a/examples/test.gs.disable b/examples/test.gs.disable new file mode 100644 index 0000000..8b2a065 --- /dev/null +++ b/examples/test.gs.disable @@ -0,0 +1,9 @@ +point(-1, 0) -> A +point(1, 0) -> B +line(A, B) -> AB +len(AB) -> length +circle(A, len(AB)) -> circleA +circle(B, len(AB)) -> circleB +intersection(circleA, circleB, 0) -> C +line(A, C) +line(B, C) diff --git a/src/doc/todo.md b/src/doc/todo.md new file mode 100644 index 0000000..e11c816 --- /dev/null +++ b/src/doc/todo.md @@ -0,0 +1,9 @@ +# TODO (Parser) +* Type checking +* Ignore case in instruction names +* Implement remaining functions +* Abort parsing on error + +# TODO (Renderer) +* Implement shape classes +* Render shape classes \ No newline at end of file diff --git a/src/parser/instruction.ts b/src/parser/instruction.ts index 67f49c6..d0ee0fd 100644 --- a/src/parser/instruction.ts +++ b/src/parser/instruction.ts @@ -4,28 +4,32 @@ enum InstructionType { Point, Line, - Circle + Circle, + Length } abstract class Instruction { public fn: InstructionType; public params :Parameter[]; + private argc: number; - constructor(type: InstructionType) + constructor(type: InstructionType, argc: number) { this.fn = type; + this.argc = argc; this.params = []; } abstract eval(); + public getParameterCount(): number { return this.argc; } } class PointInstruction extends Instruction { constructor() { - super(InstructionType.Point); + super(InstructionType.Point, 2); } eval() @@ -38,7 +42,7 @@ class LineInstruction extends Instruction { constructor() { - super(InstructionType.Line); + super(InstructionType.Line, 2); } eval() @@ -48,4 +52,36 @@ class LineInstruction extends Instruction this.params[1].eval() ]; } +} + +class CircleInstruction extends Instruction +{ + constructor() + { + super(InstructionType.Line, 2); + } + + eval() + { + return [ + this.params[0].eval(), + this.params[1].eval() + ]; + } +} + +class LengthInstruction extends Instruction +{ + constructor() + { + super(InstructionType.Line, 1); + } + + eval() + { + let line = this.params[0].eval(); + let dx = line[1].x - line[0].x; + let dy = line[1].y - line[0].y; + return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + } } \ No newline at end of file diff --git a/src/parser/parser.ts b/src/parser/parser.ts index 2a74445..ee57532 100644 --- a/src/parser/parser.ts +++ b/src/parser/parser.ts @@ -15,8 +15,9 @@ class Parser for(let line of lines) { let instr = this.parseInstruction(line); - if(!instr[0]) - this.instructions.push(instr[1]); + if(instr !== null) + if(!instr[0]) + this.instructions.push(instr[1]); } } @@ -80,6 +81,18 @@ class Parser break; } + case "circle": + { + newInstruction = new CircleInstruction(); + break; + } + + case "len": + { + newInstruction = new LengthInstruction(); + break; + } + default: { console.error("Unknown instruction \"" + symbol + "\""); @@ -87,6 +100,13 @@ class Parser } } + let expectedArgs = newInstruction.getParameterCount(); + if(expectedArgs !== params.length) + { + console.error("Wrong number of arguments for instruction \"" + symbol + "\". Expected " + expectedArgs + " arguments but received " + params.length + " instead."); + return null; + } + for(let param of params) { if(!this.parseParameter(newInstruction, param)) @@ -100,7 +120,6 @@ class Parser if(assignment !== -1) { let variableName = instruction.substring(assignment + 2, instruction.length); - if(variableName in this.variables) { console.error("Redefinition of variable \"" + variableName + "\" is not allowed."); @@ -115,7 +134,7 @@ class Parser private parseParameter(instr: Instruction, parameter: string): boolean { - let match = parameter.match(/\d*\.?\d*$/); + let match = parameter.match(/-?\d*\.?\d*$/); if(match !== null && match[0] === parameter && match.index === 0) { let val = parseFloat(parameter); @@ -125,7 +144,7 @@ class Parser return true; } - match = parameter.match(/[A-Za-z]/) + match = parameter.match(/[A-Za-z]*/) if(match !== null && match[0] === parameter && match.index === 0) { let paramObj = this.variables[parameter];