Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[Updated to v2.2.1] C# Eval: expression parser and compiler

Discussion in 'Assets and Asset Store' started by DenisZykov, Mar 31, 2016.

  1. DenisZykov

    DenisZykov

    Joined:
    Mar 31, 2016
    Posts:
    19
    This package provides the software interface for parsing and expression execution written in C#. Since it is written in C# 3.5, it should work with any version of Unity. Source code of parser and compiler is included.

    Features:
    - C# 3.5 expression parser
    - AOT compiler for System.Linq.Expressions

    Compability:
    It is tested to work on: iOS, Android, WebGL, PC/Mac
    It should work on any other platforms.

    Documentation
    C# Eval() on Asset Store

    Release Notes:
    2.1.2
     
    Last edited: Mar 22, 2017
  2. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    Does it offer support for statements?
    As in multiple "commands" per code submission?
    Can you return a func or action out of the code itself? ("return () =>123" would return a func<int>)


    If not can you add those?
     
  3. DenisZykov

    DenisZykov

    Joined:
    Mar 31, 2016
    Posts:
    19
    Short answer is no. This package is designed only for evaluation of expressions. It relies on System.Linq.Expressions that does not support statements in .NET 3.5(Unity). However in the future I plan to add some "functional" language extensions. Such as 'let', or switch(expression form from C#7).
    Code (CSharp):
    1. let x = 1 + 1;
    2. let fn = (y,z) => x * y * z;
    3.  
    4. fn(2,3) // will return 12
    If you do not want (iOS, WebGL and other IL2CPP stuff), I advise you to look in the direction of CodeDOM.
    Yes, experimental v.2.0.0 support for lambda expressions (with some resitrctions on iOS and WebGL). You can try it right now from GitHub or wait for stable release in few weeks.
    Code (CSharp):
    1.  
    2. // return function
    3. var fn = CSharpExpression.Evaluate<Func<int, int>>("a => a + 1") // => Func<int, int>
    4. // argument closure
    5. var fn = CSharpExpression.Evaluate<int, Func<int, int>>("a => arg1 + a + 1", arg1Name: "arg1") // => Func<int, int>
     
    Last edited: Feb 14, 2017
    dadude123 likes this.
  4. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    that let thing is a good idea. but would it be possible to rename it to "var" (just give an option to do so).
    detecting the case when something starts with var + identifier should be possible with a regex, then you can snip that away (and extract the identifier) and just store it in a dictionary or so.

    i know that not having statement lists from .NET 4.0 is a problem, but I guess it should be possible to sail around that with a few tricks :)

    good work so far
     
  5. DenisZykov

    DenisZykov

    Joined:
    Mar 31, 2016
    Posts:
    19
    Imperative varables are not available because I can't save an intermediate state during the execution of the expression (limitation of System.Linq.Expressions).
    'Let' is declarative construct (Declarative vs. Imperative). It's not imperative 'set variable x equals to result of 1 plus 1' it's a declaration of 'let x will be 1 plus 1'. And references to x will be replaced by '1 + 1' expression (like 'let' from Clojure). This is possible since unfolding of such 'let' structures occurs at 'building a syntax tree' stage.

    But almost any function can be written in a declarative style.
    I will look at statements after Unity update Mono runtime.
     
  6. DenisZykov

    DenisZykov

    Joined:
    Mar 31, 2016
    Posts:
    19
    A new version is released 2.1.2:

    Features
    • added more descriptive message to member binding error
    • added autodoc comments for public members
    • hidden ReadOnlyDictionary from public access
    • removed WEBGL check for later version of Unity, because unsigned types bug was fixed
    • added generic types and generic methods
    • added nullable types via '?' suffix
    Code (CSharp):
    1. CSharpExpression.Evaluate<int?>("default(int?)"); // -> null
    • added lambda expression syntax '() => x' and 'new Func(a => x)'
    • added support for expression parameter re-mapping with lambda syntax at beggining of expression
    Code (CSharp):
    1. CSharpExpression.Evaluate<int, int, int>("(x,y) => x + y", 2, 2); // -> 4
    • added support for Func<> lambdas on AOT environments
    • added additional constructor to Binder class
    Code (CSharp):
    1. public Binder(Type lambdaType, ITypeResolver typeResolver = null);
    • added ArgumentsTree ToString method
    Bug Fixes
    • fixed error with wrongly resolved types (only by name) in KnownTypeResolver
    • fixed bug with ACCESS_VIOLATION on iOS (Unity 5.x.x IL2CPP)
    • fixed few Unity 3.4 related errors in code
    • fixed 'new' expression parsed with error on chained calls new a().b().c()
    • fixed some cases of lifted binary/unary/conversion operations
    • fixed some AOT'ed operations on System.Boolean type
    • fixed null-propagation chains generate invalid code
    • fixed some edge cases of resolving nested generic types
    • fixed error with types without type.FullName value
    • fixed Condition operator types promotion
    • fixed Power operator types promotion and null-lifting
    • fixed enum constants threated as underlying types during binary/unary operations
    Breaking changes
    • ParserNode renamed to ParseTreeNode
    • ExpressionTree renamed to SyntaxTreeNode
    • ExpressionBuilder renamed to Binder
    • ITypeResolutionService renamed to ITypeResolver
    • ITypeResolver.GetType removed
    • ITypeResolver now could be configured with TypeDiscoveryOptions
     
  7. Yassir_

    Yassir_

    Joined:
    Aug 5, 2017
    Posts:
    1
    Hello everyone,
    Is there a way to pass list of objects before evaluating the expression, something like below :

    var parametres = new KnownParametreResolver();
    parametres["x"] = x;
    parametres["y"] = y;
    parametres["z"] = z;
    bool result = CSharpExpression.Evaluate<bool>("x + y + z > 100", parametres);

    Thanks
     
  8. DenisZykov

    DenisZykov

    Joined:
    Mar 31, 2016
    Posts:
    19
    Hi Yassir! Here is examples how you could pass parameters to Evaluate method:

    Code (CSharp):
    1.  
    2. // you could pass values as arguments to Evaluate method
    3.             var v1 = 100;
    4.             var v2 = 200;
    5.             var v3 = 300;
    6.             bool r;
    7.  
    8.             // arg1, arg2, arg2 is default names for passed arguments
    9.             r = CSharpExpression.Evaluate<int, int, int, bool>("arg1 + arg2 + arg3 > 100", v1, v2, v3);
    10.  
    11. // and you could 'name' passed arguments
    12.             r = CSharpExpression.Evaluate<int, int, int, bool>("x + y + z > 100", v1, v2, v3, "x", "y", "z");
    13.  
    14. // or you could pass dictionary with parameters
    15.             var dict = new Dictionary<string, int> {
    16.                 {"x", 100},
    17.                 {"y", 100},
    18.                 {"z", 100},
    19.             };
    20.  
    21.             r = CSharpExpression.Evaluate<Dictionary<string, int>, bool>("d[\"x\"] + d[\"y\"] + d[\"z\"] > 100", dict, "d");
    22.  
    23. // or you could pass your object as parameter
    24.            class MyClass
    25.            {
    26.               public int x;
    27.               public int y;
    28.               public int z;
    29.            }
    30.  
    31.             var my = new MyClass {
    32.                 x = 100,
    33.                 y = 100,
    34.                 z = 100
    35.             };
    36.  
    37.             r = CSharpExpression.Evaluate<MyClass, bool>("arg.x + arg.y + arg.z > 100", my, "arg");
     
  9. yoannG

    yoannG

    Joined:
    Jul 14, 2013
    Posts:
    15
    Hello Denis,
    I was about to purchase the package, but i got this error message. Probably just an automated message or something, but i wanted to check with you first.

    Possible incompatibility with Unity 2018
    This package was published using Unity 3 and contains asset types which may not upgrade cleanly to Unity 2018:
    • Compiled assemblies
    While Unity will generally attempt to upgrade assets to work, problems may still occur. For more information about upgrading projects to Unity 2018, please refer to the Unity 5.0 Upgrade Guide.
    For more information about the compatibility of this specific package, please contact the publisher directly.
     
  10. DenisZykov

    DenisZykov

    Joined:
    Mar 31, 2016
    Posts:
    19
    Hi, yoannG! Yes, this is automated message. And it is not relevant because my asset is not using Unity's assemblies. It is depends on mscorlib and System.dll. So it portable and could run almost anywhere.

    Probably on next release I will submit my asset from multiple Unity versions and this message will gone.
     
    NeatWolf likes this.
  11. yoannG

    yoannG

    Joined:
    Jul 14, 2013
    Posts:
    15
    Fantastic !
    I will get back to you if i run into problems, which will definitely happen!
     
  12. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    924
    That's great to hear! I needed a dynamic way to evaluate expressions to build a conditional system and this looks like the best implementation I could hope for! (not relying on reflection). Of course, I know it's definitely a costly function to call, but in my case I just need to do this sparingly, so it should be ok :)

    I was about to ask if you were still developing/supporting it, but I can now see the answer is yes, so this gets straight in the cart :)

    Looking forward the next update!
     
    DenisZykov likes this.
  13. DenisZykov

    DenisZykov

    Joined:
    Mar 31, 2016
    Posts:
    19
    Thanks!
    If you have any questions you could ask them here, on GitHub (if it is a bug) or via email (support@gamedevware.com).

    Also any user reviews (good/bad/suggestions) to my asset would help me a lot.
     
    tosiabunio and NeatWolf like this.