Occasionally, there is a need to have the user enter a mathematical expression and then have the application evaluate it. I’ve run into this situation a number of times in the past, and in those cases I’ve thrown together the minimum bit of programming that would do the job in the particular instance. For a current project I’ve decided to put a bit more effort into it, and have created an expression evaluator class that should handle any situation that I expect to encounter in the foreseeable future.
For anyone who would like to make use of this class, you can download it here:
Is this based on the “Shunting Yard” Algorithim?
I had a Xojo version in a RetroBasic project I did a few years ago, and I just updated it (currently in SWIFT), but will be taking the re-engineered SWIFT code and porting it back to XOJO for another project I have coming up. It handles any defined function (with 0, 1 or 2 arguments), as well as Scalar variables, and Arrays up to 2 dimensions
Yes. At least it’s a variation of the Shunting Yard algorithm. Every time I implement this I go back to one of my old computer science text books. They never used the Shunting Yard name in that text (possibly because trains hadn’t been invented back then), but it is a stack based parsing method.
I don’t have 2 argument functions implemented yet, so there’s no Atan2 or similar functions yet, but they’re on my to do list.
It doesn’t do arrays. I doubt that I’ll implement arrays, but you never know.
Hi Paul. Thanks for the reference. I’d missed that, but of course that is an ideal example for XojoScript.
Just to clarify, the functionality of the class that I created falls somewhere between the XojoScript example project and Dave S’s RetroBasic expression evaluation capabilities. I didn’t want to go full blown computer language processing, but still needed to handle expressions with variables in an efficient way.
The ExpressionEvaluator class deals with expressions in two stages. First, it parses the expression, and creates a symbol table of any variable names that are in the expression, and then creates a compiled pseudo code for later evaluation. Second, a separate evaluation method performs the actual evaluation of the expression. The intention is to spend a bit more processor time in parsing the expression in order to save more time later when evaluating it. This is geared towards my own applications, where the user will enter perhaps one or two expressions, and then they will be evaluated thousands of times. So, the evaluation stage needs to be the most efficient. (This would suggest that XojoScript would be the better route to go, but there are some other subtle but important considerations that affect the decision.)
What initiated all of this is my current project, which is the development of a non-linear multi-variable optimizer. For this, I need the ability to efficiently deal with variables, but I don’t need all the full blown features of a programming language expression evaluator (eg. array handling etc.). This class has some useful tools for accessing and changing variable values without much grief.
One of the two examples in the ExpressionEvaluator project file demonstrates the Gauss-Seidel method for solving a set of n linear equations in n unknowns. I think this is a good demonstration showing that a very small amount of external code can be combined with the class to give a very useful result.
Thanks for sharing this. The program runs in Xojo 2016 r4.1 but if you enter a simple expression and click parse it crashes with a TypeMismatchException in ExpressionEvaluator.Init.
The same simple expression works fine in Xojo 2016 r2.1
Thanks for the feedback Paul. I had been avoiding Xojo 2016 r4.x because of reports of flaky behaviour. But I tried it now, and verify that there is a problem. I’ll try to track down the problem and get back to you.
Meanwhile, If you still have 2016r3 installed, it should work.
[quote=352987:@Edwin van den Akker]
With a bit of tinkering this expression evaluator might even work in iOS[/quote]
I haven’t done any iOS projects yet. So, I’m not sure how much work it would take to make this class compatible. The first thing I would check is that the introspection parts are compatible, or at least easily adaptable. If that’s not a problem, then the rest should be easy.
I did some iOS introspection stuff while making some kind for database framework, where a class is kind of a blueprint of a SQLite table layout. The class would match the public properties of that class with the table of the db. It would add fields if they didn’t appear in the table.
A similar thing I made a long time ago for desktop. I didn’t have to change that much. I think I mainly added the “xojo.” in front of the introspection parts.
Also, I removed any string datatypes, or simply changed them to the text datatype.
I’d forgotten that iOS uses the Text data type instead of String. This could add a fair amount of work to convert it to an iOS compatible format. Not impossible though. And maybe worth doing, since XojoScript is not an option for iOS. If you’re interested in making an iOS version of this, I’d be happy to help.