UNPKG

expression-evaluation

Version:
424 lines (423 loc) 17.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ParserState = void 0; const ParserFrame_js_1 = require("./ParserFrame.js"); const FunctionDefinition_js_1 = require("./FunctionDefinition.js"); const GlobalFunctions_js_1 = require("./function/GlobalFunctions.js"); const BaseFunctions_js_1 = require("./function/BaseFunctions.js"); const CompositeFunctions_js_1 = require("./function/CompositeFunctions.js"); const MathFunctions_js_1 = require("./function/MathFunctions.js"); const MutationFunctions_js_1 = require("./function/MutationFunctions.js"); const Type_js_1 = require("./Type.js"); class Literal { value; constructor(value) { this.value = value; } } const valueTrue = new Literal(true); const valueFalse = new Literal(false); const valueNull = new Literal(undefined); class Assignment { operator; constructor(operator) { this.operator = operator; } } const funcAssignment = new Assignment(); const funcOrAssignment = new Assignment(GlobalFunctions_js_1.funcOr); const funcAndAssignment = new Assignment(GlobalFunctions_js_1.funcAnd); const funcAddAssignment = new Assignment(MathFunctions_js_1.funcAdd); const funcSubtractAssignment = new Assignment(MathFunctions_js_1.funcSubtract); const funcMultiplyAssignment = new Assignment(MathFunctions_js_1.funcMultiply); const funcDivideAssignment = new Assignment(MathFunctions_js_1.funcDivide); const funcRemainderAssignment = new Assignment(MathFunctions_js_1.funcRemainder); const symbolParenthesesOpen = Symbol(); const symbolParenthesesClose = Symbol(); const symbolBracketsOpen = Symbol(); const symbolBracketsClose = Symbol(); const symbolBracesOpen = Symbol(); const symbolBracesClose = Symbol(); const symbolColonSeparator = Symbol(); const symbolCommaSeparator = Symbol(); const symbolOptionalType = Symbol(); const symbolScope = Symbol(); const symbolCycle = Symbol(); const isSign = (c) => c === '+' || c === '-'; const isAlpha = (c) => c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '_'; const isNumeric = (c) => c >= '0' && c <= '9'; const isAlphanumeric = (c) => isAlpha(c) || isNumeric(c); const isHexadecimal = (c) => isNumeric(c) || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F'; const isQuotation = (c) => c === '\'' || c === '"' || c === '`'; class ParserState extends ParserFrame_js_1.ParserFrame { _fragment; constructor(expr) { super(expr); } get literalValue() { return this._fragment.value; } get assignmentOperator() { return this._fragment.operator; } get operator() { return this._fragment; } get type() { return this._fragment; } get token() { return this._fragment; } get isOperator() { return this._fragment instanceof FunctionDefinition_js_1.FunctionDefinition; } get isLiteral() { return this._fragment instanceof Literal; } get isAssignment() { return this._fragment instanceof Assignment; } get isType() { return this._fragment instanceof Type_js_1.Type; } get isToken() { return typeof this._fragment === 'string'; } get isParenthesesOpen() { return this._fragment === symbolParenthesesOpen; } get isParenthesesClose() { return this._fragment === symbolParenthesesClose; } get isBracketsOpen() { return this._fragment === symbolBracketsOpen; } get isBracketsClose() { return this._fragment === symbolBracketsClose; } get isBracesOpen() { return this._fragment === symbolBracesOpen; } get isBracesClose() { return this._fragment === symbolBracesClose; } get isColonSeparator() { return this._fragment === symbolColonSeparator; } get isCommaSeparator() { return this._fragment === symbolCommaSeparator; } get isOptionalType() { return this._fragment === symbolOptionalType; } get isScope() { return this._fragment === symbolScope; } get isCycle() { return this._fragment === symbolCycle; } get isVoid() { return this._fragment == null; } clone() { const state = new ParserState(this._expr); state._start = this._start; state._end = this._end; state._fragment = this._fragment; return state; } next() { this._fragment = undefined; while (this._end < this._expr.length && this._fragment == null) { this._start = this._end; const c = this._expr.charAt(this._end); ++this._end; switch (c) { case ' ': case '\t': case '\n': case '\r': break; case '(': this._fragment = symbolParenthesesOpen; break; case ')': this._fragment = symbolParenthesesClose; break; case '[': this._fragment = symbolBracketsOpen; break; case ']': this._fragment = symbolBracketsClose; break; case '{': this._fragment = symbolBracesOpen; break; case '}': this._fragment = symbolBracesClose; break; case ':': this._fragment = symbolColonSeparator; break; case ',': this._fragment = symbolCommaSeparator; break; case '@': this._fragment = symbolCycle; break; case '?': switch (this._expr.charAt(this._end)) { case '?': ++this._end; this._fragment = Type_js_1.typeUnknown; break; case ':': ++this._end; this._fragment = BaseFunctions_js_1.funcCoalesce; break; default: this._fragment = symbolOptionalType; break; } break; case '$': this._fragment = BaseFunctions_js_1.funcSwitch; break; case '|': switch (this._expr.charAt(this._end)) { case '=': ++this._end; this._fragment = funcOrAssignment; break; default: this._fragment = GlobalFunctions_js_1.funcOr; break; } break; case '&': switch (this._expr.charAt(this._end)) { case '=': ++this._end; this._fragment = funcAndAssignment; break; default: this._fragment = GlobalFunctions_js_1.funcAnd; break; } break; case '>': switch (this._expr.charAt(this._end)) { case '=': ++this._end; this._fragment = BaseFunctions_js_1.funcGreaterOrEqual; break; default: this._fragment = BaseFunctions_js_1.funcGreaterThan; break; } break; case '<': switch (this._expr.charAt(this._end)) { case '=': ++this._end; this._fragment = BaseFunctions_js_1.funcLessOrEqual; break; default: this._fragment = BaseFunctions_js_1.funcLessThan; break; } break; case '!': switch (this._expr.charAt(this._end)) { case '=': ++this._end; this._fragment = BaseFunctions_js_1.funcNotEqual; break; default: this._fragment = GlobalFunctions_js_1.funcNot; break; } break; case '=': switch (this._expr.charAt(this._end)) { case '=': ++this._end; this._fragment = BaseFunctions_js_1.funcEqual; break; default: this._fragment = funcAssignment; break; } break; case '+': switch (this._expr.charAt(this._end)) { case '>': ++this._end; this._fragment = CompositeFunctions_js_1.funcAppend; break; case '=': ++this._end; this._fragment = funcAddAssignment; break; default: this._fragment = MathFunctions_js_1.funcAdd; break; } break; case '-': switch (this._expr.charAt(this._end)) { case '>': ++this._end; this._fragment = symbolScope; break; case '=': ++this._end; this._fragment = funcSubtractAssignment; break; default: this._fragment = MathFunctions_js_1.funcSubtract; break; } break; case '*': switch (this._expr.charAt(this._end)) { case '=': ++this._end; this._fragment = funcMultiplyAssignment; break; default: this._fragment = MathFunctions_js_1.funcMultiply; break; } break; case '/': switch (this._expr.charAt(this._end)) { case '=': ++this._end; this._fragment = funcDivideAssignment; break; default: this._fragment = MathFunctions_js_1.funcDivide; break; } break; case '%': switch (this._expr.charAt(this._end)) { case '=': ++this._end; this._fragment = funcRemainderAssignment; break; default: this._fragment = MathFunctions_js_1.funcRemainder; break; } break; case '^': this._fragment = MathFunctions_js_1.funcPower; break; case '.': this._fragment = CompositeFunctions_js_1.funcAt; break; case '#': while (isHexadecimal(this._expr.charAt(this._end))) { ++this._end; } this._fragment = new Literal(this._expr.charAt(this._end) === '#' ? (0, MutationFunctions_js_1.parseBuffer)(this._expr.substring(this._start + 1, this._end++)) : parseInt(this._expr.substring(this._start + 1, this._end), 16)); break; default: if (isAlpha(c)) { while (isAlphanumeric(this._expr.charAt(this._end))) { ++this._end; } const token = this._expr.substring(this._start, this._end); switch (token) { case 'true': this._fragment = valueTrue; break; case 'false': this._fragment = valueFalse; break; case 'null': this._fragment = valueNull; break; case 'void': this._fragment = Type_js_1.typeVoid; break; case 'boolean': this._fragment = Type_js_1.typeBoolean; break; case 'number': this._fragment = Type_js_1.typeNumber; break; case 'buffer': this._fragment = Type_js_1.typeBuffer; break; case 'string': this._fragment = Type_js_1.typeString; break; case 'array': this._fragment = Type_js_1.typeArray; break; case 'object': this._fragment = Type_js_1.typeObject; break; case 'function': this._fragment = Type_js_1.typeFunction; break; default: this._fragment = token; break; } } else if (isNumeric(c)) { while (isNumeric(this._expr.charAt(this._end))) { ++this._end; } if (this._expr.charAt(this._end) === '.') { ++this._end; if (isNumeric(this._expr.charAt(this._end))) { ++this._end; while (isNumeric(this._expr.charAt(this._end))) { ++this._end; } } else { --this._end; } } if (this._expr.charAt(this._end) === 'e') { ++this._end; if (isNumeric(this._expr.charAt(this._end)) || isSign(this._expr.charAt(this._end))) { ++this._end; while (isNumeric(this._expr.charAt(this._end))) { ++this._end; } } } this._fragment = new Literal(parseFloat(this._expr.substring(this._start, this._end))); } else if (isQuotation(c)) { while (this._expr.charAt(this._end) !== '' && this._expr.charAt(this._end) !== c) { ++this._end; } if (this._end >= this._expr.length) { this._start = this._expr.length; throw new Error(`missing closing quotation mark ${c}`); } this._fragment = new Literal(this._expr.substring(this._start + 1, this._end++)); } else { throw new Error(`unknown symbol ${c}`); } break; } } if (this._end > this._expr.length) { this._start = this._end = this._expr.length; } return this; } } exports.ParserState = ParserState;