silphius/app/astride/evaluators/binary.js
2024-06-30 11:18:26 -05:00

49 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 {
async: false,
value: binary(left.value, right.value),
};
}