EvalEx 0.1.0

dotnet add package EvalEx --version 0.1.0                
NuGet\Install-Package EvalEx -Version 0.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EvalEx" Version="0.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add EvalEx --version 0.1.0                
#r "nuget: EvalEx, 0.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install EvalEx as a Cake Addin
#addin nuget:?package=EvalEx&version=0.1.0

// Install EvalEx as a Cake Tool
#tool nuget:?package=EvalEx&version=0.1.0                

EvalEx -- Expression Evaluator

EvalEx is a simple yet powerful expression evaluator written in C# and provided as a class library. EvalEx extensively supports double-based calculations, and has a limited support for double[], string, integer (as long data types) and JSON objects, using the Newtonsoft library. EvalEx can be extended adding new functions and even operators. This project initially started porting to C# the EvalEx Java project by Udo Klimaschewski (thanks 🙏).

Basic Usage

using EvalEx;

Expression e = new Expression();
e.SetIntVariable("A", 10);
e.SetIntVariable("a", 20);
long result = e.EvalInt("a+A"); // -> 30

Variables

Basic variables data types are double, double[] and string. JSON objects are basically handled as strings, and converted to JSON only when a JSON properties or JSON Path expressions are used. Variables are added to expression instances and a name is assigned. Note that variable names are case sensitive.

using EvalEx;

Expression e = new Expression();
e.SetDoubleVariable("d", 123.45d);
e.SetArrayVariable("a", new double[] { 12.1d, 23.2d, 34.3d });
e.SetStringVariable("s", "Hello World!");
e.SetStringVariable("s", "{ \"key\" : 123 }");

Functions

Functions can be added as C# classes, extending the Function or LazyFunction (for lazily evaluated functions) class

protected class TestSum : Function
{
    public TestSum() : base("TESTSUM", 2) { }

    public override double Eval(List<double> parameters)
    {
        return parameters[0] + parameters[1];
    }
}
...
e.AddFunction(new TestSum());

or using the DynaFunction class, using a specific syntax

FUNCTION(param1: [type], param2: [type], ...): [return type] => [function]

[type] can be one of Float, Int, String.

DynaFunction d = new DynaFunction("PITAGORA(leg1: Float, leg2: Float): Float => SQRT( leg1^2 + leg2^2 )");
expression.AddLazyFunction(d.AsLazyFunction());

Expression Break

Sometimes, you may want to inform your application that a particular expression should not return a value. In such cases, you can use the IFBRK(check, result) function. This function returns result if check returns a true (!= 0) value, otherwise throws an ExpressionBreakException

e.EvalDouble("IFBRK(3<5, 1.0)"); // returns 1.0 (double
e.EvalDouble("IFBRK(3>5, 1.0)"); // throws ExpressionBreakException

Arrays, map and reduce

EvalEx offers a basic array support (see "Builtin Functions" for more informations), and depending on the use cases, you'll probably want to write your own functions to handle with them. Nevertheless, there are two operators to work with arrays: map ($) and reduce (@). Map iteratively invokes a function that takes at least one parameter on any element of the array and returns a "mutated" version of the array. Reduce invokes a function that takes at least two parameters passing the first two elements of the array as arguments, and then iteratively invokes the same functions passing as first argument the result of the preceding computation, and the next element of the array as second argument. Suppose you have declared in your expression two functions "SQUARE(x)" defined as x^2, and "SUM(a,b)" defined as a+b.

double[] arr = new double[] { 1d, 3d, 5d };
expression.EvalArray("$SQUARE(arr)")); // returns { 1d, 9d, 25d }
expression.EvalInt("@SUM(arr)")); // returns (1+3)+5 => 9

CachingExpression

If you plan to evaluate the same function in a loop, and the function might be computational intensive, you can use the CachingExpression class, superclass of Expression, that caches a signature of the expression and returns a cached value of it.

Expressions showcase

Simple numeric expressions

"5+3" -> 8
"SIN(PI)" -> 0
"x^3" -> 8 (x = 2)
"3^x" -> 9
"81^0.75" -> 27

IF

IF function is always lazily evaluated

IF(3<5, 1, 3/0); // returns 1, does not throw a division by zero

Scientific Notation

Supported with both uppercase or lowercase E.

e.EvalInt("123.4567E4"); /// 1234567 (long)
e.EvalDouble("1e-10"); // 0.0000000001d (double)

JSON

Simple JSON properties access can be inlined using dot notation

e.SetStringVariable("jj", @"{'adouble':123.45d,'aint':37, 'anested': { 'nstring': 'hello world' } }");
e.EvalInt("jj.aint"); // 37
e.EvalString("jj.nested.nstring"); // "hello world"

more complex JSON Path expressions can be put inside double quotes

expression.EvalInt("bigjson.\"$.Manufacturers[?(@.Name == 'Acme Co')].Products[0].Price\"")); // 50

// if multiple values are returned, double or double[] values, they will be merged:
expression.EvalArray("bigjson.\"$..Products[?(@.Price >= 50)].Deps\"")); //  { 1, 3, 5, 2, 4, 6 }

Builtins

Operators

Double-based Operators

Arithmetic operators +, -, *, /, modulus %, and power ^ operator. Unary + and - operators. Logical operators and &&, or || and not !. Equal to =, greater than >, less than <, greater-or-equal-to >=, less-than-or-equal-to <=, different than <> operators. Notice that a boolean false value is 0.0d, while any other double value is considered as true; logical true is returned as 1.0d.

String Operators

Concatenation %%, concatenation with a blank in between ++ (e.g. "hello"++"world""hello world"), concatenation with a blank-plus-blank sequence +++ (e.g. "hello"+++"world""hello + world"). String comparison, equal == and different != (notice that strings are trimmed via .Trim() method before being compared! String length comparison, longer than >> and shorter than << (notice that strings are trimmed via .Trim() method before being compared!

Functions

IF evaluates the first argument and, if it represents a truth value, the second argument is evaluated and returned, the second otherwise. IFBRK evaluates the first argument and, if it represents a truth value, the argument is evaluated and returned, otherwise an ExpressionBreakException is raised.

Double-based Functions

NOT returns the logical negation of the double argument. RANDOM returns a random number between 0 (inclusive) and 1 (exclusive). Trigonometric functions SIN, COS, TAN, ASIN, ACOS, ATAN, argument is an angle measured in radians. RAD converts degrees to radians, and DEG converts an radians to degrees. MAX, MIN, AVG return the maximum, the minimum and the average of the provided double arguments. ABS returns the absolute value. LN and LOG return the natural (base e) logarithm. SQRT returns the square root of the argument. ROUND, returns the rounded (0.5 based) double value of the argument FLOOR returns the greatest integer value lower than or equal to the argument. CEIL returns the lowest integer value greater than or equal to the argument.

Array-based Functions

JOIN returns an array that is the concatenation of the arguments; if an argument is a double, it's treated as a single-value array. SORT returns an array that contains a concatenation of the arguments, sorted in ascending order.

String-based Functions

CONCAT returns the strings joined (just like the %% operator, but with multiple arguments). STRLEN returns the length of the string (not trimmed). STRCMP compares the first string argument with all the other arguments and returns true or false. STRICMP same as STRCMP, but ignoring case (case insensitive). IN returns true if the first argument as a string is equal to one of the other arguments

Constants

e the base of the natural logarithms, aka the Napier's constant PI the greek-pi NaN a placeholder for the double "Not a Number" constant null same as NaN TRUE is 1.0d FALSE is 0.0d

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.1.0 585 4/30/2020