@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
138 lines (116 loc) • 5.17 kB
JavaScript
import { assert } from "../../../assert.js";
import { ReactiveAdd } from "../../../model/reactive/model/arithmetic/ReactiveAdd.js";
import { ReactiveDivide } from "../../../model/reactive/model/arithmetic/ReactiveDivide.js";
import { ReactiveMultiply } from "../../../model/reactive/model/arithmetic/ReactiveMultiply.js";
import { ReactiveNegate } from "../../../model/reactive/model/arithmetic/ReactiveNegate.js";
import { ReactiveSubtract } from "../../../model/reactive/model/arithmetic/ReactiveSubtract.js";
import { ReactiveEquals } from "../../../model/reactive/model/comparative/ReactiveEquals.js";
import { ReactiveGreaterThan } from "../../../model/reactive/model/comparative/ReactiveGreaterThan.js";
import { ReactiveGreaterThanOrEqual } from "../../../model/reactive/model/comparative/ReactiveGreaterThanOrEqual.js";
import { ReactiveLessThan } from "../../../model/reactive/model/comparative/ReactiveLessThan.js";
import { ReactiveLessThanOrEqual } from "../../../model/reactive/model/comparative/ReactiveLessThanOrEqual.js";
import { ReactiveNotEquals } from "../../../model/reactive/model/comparative/ReactiveNotEquals.js";
import { ReactiveAnd } from "../../../model/reactive/model/logic/ReactiveAnd.js";
import { ReactiveNot } from "../../../model/reactive/model/logic/ReactiveNot.js";
import { ReactiveOr } from "../../../model/reactive/model/logic/ReactiveOr.js";
import { ReactiveLiteralBoolean } from "../../../model/reactive/model/terminal/ReactiveLiteralBoolean.js";
import { ReactiveLiteralNumber } from "../../../model/reactive/model/terminal/ReactiveLiteralNumber.js";
import { ReactiveLiteralString } from "../../../model/reactive/model/terminal/ReactiveLiteralString.js";
import { ReactiveReference } from "../../../model/reactive/model/terminal/ReactiveReference.js";
const Compiler_Types = {
BinaryExpression(node) {
const l = compile(node.left);
const r = compile(node.right);
const operator = node.operator;
if (operator === "&&") {
return ReactiveAnd.from(l, r);
} else if (operator === "||") {
return ReactiveOr.from(l, r);
} else if (operator === "+") {
return ReactiveAdd.from(l, r);
} else if (operator === "-") {
return ReactiveSubtract.from(l, r);
} else if (operator === "*") {
return ReactiveMultiply.from(l, r);
} else if (operator === "/") {
return ReactiveDivide.from(l, r);
} else if (operator === "==") {
return ReactiveEquals.from(l, r);
} else if (operator === "!=") {
return ReactiveNotEquals.from(l, r);
} else if (operator === ">") {
return ReactiveGreaterThan.from(l, r);
} else if (operator === ">=") {
return ReactiveGreaterThanOrEqual.from(l, r);
} else if (operator === "<") {
return ReactiveLessThan.from(l, r);
} else if (operator === "<=") {
return ReactiveLessThanOrEqual.from(l, r);
} else {
throw new Error(`Unsupported binary expression operator '${operator}'`);
}
},
UnaryExpression(node) {
const source = compile(node.argument);
const operator = node.operator;
if (operator === '!') {
return ReactiveNot.from(source);
} else if (operator === '-') {
return ReactiveNegate.from(source);
} else {
throw new Error(`Unsupported unary expression operator '${operator}'`);
}
},
Reference(node) {
const names = [];
const path = node.path;
const n = path.length;
for (let i = 0; i < n; i++) {
const identifier = path[i];
names.push(identifier.name);
}
return new ReactiveReference(names.join('.'));
},
/**
*
* @param {{value:(number|string|boolean)}} node
* @returns {ReactiveLiteralString|ReactiveLiteralNumber|ReactiveLiteralBoolean}
* @constructor
*/
Literal(node) {
const value = node.value;
const t = typeof value;
if (t === "number") {
return ReactiveLiteralNumber.from(value);
} else if (t === "boolean") {
return ReactiveLiteralBoolean.from(value);
} else if (t === "string") {
return ReactiveLiteralString.from(value);
} else {
throw new Error(`Unsupported literal type '${t}'`);
}
}
};
/**
*
* @param {{type:string}} node
*/
function compile(node) {
const node_type = node.type;
assert.isString(node_type, 'node.type');
const type_compiler = Compiler_Types[node_type];
if (type_compiler === undefined) {
throw new Error(`Unsupported node type '${node_type}'`);
}
return type_compiler(node);
}
export class ReactivePegCompiler {
/**
*
* @param {Object} syntaxTree
* @returns {ReactiveExpression}
*/
static compile(syntaxTree) {
return compile(syntaxTree);
}
}