Skip to content

Instantly share code, notes, and snippets.

@iykekings
Created October 26, 2022 22:21
Show Gist options
  • Select an option

  • Save iykekings/d9702c06f41116ffd1e620bf3c412a2c to your computer and use it in GitHub Desktop.

Select an option

Save iykekings/d9702c06f41116ffd1e620bf3c412a2c to your computer and use it in GitHub Desktop.

Revisions

  1. iykekings created this gist Oct 26, 2022.
    99 changes: 99 additions & 0 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,99 @@
    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
    }
    3 changes: 3 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    # dart-naive-eval

    Created with <3 with [dartpad.dev](https://dartpad.dev).