UNPKG

mutants-appfx

Version:

appfx module

191 lines (182 loc) 5.34 kB
import { ExprListener } from './ExprListener'; import ExprException from './ExprException'; import DateUtil from './DateUtil'; import * as AggregatesUtil from './AggregatesUtil'; export default class ExprExecutor extends ExprListener { scope; result; constructor(scope) { super(); this.scope = scope || {}; } exitExec(ctx) { this.result = ctx.getChild(0).value; } // singleExpression ( ',' singleExpression )* exitExpressionSequence(ctx) { const value = [ctx.getChild(0).value]; for (let i = 2, l = ctx.getChildCount(); i < l; i += 2) { value.push(ctx.getChild(i).value); } ctx.value = value; } // '=' CONST* exitConstStringExpression(ctx){ ctx.value = ctx.getChild(1).getText(); } // singleExpression '.' ID '(' expressionSequence ')' exitFunctionInvokeExpression(ctx) { ctx.value = ctx.getChild(0).value[ctx.getChild(2).getText()].apply(ctx.getChild( 0).value, ctx.getChild(4).value); } // singleExpression '[' expressionSequence ']' exitMemberIndexExpression(ctx) { ctx.value = ctx.getChild(2).value.reduce((v,index)=>{ return v[index]; },ctx.getChild(0).value); } // singleExpression '.' ID exitMemberDotExpression(ctx) { if (!ctx.getChild(0).value){ return undefined; } ctx.value = ctx.getChild(0).value[ctx.getChild(2).getText()]; } // ( '~' | '!') singleExpression exitUnaryExpression(ctx) { const oper = ctx.getChild(0).getText(); if (oper === '~') { ctx.value = ~ctx.getChild(1).value; } else if (oper === '!') { ctx.value = !ctx.getChild(1).value; } else { throw new ExprException(`UnaryExpression operator ${oper} not support`); } } /* '*' | '/' | '%' | '+' | '-' | '<<' | '>>' | '>>>' | '<' | '>' | '<=' | '>=' | 'in' | '==' | '!=' | '===' | '!==' | '&' | '^' | '|' | '&&' '||' */ exitBinaryExpression(ctx) { const a = ctx.getChild(0).value; const b = ctx.getChild(2).value; const oper = ctx.getChild(1).getText(); if (oper === 'in') { ctx.value = a in b; } else if (oper === '*') { ctx.value = a * b; } else if (oper === '/') { ctx.value = a / b; } else if (oper === '%') { ctx.value = a % b; } else if (oper === '+') { ctx.value = a + b; } else if (oper === '-') { ctx.value = a - b; } else if (oper === '<<') { ctx.value = a << b; } else if (oper === '>>') { ctx.value = a >> b; } else if (oper === '>>>') { ctx.value = a >>> b; } else if (oper === '<') { ctx.value = a < b; } else if (oper === '>') { ctx.value = a > b; } else if (oper === '<=') { ctx.value = a <= b; } else if (oper === '>=') { ctx.value = a >= b; } else if (oper === '==') { ctx.value = a == b; } else if (oper === '!=') { ctx.value = a != b; } else if (oper === '===') { ctx.value = a === b; } else if (oper === '!==') { ctx.value = a !== b; } else if (oper === '&') { ctx.value = a & b; } else if (oper === '^') { ctx.value = a ^ b; } else if (oper === '|') { ctx.value = a | b; } else if (oper === '&&') { ctx.value = a && b; } else if (oper === '||') { ctx.value = a || b; } else { throw new ExprException(`BinaryExpression operator ${oper} not support`); } } // singleExpression '?' singleExpression ':' singleExpression exitTernaryExpression(ctx) { const condition = ctx.getChild(0); const success = ctx.getChild(2); const fail = ctx.getChild(4); if (condition.value) { ctx.value = success.value; } else { ctx.value = fail.value; } } exitInternalExpression(ctx) { const internalObj = ctx.getText(); if (internalObj === 'now') { ctx.value = new Date(); } else if (internalObj === 'Date') { ctx.value = DateUtil; } else if (internalObj === 'Math') { ctx.value = Math; } else if (internalObj === 'Aggs') { ctx.value = AggregatesUtil; } else { throw new ExprException(`InternalExpression ${internalObj} not support`); } } // value exitLiteralExpression(ctx) { // value左右可以有空格 ctx.value = new Function(`return ${ctx.getText().trim()}`)(); } // VARID exitIdentifierExpression(ctx) { ctx.value = this.scope[ctx.getText().substr(1)]; } // '(' expressionSequence ')' exitParenthesizedExpression(ctx) { ctx.value = ctx.getChild(1).value; } // objectLiteral exitObjectLiteralExpression(ctx) { ctx.value = ctx.getChild(0).value; } // '{' (propertyAssignment (',' propertyAssignment)*)? ','? '}' exitObjectPropertyAssignmentExpression(ctx) { const ps = []; for (let i = 1, l = ctx.getChildCount() - 1; i < l; i += 2) { ps.push(ctx.getChild(i).value); } ctx.value = Object.assign({}, ...ps); } // ID (':' |'=') singleExpression exitPropertyExpressionAssignment(ctx) { ctx.value = ctx.value || {}; ctx.value[ctx.getChild(0).getText()] = ctx.getChild(2).value; } // '[' singleExpression ']' ':' singleExpression exitComputedPropertyExpressionAssignment(ctx) { ctx.value = ctx.value || {}; ctx.value[ctx.getChild(1).value] = ctx.getChild(4).value; } exitConstString(ctx) { ctx.value = ctx.getText(); } }