46 lines
1.6 KiB
JavaScript
46 lines
1.6 KiB
JavaScript
export default function(node, {evaluate, scope}) {
|
|
const binary = (left, right) => {
|
|
switch (node.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 'in' : return left in 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;
|
|
case '!=' : return left != right;
|
|
case '||' : return left || right;
|
|
case '&&' : return left && right;
|
|
case '??' : return (left === null || left === undefined) ? right : left;
|
|
case 'instanceof': return left instanceof right;
|
|
/* v8 ignore next 2 */
|
|
default:
|
|
throw new Error(`operator not implemented: ${node.operator}`);
|
|
}
|
|
};
|
|
const left = evaluate(node.left, {scope});
|
|
const right = evaluate(node.right, {scope});
|
|
if (left.async || right.async) {
|
|
return {
|
|
async: true,
|
|
value: Promise
|
|
.all([left.value, right.value])
|
|
.then(([left, right]) => binary(left, right)),
|
|
};
|
|
}
|
|
return {value: binary(left.value, right.value)};
|
|
}
|