added functions to parser
This commit is contained in:
parent
79c54f3c0d
commit
01165d43fb
5 changed files with 91 additions and 11 deletions
|
@ -1,2 +1,9 @@
|
||||||
[point(3, 4) -> A]
|
point(0.2378, -34.389) -> A
|
||||||
line(A, point(7, 8))
|
point(2.5, 0) -> B
|
||||||
|
[point(-1, 3) -> C]
|
||||||
|
|
||||||
|
line(A, B) -> AB
|
||||||
|
line(B, C)
|
||||||
|
line(C, A)
|
||||||
|
|
||||||
|
circle(A, len(AB))
|
9
examples/test.gs.disable
Normal file
9
examples/test.gs.disable
Normal file
|
@ -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)
|
9
src/doc/todo.md
Normal file
9
src/doc/todo.md
Normal file
|
@ -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
|
|
@ -4,28 +4,32 @@ enum InstructionType
|
||||||
{
|
{
|
||||||
Point,
|
Point,
|
||||||
Line,
|
Line,
|
||||||
Circle
|
Circle,
|
||||||
|
Length
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Instruction
|
abstract class Instruction
|
||||||
{
|
{
|
||||||
public fn: InstructionType;
|
public fn: InstructionType;
|
||||||
public params :Parameter[];
|
public params :Parameter[];
|
||||||
|
private argc: number;
|
||||||
|
|
||||||
constructor(type: InstructionType)
|
constructor(type: InstructionType, argc: number)
|
||||||
{
|
{
|
||||||
this.fn = type;
|
this.fn = type;
|
||||||
|
this.argc = argc;
|
||||||
this.params = [];
|
this.params = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract eval();
|
abstract eval();
|
||||||
|
public getParameterCount(): number { return this.argc; }
|
||||||
}
|
}
|
||||||
|
|
||||||
class PointInstruction extends Instruction
|
class PointInstruction extends Instruction
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
super(InstructionType.Point);
|
super(InstructionType.Point, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
eval()
|
eval()
|
||||||
|
@ -38,7 +42,7 @@ class LineInstruction extends Instruction
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
super(InstructionType.Line);
|
super(InstructionType.Line, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
eval()
|
eval()
|
||||||
|
@ -49,3 +53,35 @@ class LineInstruction extends Instruction
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ class Parser
|
||||||
for(let line of lines)
|
for(let line of lines)
|
||||||
{
|
{
|
||||||
let instr = this.parseInstruction(line);
|
let instr = this.parseInstruction(line);
|
||||||
|
if(instr !== null)
|
||||||
if(!instr[0])
|
if(!instr[0])
|
||||||
this.instructions.push(instr[1]);
|
this.instructions.push(instr[1]);
|
||||||
}
|
}
|
||||||
|
@ -80,6 +81,18 @@ class Parser
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "circle":
|
||||||
|
{
|
||||||
|
newInstruction = new CircleInstruction();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "len":
|
||||||
|
{
|
||||||
|
newInstruction = new LengthInstruction();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
console.error("Unknown instruction \"" + symbol + "\"");
|
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)
|
for(let param of params)
|
||||||
{
|
{
|
||||||
if(!this.parseParameter(newInstruction, param))
|
if(!this.parseParameter(newInstruction, param))
|
||||||
|
@ -100,7 +120,6 @@ class Parser
|
||||||
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.variables)
|
||||||
{
|
{
|
||||||
console.error("Redefinition of variable \"" + variableName + "\" is not allowed.");
|
console.error("Redefinition of variable \"" + variableName + "\" is not allowed.");
|
||||||
|
@ -115,7 +134,7 @@ class Parser
|
||||||
|
|
||||||
private parseParameter(instr: Instruction, parameter: string): boolean
|
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)
|
if(match !== null && match[0] === parameter && match.index === 0)
|
||||||
{
|
{
|
||||||
let val = parseFloat(parameter);
|
let val = parseFloat(parameter);
|
||||||
|
@ -125,7 +144,7 @@ class Parser
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
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.variables[parameter];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue