This project has moved. For the latest updates, please go here.

Questions on this project

Nov 11, 2013 at 4:38 PM
Edited Nov 11, 2013 at 4:40 PM
Hello,
This project looks very promising.
I am looking for that kind of library for a project and:
  • Ncalc.codeplex.com does not fit my needs as I think it cannot handle arrays or custom types
  • Flee.codeplex.com is very nice, but for a few reasons it does not fit my needs, and it seems to be not maintained any more.
I would like to know if this library is still maintained, and if the following features are planned to be implemented or not.

Let's say I have this:
var expr = new CompiledExpression("myInt * var1 * var2.myfunction() * customFunction(10,10)");
expr.RegisterType("myInt", 10);
expr.Eval();
I am looking for the following features:
  1. Function to list all "variables" : here it would be "myInt, var1, var2"
  2. Ability to have dynamic variables: Have events that detect the list of undefined variable, in order to ask for a type and value of the variable. It would be useful for var1 and var2 that are not defined with "RegisterType" function
  3. Function to list all "functions" used : here is would be "customFunction"
  4. Ability to have customFunctions. I found a way to make it work by registering a static class with RegisterType("prefix",myStaticClass) -> I can then use custom functions with prefix.customFunction().
    Is there a workaround to get rid of the prefix ?
I looked at the code, and maybe the topics 1 & 2 would be feasible to implement without many modifications. I would add a "variables" object in the ExpressionCompiler class, that handles events.
Do you think these features make sense for your library, and is there a chance they would be implemented in the future?

Best regards,
Nov 21, 2013 at 10:47 PM
I have a very similar set of needs.

I need to support a fairly simple grammar for my expression, since they will be created by 3rd parties. For this reason, the "myFunctions.foo()" approach doesn't work. I need a way to be able to bind to "naked" functions (without a type/object prefix) in the expression. This is #4 above. I'm wondering if it would be reasonable to register a "default" type where I put all my built-in functions, then have the compiler fall back to looking in that type if the function isn't otherwise resolved. Or possibly just have a setting to specify the default/fallback type (so I can register all my functions via the "foo" type, then tell the parser that the default type is "foo", directing it to look in the foo type/object for anything it can't resolve - exactly as if I had prefixed it with "foo.").

I also need to discover and bind to the expression variables at expression compile time (I don't know in advance what variables will be referenced in a given expression) and without an object/type prefix. Given my initial review of how the parser/compiler works, I think the idea of a callback is probably the cleanest way to handle this. Essentially, right in the spot where it throws an exception now on an unrecognized token, it could call a callback and give you a shot to supply the token (presumably an object with some defined method to supply to value when needed later). This is #2 above.

The combination of these things would allow me to have an expression like "len(textField) > max(240, maxTextLen)" where I have supplied the len and max functions and I find out when the expression is compiled that I need to bind to textField and maxTextLen (I have to go find them in a large package of properties that I'm maintaining).

Just wondering if bobby751 made any progress on these things, or if the original maintainer has any comments. Thanks.
Nov 23, 2013 at 3:27 PM
Currently I haven't started to modify this code. As you did, I found where the library triggers an exception for topic #2 on dynamic variables.
By analyzing a few other libs, I think it would be feasible to implement it here.

I just added a few regions in the source, in order to be able to undertand the code easily, but it is not a lot of work.

I have a few other needs, that are not given by any open source Expression Evaluator I tested. I don't know yet the one I will use, as every of them seems not supported any more by its developper/ have any active team members...
  • Be able to use short operations, like if(xxx), (but it could be a custom function)
  • Be able to extract each individual "element" of an expression without evaluating it : for a variable it is easy, but when it is a property of a variable, it is much more difficult...
Ex: 3 + parameter.variable + parameter.myFunction(33) + myVar
-> I want to extract in a List: "parameter", "parameter.variable", "parameter.myFunction(33)", "myVar"

If we have the same set of needs, we could share our findings if you like.
Best regards
Developer
Feb 1, 2014 at 10:10 AM
Edited Feb 1, 2014 at 10:11 AM
Hi, I have been busy for the past few months with work, and honestly I didn't know that ExpressionEvaluator was generating that much interest so I didn't browse through the discussions.

I have recently gotten back into working on the code (as I have found use for it in my day job, as it were), so I'd be happy to look at your suggestions.

1. Function to list all variables, functions.

This would be simple to do. Would you just need a list of strings for each kind, variable and function? What use would this list be to you?

2. Dynamic variables.

I'm not sure how this works, however the latest commit has a ScopeCompile method available. Basically it creates a function that accepts and object, and any undefined variables in the expression are "scoped" to that object. Since the scope parameter is of type Object, binding is done at "run-time" instead of "compile time". I don't know if this fulfills your requirement of "dynamic", but you can essentially do this:
class Scope{
    public bool foo() {
         return true;
    }

     public int x { get { return 1; }  }
     public int y { get { return 2; }  }
}

class Scope2{
    public bool foo() {
        return false;
    }

     public string x { get { return "not this one" } }
     public string y { get { return "this one" } }
}

var expr = "foo() ? x : y";
var comp = new CompiledExpression(expr);
var func = comp.ScopeCompile();

var scope = new Scope();
var scope2 = new Scope2();

var result = func(scope);   // returns 1
var result2 = func(scope2);  // returns 'this one'
Using ScopeCompile I was able to make a template parser that contained embedded code and dynamic scope, if you are familiar with angularjs, I was essentially able to replicate ng-repeat like so:
  <tr repeat="item in data.Items">
      <td>{{item.Name}}</td>
      <td>{{item.Container1.Property1}}</td>
      <td>{{item.Container1.Property2}}</td>
  </tr>
The above is XML being parsed in a manner similar to HTML, for use in dynamically templating a powerpoint slide.

3. Removing the prefix for custom functions / variables

In addition to ScopeCompile there is also a Global property that will be used if ScopeCompile is NOT in effect. (I will probably change it as now it strikes me that this usage is a bit ambiguous). Maybe a RegisterGlobal method instead?

If it would be possible I would be interested to know what sort of way you are using ExpressionEvaluator. Please feel free to contact me via the Contact button on my profile page and I'd be happy to continue discussions through email (that way I get notifications on my phone)