sbis3-node-ws
Version:
Модуль позволяет использовать ядро интерфейсного фреймворка sbis3-ws(`core.js`) и модуль работы с данными (`Source.js`) в приложении на nodejs.
216 lines • 9.69 kB
JavaScript
define('js!Core/tmpl/js/helpers/expressions',
[
'js!Core/tmpl/js/helpers/utils',
'js!Core/tmpl/js/helpers/calculator',
'js!Core/tmpl/js/helpers/decorators',
'js!Core/tmpl/js/helpers/scopes',
'js!Core/tmpl/js/helpers/errorHandling'
], function (utils, calc, decorators, scopes, errorHandling) {
'use strict';
var findCalculator = function findCalculator(calculators, scope) {
var calculator = calc;
for (var i=0; i < calculators.length; i++) {
if (calculators[i].is(scope)) {
calculator = calculators[i].calculator;
break;
}
}
return calculator;
};
var expressions = {
'Identifier': function IdentifierCaller(node, data) {
var val,
scope = scopes.executeScope(node.name, data),
calculator = findCalculator(this.calculators, scope);
val = calculator(node.name, scope);
node.value = val;
return val;
},
'ExpressionStatement': function ExpressionStatementCaller(node, data) {
var expr = this[node.expression.type](node.expression, data);
node.value = expr;
return expr;
},
'LogicalExpression': function LogicalExpressionCaller(node, data) {
var left = this[node.left.type](node.left, data),
right = this[node.right.type](node.right, data),
exprString = left + ' ' + node + ' ' + right,
val = logicalExpressionTypes(node.operator, left, right);
function logicalExpressionTypes(operator, left, right) {
if (operator) {
switch (operator) {
case '||':
return left || right;
case '&&':
return left && right;
default:
errorHandling('Wrong conditional expression ' + exprString, this.filename);
}
}
errorHandling('Wrong conditional expression ' + exprString, this.filename);
}
node.value = val;
return val;
},
'Literal': function LiteralNodeCaller(node) {
return node.value;
},
'MemberExpression': function MemberExpressionNodeCaller(node, data) {
var val, onObject = this[node.object.type](node.object, data), calc;
if (node.property) {
if (onObject) {
if (node.computed) {
calc = findCalculator(this.calculators, onObject);
if (node.property.type !== 'Literal') {
val = calc(this[node.property.type](node.property, data), onObject);
} else {
val = calc(this[node.property.type](node.property), onObject);
}
} else {
val = this[node.property.type](node.property, onObject);
}
}
} else {
val = onObject;
}
node.value = val;
return val;
},
'ConditionalExpression': function ConditionalExpressionNodeCaller(node, data) {
var alternate = (node.alternate !== undefined) ? this[node.alternate.type](node.alternate, data) : undefined,
val;
val = this[node.test.type](node.test, data) ? this[node.consequent.type](node.consequent, data) : alternate;
node.value = val;
return val;
},
'CallExpression': function CallExpressionCaller(node, data) {
var callee = this[node.callee.type](node.callee, data),
val,
mapFn = function mapArgs(value) {
return this[value.type](value, data);
};
if (callee) {
if (node.callee.object) {
val = callee.apply(node.callee.object.value, utils.mapForLoop(node.arguments, mapFn.bind(this)))
} else {
val = callee.apply(data, utils.mapForLoop(node.arguments, mapFn.bind(this)));
}
node.value = val;
return val;
}
errorHandling('Call expression error. Object to call on is "' + node.callee.string + '" equals to ' + callee, this.filename);
},
'BinaryExpression': function BinaryExpressionCaller(node, data) {
var val = binaryExpressionTypes(node.operator, this[node.left.type](node.left, data), this[node.right.type](node.right, data));
node.value = val;
function binaryExpressionTypes(operator, left, right) {
if (operator) {
switch (operator) {
case '*':
return left * right;
case '/':
return left / right;
case '%':
return left % right;
case '+':
return left + right;
case '-':
return left - right;
case '<':
return left < right;
case '>':
return left > right;
case '<=':
return left <= right;
case '>=':
return left >= right;
case '==':
return left == right;
case '!=':
return left != right;
case '===':
return left === right;
case '!==':
return left !== right;
default:
errorHandling('Wrong binary expression ' + left + ' ' + operator + ' ' + right, this.filename);
}
}
errorHandling('Wrong binary expression ' + left + ' ' + operator + ' ' + right, this.filename);
}
return val;
},
'DecoratorChainCall': function DecoratorChainCallCaller(node, data, caller, nodecaller) {
if (decorators[node.identifier]) {
var decArgs = utils.mapForLoop(node.argumentsDecorator || [], function decArgsMap(value) {
return this[value.type](value, data);
}.bind(this)), val;
if (node.identifier === 'trace') {
decArgs.unshift(nodecaller.string);
}
decArgs.unshift(caller);
val = decorators[node.identifier].apply(undefined, decArgs);
node.value = val;
return val;
}
errorHandling('There is no decorator with such name: "' + node.identifier + '". Called on expression: ' + (nodecaller ? nodecaller.string : nodecaller ), this.filename);
},
'DecoratorChainContext': function DecoratorChainContextCaller(node, data, caller, nodecaller) {
var val;
if (node.entity) {
val = this[node.fn.type](node.fn, data, this[node.entity.type](node.entity, data, caller, nodecaller), nodecaller);
} else {
val = this[node.fn.type](node.fn, data, caller, nodecaller);
}
node.value = val;
return val;
},
'DecoratorCall': function DecoratorCallCaller(node, data) {
var val = this[node.decorator.type](node.decorator, data, (node.caller ? this[node.caller.type](node.caller, data) : undefined), node.caller);
node.value = val;
return val;
},
'UnaryExpression': function UnaryExpressionCaller(node, data) {
var val = unaryExpressionTypes(node.operator, this[node.argument.type](node.argument, data));
node.value = val;
function unaryExpressionTypes(operator, argument) {
if (operator) {
switch (operator) {
case '+':
return +argument;
case '-':
return -argument;
case '!':
return !argument;
default:
errorHandling('Wrong unary expression ' + operator + argument, this.filename);
}
}
errorHandling('Wrong unary expression ' + operator + argument, this.filename);
}
return val;
},
'ArrayExpression': function ArrayExpressionNodeCaller(node, data) {
var val = utils.mapForLoop(node.elements, function ArrayExpressionNodeMap(value) {
return this[value.type](value, data);
}.bind(this)) || [];
node.value = val;
return val;
},
'ObjectExpression': function ObjectExpressionNodeCaller(node, data) {
var obj = {}, massArr = utils.mapForLoop(node.properties, function ObjectExpressionNodeMap(value) {
var key = this[value.key.type](value.key, data);
if (key) {
obj[key] = this[value.value.type](value.value, data);
}
}.bind(this)) || {};
node.value = obj;
return obj;
},
'EmptyStatement': function EmptyStatementNodeCaller(node, data) {
node.value = undefined;
return;
}
};
return expressions;
});