UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

138 lines (116 loc) 5.17 kB
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); } }