Evaluators
Normally you run metaesEval
in the following way:
metaesEval("2+a", console.log, console.error); // Error
What we already know is to fix the missing a
you can provide extra environment value:
metaesEval("2+a", console.log, console.error, { a: 2 }); // 4
But, what if we want to delay a
dereferencing util a
is hit in the runtime? We'd want use custom Identifier
evaluator, meaning we want to tell metaES how to resolve variables in non-standard way. Maybe that interpreter would reach over HTTP, WebSocket etc. and this would take uknown amount of time? It can be done with overriding interpreters
field in the config
:
const evaluators = createEnvironment(
{
Identifier(e, c, cerr) {
c(44);
}
},
ECMAScriptEvaluators
);
metaesEval("var b=3; 2+a+b", console.log, console.error, { a: 2 }, { evaluators }); // result: 90
Few things to note:
evaluators
is anenvironment
,evaluators
environment has to reference at some point an outer environment which should beECMAScriptEvaluators
. This environment is provided by metaES itself and contains interpreters to interpret ECMAScript nodes. Otherwise metaES will just throwNotImplementedException
for rest of the nodes,- we actually broke
Indentifier
- it always returns 44, even if variable is defined.
Let's patch it:
const promised44 = () => Promise.resolve(44);
const evaluators = createEnvironment(
{
Identifier(e, c, cerr, env, config) {
ECMAScriptEvaluators.values.Identifier(e, c, (_) => promised44().then(c).catch(cerr), env, config);
}
},
ECMAScriptEvaluators
);
metaesEval("var b=3; 2+a+b", console.log, console.error, {}, { evaluators }); // 49
Identifier
first tries to reach variable in a standard way. When fails, it always falls back with promised44
- a Promise
that resolves for any value, in example it's always 44.
This solution is still not ideal - you need to use createEnvironmentOverriding
to make sure future configurations will be handled correctly, especially when there are multiple layers of overrides.