silphius/app/astride/evaluate.js
2024-06-22 10:47:17 -05:00

48 lines
1.6 KiB
JavaScript

const evaluators = Object.fromEntries(
Object.entries(
import.meta.glob(
['./evaluators/*.js', '!./evaluators/*.test.js'],
{eager: true, import: 'default'},
)
)
.map(([path, evaluator]) => ([
path.replace(/\.\/evaluators\/(.*)\.js/, '$1'),
evaluator,
])),
);
export default function evaluate(node, {scope} = {}) {
switch (node.type) {
case 'ArrayExpression':
return evaluators.array(node, {evaluate, scope});
case 'AssignmentExpression':
return evaluators.assignment(node, {evaluate, scope});
case 'AwaitExpression':
return evaluators.await(node, {evaluate, scope});
case 'BinaryExpression':
return evaluators.binary(node, {evaluate, scope});
case 'Literal':
return evaluators.literal(node, {evaluate, scope});
case 'CallExpression':
return evaluators.call(node, {evaluate, scope});
case 'ChainExpression':
return evaluate(node.expression, {evaluate, scope});
case 'ConditionalExpression':
return evaluators.conditional(node, {evaluate, scope});
case 'Identifier':
return evaluators.identifier(node, {evaluate, scope});
case 'LogicalExpression':
return evaluators.binary(node, {evaluate, scope});
case 'MemberExpression':
return evaluators.member(node, {evaluate, scope});
case 'ObjectExpression':
return evaluators.object(node, {evaluate, scope});
case 'UnaryExpression':
return evaluators.unary(node, {evaluate, scope});
case 'UpdateExpression':
return evaluators.update(node, {evaluate, scope});
default:
throw new EvalError(`astride: Can't evaluate node of type ${node.type}`)
}
}