Created with <3 with dartpad.dev.
Created
October 26, 2022 22:21
-
-
Save iykekings/d9702c06f41116ffd1e620bf3c412a2c to your computer and use it in GitHub Desktop.
dart-naive-eval
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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