appsup-dart / expressions

A library to parse and evaluate simple expressions.
BSD 3-Clause "New" or "Revised" License
41 stars 19 forks source link

Add Exponent operator #7

Closed malown closed 4 years ago

malown commented 4 years ago

The exponent operator is very commonly used in geometry and algebra. At the moment one could add the function pow to the context when the expression is evaluated, however that makes the expression less readable.

I noticed that Dart itself doesn't support the ** operator like most languages, but i'd suggest using it in this case.

apgapg commented 4 years ago

Its already there i guess case '^': return left ^ right();

Try a test case of 2^2 and see if it evaluates correctly

malown commented 4 years ago

That's the bitwise XOR operator https://en.wikipedia.org/wiki/Bitwise_operations_in_C#Bitwise_XOR_^

bbjay commented 4 years ago

Just came across the same issue. The error message I got was "NoSuchMethodError: Class 'double' has no instance method '^'."

I first tried to define a '^' method with pow in the context, but it looks like the context is just for variables and functions, not for infix/binary operators.

In the end I got it working with a custom evaluator:

import 'dart:math';

class MyEvaluator extends ExpressionEvaluator {
    const MyEvaluator();

    @override
    evalBinaryExpression(BinaryExpression expression, Map<String, dynamic> context) {
        if (expression.operator == '^') {
            final left = eval(expression.left, context);
            final right = () => eval(expression.right, context);
            return pow(left, right());
        }
        return super.evalBinaryExpression(expression, context);
    }
}
malown commented 4 years ago

That will interfere with the bitwise XOR mentioned above. Also, you didn't set the precedence for the operator so the expression 5 3^2 gets evaluated as (5 3)^2

Check out my repo for a solution. I Used the ° sign as the exponent operator as i couldn't get ** to get parsed properly

https://github.com/malown/expressions

apgapg commented 4 years ago

You can simply define a callMemberExpression like 'pow(2,2)'

malown commented 4 years ago

For my usecase i need the expression to be easily readable by humans without using regex

Throvn commented 2 years ago

Does someone have a solution for this? Unfortunately @malown took all of their repositories down and I have no clue on how to extend the code snippet above to make it work properly :(