rpnToComputable function
Computable
rpnToComputable(
- List<
Token< tokens, {TokenType> > - ComputeContext context = const DefaultComputeContext(),
Collapses the RPN into a tree of computable expressions.
Implementation
Computable rpnToComputable(List<Token> tokens,
{ComputeContext context = const DefaultComputeContext()}) {
if (tokens.isEmpty) {
return Result.zero();
}
final List<Computable> stack = [];
for (final token in tokens) {
_log.finest('Current token: $token Stack: $stack');
if (token is OperatorToken) {
if (stack.isEmpty) {
throw ComputationError(ComputationStep.eval,
message: "Tried to use operator ${token.rawValue} but no operands",
globalPosition: token.globalOffset);
}
final rightHand = stack.removeLast();
final Computable leftHand;
if (stack.isEmpty) {
leftHand = Result.zero();
} else {
leftHand = stack.removeLast();
}
stack.add(Expression(
operator: token.operator, leftHand: leftHand, rightHand: rightHand));
} else if (token is ModifierToken) {
stack.add(token.modifier.modify(stack.removeLast().compute(context)));
} else if (token is FunctionToken) {
final arguments = List.generate(token.function.requiredParameterCount,
(index) => stack.removeLast().compute(context));
stack.add(token.function.compute(context, arguments));
} else {
stack.add(token);
}
}
return stack.singleOrNull ?? tokens.single.compute(context);
}