I built this shard because I needed a simple and performant. Crystal is already great for this type of logic, and I wanted to leverage its type system to build a clean and fast parser/evaluator.
Key Features
Zero Dependencies: Uses only the Crystal standard library.
Simple API: Designed to be intuitive and easy to integrate into any project.
Performant: Optimized for fast tokenization and evaluation, keeping overhead to a minimum.
Usage
require “eeeval”
vars = {“x” => 3.0, “y” => 1.5}
result = EEEval::CalcFuncParser.evaluate(“x^2 + sin(y)”, vars)
puts result
Here the GitHub repository
I’d love to hear your feedback, especially if you have ideas for additional features (like custom variables or functions) or if you want to help improve the performance further. Feel free to open an issue or a PR on GitHub!
yes good to see someone had the same idea with same syntax. I started the library in 2023 and now I wanted to code again with my preferred language. In the last version I added AST (abstract syntax tree) to have more performances
This reminds me of the expression evaluator in Crinja. Its primary purpose is to evaluate expressions in template tags (such as the x > 3 in {% if x > 3 %}.
It can also be used standalone with Crinja#evaluate. Unfortunately the documentation for that use case is very slim. Sorry bout that
There are lots of specs, though. They should demonstrate pretty clearly how it works:
Here is a translation of the original example. Primary difference is that Crinja doesn’t have a sin function built in (the original use case is text oriented, rather than math). But it’s easy to define your own function.
And the exponential operator is ** instead of ^, but that’s just a syntax detail.
require "crinja"
Crinja.function :sin do
Math.sin(arguments.varargs.first.as_number)
end
vars = {"x" => 3.0, "y" => 1.5}
result = Crinja.new.evaluate("x ** 2 + sin(y)", vars)
puts result
It’s a lot more powerful than simple arithmetic expressions and allows defining custom functionality. It implements the full grammar of Jinja expressions, except for a few Pythonisms (see Differences from Jinja2).
I was wondering whether it would make sense to extract this as a dedicated tool, maybe even in a separate shard.
The sibiling implementation JinJava uses Java Expression Language, a standalone