eval method
Decimal?
eval()
Evaluates the expression.
Returns the result of the expression. Trailing zeros are stripped.
Implementation
Decimal? eval() {
ListQueue<LazyNumber> stack = ListQueue();
for (final Token token in getRPN()) {
switch (token.type) {
case TokenType.unaryOperator:
{
final LazyNumber value = stack.removeFirst();
LazyNumber result = new LazyNumberImpl(eval: () {
return operators[token.surface]?.evalLazy(value, null).eval();
}, getString: () {
return operators[token.surface]
?.evalLazy(value, null)
.eval()
.toString();
});
stack.addFirst(result);
break;
}
case TokenType.operator:
if (operators[token.surface]!.isUnaryOperator()) {
LazyNumber value = stack.removeFirst();
LazyNumberImpl result = new LazyNumberImpl(eval: () {
return operators[token.surface]!.evalLazy(value, null).eval();
}, getString: () {
return operators[token.surface]!
.evalLazy(value, null)
.eval()
.toString();
});
stack.addFirst(result);
} else {
final LazyNumber v1 = stack.removeFirst();
final LazyNumber v2 = stack.removeFirst();
LazyNumber result = new LazyNumberImpl(eval: () {
return operators[token.surface]?.evalLazy(v2, v1).eval();
}, getString: () {
return operators[token.surface]
?.evalLazy(v2, v1)
.eval()
.toString();
});
stack.addFirst(result);
}
break;
case TokenType.variable:
if (!variables.containsKey(token.surface)) {
throw new ExpressionException(
"Unknown operator or function: " + token.toString());
}
stack.addFirst(LazyNumberImpl(eval: () {
LazyNumber? lazyVariable = variables[token.surface];
Decimal? value = lazyVariable == null ? null : lazyVariable.eval();
return value;
}, getString: () {
LazyNumber? lazyVariable = variables[token.surface];
return lazyVariable?.getString();
}));
break;
case TokenType.function:
ILazyFunction f = functions[token.surface.toUpperCase()]!;
List<LazyNumber> p = [];
// pop parameters off the stack until we hit the start of
// this function's parameter list
while (!stack.isEmpty && stack.first != _paramsStart) {
p.insert(0, stack.removeFirst());
}
if (stack.first == _paramsStart) {
stack.removeFirst();
}
LazyNumber? fResult = f.lazyEval(p);
stack.addFirst(fResult);
break;
case TokenType.openParen:
stack.addFirst(_paramsStart);
break;
case TokenType.literal:
stack.addFirst(LazyNumberImpl(eval: () {
if (token.surface.toLowerCase() == "null") {
return null;
}
return Decimal.parse(token.surface);
}, getString: () {
return Decimal.parse(token.surface).toString();
}));
break;
case TokenType.stringParam:
stack.addFirst(LazyNumberImpl(eval: () {
return null;
}, getString: () {
return token.surface;
}));
break;
case TokenType.hexLiteral:
stack.addFirst(LazyNumberImpl(eval: () {
BigInt bigInt = BigInt.parse(token.surface.substring(2), radix: 16);
return Decimal.parse(bigInt.toString());
}, getString: () {
BigInt bigInt = BigInt.parse(token.surface.substring(2), radix: 16);
return Decimal.parse(bigInt.toString()).toString();
}));
break;
default:
throw new ExpressionException.pos(
"Unexpected token " + token.surface, token.pos);
}
}
Decimal? result = stack.removeFirst().eval();
if (result == null) {
return null;
}
// if (stripTrailingZeros) {
// result = result.stripTrailingZeros();
// }
return result;
}