Files
DiceCloud/app/imports/api/engine/computation/computeComputation/computeCalculations.js
Stefan Zermatten cb1fd38df3 Optimized some slow parts of the engine.
Last low hanging fruit: parsing is slow, cache parsed calculations
2021-09-29 15:54:14 +02:00

51 lines
1.8 KiB
JavaScript

import { CompilationContext } from '/imports/parser/parser.js';
import INLINE_CALCULATION_REGEX from '/imports/constants/INLINE_CALCULTION_REGEX.js';
import ConstantNode from '/imports/parser/parseTree/ConstantNode.js';
import ErrorNode from '/imports/parser/parseTree/ErrorNode.js';
export default function computeCalculations(computation, node){
if (!node.data) return;
// evaluate all the calculations
node.data._computationDetails?.calculations?.forEach(calcObj => {
evaluateCalculation(calcObj, computation.scope)
});
node.data._computationDetails?.inlineCalculations?.forEach(inlineCalcObj => {
embedInlineCalculations(inlineCalcObj);
});
}
function evaluateCalculation(calculation, scope){
const context = new CompilationContext();
const parseNode = calculation._parsedCalculation;
const fn = calculation._parseLevel;
const calculationScope = {...calculation._localScope, ...scope};
const resultNode = parseNode[fn](calculationScope, context);
if (resultNode instanceof ConstantNode){
calculation.value = resultNode.value;
} else if (resultNode instanceof ErrorNode){
calculation.value = null;
} else {
calculation.value = resultNode.toString();
}
if (calculation.errors){
calculation.errors = [...calculation.errors, ...context.errors]
} else {
calculation.errors = context.errors
}
// remove the working fields
delete calculation._parseLevel;
delete calculation._parsedCalculation;
delete calculation._localScope;
}
function embedInlineCalculations(inlineCalcObj){
const string = inlineCalcObj.text;
const calculations = inlineCalcObj.inlineCalculations;
if (!string || !calculations) return;
let index = 0;
inlineCalcObj.value = string.replace(INLINE_CALCULATION_REGEX, substring => {
let calc = calculations[index++];
return (calc && 'value' in calc) ? calc.value : substring;
});
}