53 lines
1.6 KiB
JavaScript
53 lines
1.6 KiB
JavaScript
import computeStat from '/imports/api/creature/computation/computeStat.js';
|
|
import { parse, CompilationContext } from '/imports/parser/parser.js';
|
|
import SymbolNode from '/imports/parser/parseTree/SymbolNode.js';
|
|
import AccessorNode from '/imports/parser/parseTree/AccessorNode.js';
|
|
import ConstantNode from '/imports/parser/parseTree/ConstantNode.js';
|
|
|
|
/* Convert a calculation into a constant output and errors*/
|
|
export default function evaluateCalculation(string, memo, fn = 'reduce'){
|
|
let dependencies = [];
|
|
let errors = [];
|
|
if (!string) return {
|
|
context: {errors},
|
|
result: new ConstantNode({value: string, type: 'string'}),
|
|
dependencies,
|
|
};
|
|
// Parse the string
|
|
let calc;
|
|
try {
|
|
calc = parse(string);
|
|
} catch (e) {
|
|
errors.push({
|
|
type: 'parsing',
|
|
message: e.message || e
|
|
});
|
|
return {
|
|
context: {errors},
|
|
result: new ConstantNode({value: string, type: 'string'}),
|
|
dependencies,
|
|
};
|
|
}
|
|
if (!calc){
|
|
return {
|
|
context: {errors},
|
|
result: new ConstantNode({value: calc, type: 'string'}),
|
|
dependencies,
|
|
};
|
|
}
|
|
// Ensure all symbol nodes are defined and computed
|
|
calc.traverse(node => {
|
|
if (node instanceof SymbolNode || node instanceof AccessorNode){
|
|
let stat = memo.statsByVariableName[node.name];
|
|
if (stat && !stat.computationDetails.computed){
|
|
computeStat(stat, memo);
|
|
}
|
|
if (stat) dependencies.push(stat._id || node.name, ...stat.dependencies);
|
|
}
|
|
});
|
|
// Evaluate
|
|
let context = new CompilationContext();
|
|
let result = calc[fn](memo.statsByVariableName, context);
|
|
return {result, context, dependencies};
|
|
}
|