Skip to content

Instantly share code, notes, and snippets.

@iykekings
Created October 26, 2022 22:21
Show Gist options
  • Save iykekings/d9702c06f41116ffd1e620bf3c412a2c to your computer and use it in GitHub Desktop.
Save iykekings/d9702c06f41116ffd1e620bf3c412a2c to your computer and use it in GitHub Desktop.
dart-naive-eval
num evaluate(String expression) {
var tokens = expression.split(' ');
print(tokens);
// Stack for numbers: 'values'
List<num> values = [];
// Stack for Operators: 'ops'
List<String> ops = [];
for (var i = 0; i < tokens.length; i++) {
if (num.tryParse(tokens[i]) != null) {
// dart reafctor: removed the while here as it is not needed and bad
values.add(num.parse(tokens[i]));
}
// Current token is an opening
// brace, push it to 'ops'
else if (tokens[i] == '(') {
ops.add(tokens[i]);
}
// Closing brace encountered,
// solve entire brace
else if (tokens[i] == ')') {
while (ops.last != '(') {
values.add(applyOp(
ops.removeLast(), values.removeLast(), values.removeLast()));
}
ops.removeLast();
}
// Current token is an operator.
else if (tokens[i] == '+' ||
tokens[i] == '-' ||
tokens[i] == '*' ||
tokens[i] == '/') {
// While top of 'ops' has same
// or greater precedence to current
// token, which is an operator.
// Apply operator on top of 'ops'
// to top two elements in values stack
print(ops);
print(values);
while (ops.isNotEmpty && hasPrecedence(tokens[i], ops.last)) {
values.add(applyOp(
ops.removeLast(), values.removeLast(), values.removeLast()));
}
// Push current token to 'ops'.
ops.add(tokens[i]);
}
}
// Entire expression has been
// parsed at this point, apply remaining
// ops to remaining values
while (ops.isNotEmpty) {
values.add(
applyOp(ops.removeLast(), values.removeLast(), values.removeLast()));
}
// Top of 'values' contains
// result, return it
return values.removeLast();
}
bool hasPrecedence(String op1, String op2) {
if (op2 == '(' || op2 == ')') {
return false;
}
if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) {
return false;
} else {
return true;
}
}
num applyOp(String op, num b, num a) {
switch (op) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0) {
throw "Cannot divide by zero";
}
return a / b;
}
return 0;
}
void main() {
print(evaluate("100 * 2 + 12")); // 212
print(evaluate("100 * ( 2 + 12 )")); // 1400
print(evaluate( "100 * ( 2 + 12 ) / 14")); // 100
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment