{"id":13662589,"url":"https://github.com/deniszykov/csharp-eval-unity3d","last_synced_at":"2025-06-14T21:05:55.643Z","repository":{"id":86091342,"uuid":"55436744","full_name":"deniszykov/csharp-eval-unity3d","owner":"deniszykov","description":"C# Expression Parser for Unity3D","archived":false,"fork":false,"pushed_at":"2024-03-02T16:21:28.000Z","size":2155,"stargazers_count":205,"open_issues_count":6,"forks_count":24,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-05-24T18:06:50.733Z","etag":null,"topics":["ast","eval","expression-evaluator","expression-parser","unity","unity-asset","unity-scripts","unity3d","unity3d-plugin"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deniszykov.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"License.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-04T18:54:59.000Z","updated_at":"2024-11-18T17:36:53.000Z","dependencies_parsed_at":"2024-01-14T15:23:11.816Z","dependency_job_id":"f75ee87f-bde5-421f-9fa9-e2a1d4ca1193","html_url":"https://github.com/deniszykov/csharp-eval-unity3d","commit_stats":{"total_commits":224,"total_committers":2,"mean_commits":112.0,"dds":0.004464285714285698,"last_synced_commit":"f3251f389b4c430862a3de1896d88effe4c7cdad"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/deniszykov/csharp-eval-unity3d","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deniszykov%2Fcsharp-eval-unity3d","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deniszykov%2Fcsharp-eval-unity3d/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deniszykov%2Fcsharp-eval-unity3d/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deniszykov%2Fcsharp-eval-unity3d/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deniszykov","download_url":"https://codeload.github.com/deniszykov/csharp-eval-unity3d/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deniszykov%2Fcsharp-eval-unity3d/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259884470,"owners_count":22926444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast","eval","expression-evaluator","expression-parser","unity","unity-asset","unity-scripts","unity3d","unity3d-plugin"],"created_at":"2024-08-02T05:02:02.881Z","updated_at":"2025-06-14T21:05:55.594Z","avatar_url":"https://github.com/deniszykov.png","language":"C#","readme":"[![Actions Status](https://github.com/deniszykov/csharp-eval-unity3d/workflows/dotnet_build/badge.svg)](https://github.com/deniszykov/csharp-eval-unity3d/actions)\n\n# Licensing\n\nThis is a paid [package](https://assetstore.unity.com/packages/tools/visual-scripting/c-eval-56706), you can use it anywhere if you [purchased it](https://assetstore.unity.com/packages/tools/visual-scripting/c-eval-56706).\n\n# Introduction\n\nThis package provides the API for parsing and expression execution written in C#. It is specially designed to work with the [Unity](http://unity3d.com/) on various platforms. Since it is written in C# 3.5 and has no additional dependencies, it should work with any version of Unity (and .NET framework).\n\nIt is tested to work on:\n* IOS\n* Android\n* WebGL\n* PC/Mac\n\nIt should work on any other platforms. \n\n\u003e :warning: For AOT execution platforms (**iOS, WebGL, IL2CPP**) a [link.xml](https://github.com/deniszykov/csharp-eval-unity3d/blob/master/src/GameDevWare.Dynamic.Expressions.Unity.2021/Assets/Plugins/GameDevWare.Dynamic.Expressions/link.xml) should be added to project's root directory. Read more about [IL code stripping](https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html) in official documentation.\n\n**API**\n* CSharpExpression\n\t* Evaluate\n\t* Parse\n* AotCompilation\n\t* RegisterFunc \n\t* RegisterForFastCall (optional stuff)\n\n## Example\nParsing C# expression into **System.Linq.Expression.Expression[T]**:\n```csharp\nvar mathExpr = \"Math.Max(x, y)\";\nvar exprTree = CSharpExpression.Parse\u003cdouble, double, double\u003e(mathExpr, arg1Name: \"x\", arg2Name: \"y\") \n// exprTree -\u003e Expression\u003cFunc\u003cdouble, double, double\u003e\u003e\n```\nEvaluating C# expression:\n```csharp\nvar arifExpr = \"2 * (2 + 3) \u003c\u003c 1 + 1 \u0026 7 | 25 ^ 10\";\nvar result = CSharpExpression.Evaluate\u003cint\u003e(arifExpr); \n// result -\u003e 19\n```\n\n## Parser\nThe parser recognizes the C# 4 grammar only. It includes:\n\n* Arithmetic operations\n* Bitwise operations\n* Logical operations\n* [Conditional operator](https://msdn.microsoft.com/en-us/library/ty67wk28.aspx)\n* [Null-coalescing operator](https://msdn.microsoft.com/en-us/library/ms173224.aspx)\n* Method/Delegate/Constructor call\n* [Property/Field access](https://msdn.microsoft.com/en-us/library/6zhxzbds.aspx)\n* [Indexers](https://msdn.microsoft.com/en-gb/library/6x16t2tx.aspx)\n* [Casting and Conversion](https://msdn.microsoft.com/en-us/library/ms173105.aspx)\n* [Is Operator](https://msdn.microsoft.com/en-us/library/scekt9xw.aspx)\n* [As Operator](https://msdn.microsoft.com/en-us/library/cscsdfbt.aspx)\n* [TypeOf Operator](https://msdn.microsoft.com/en-us/library/58918ffs.aspx)\n* [Default Operator](https://msdn.microsoft.com/en-us/library/xwth0h0d.aspx)\n* [Expression grouping with parentheses](https://msdn.microsoft.com/en-us/library/0z4503sa.aspx)\n* [Checked/Unchecked scopes](https://msdn.microsoft.com/en-us/library/khy08726.aspx)\n* [Aliases for Built-In Types](https://msdn.microsoft.com/en-us/library/ya5y69ds.aspx)\n* [Null-conditional Operators](https://msdn.microsoft.com/en-us/library/dn986595.aspx)\n* Power operator ``**``\n* [Lambda expressions](https://msdn.microsoft.com/en-us/library/bb397687.aspx)\n* \"true\", \"false\", \"null\"\n\nNullable types are supported. \nGenerics are supported.\nEnumerations are supported.\n[Type inference](https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/type-inference) is not available and your should always specify generic parameters on types and methods.\n\n**Known Types**\n\nFor security reasons the parser does not provide access to any types except:\n* types used in arguments\n* primitive types\n* `Math`, `Array`, `Func\u003c\u003e` types\n\nTo access other types your should pass **typeResolver** parameter in **Parse** and **Evaluate** method:\n```csharp\nvar typeResolver = new KnownTypeResolver(typeof(Mathf), typeof(Time));\nCSharpExpression.Evaluate\u003cint\u003e(\"Mathf.Clamp(Time.time, 1.0f, 3.0f)\", typeResolver); \n```\nIf you want to access all types in **UnityEngine** you can pass custom **AssemblyTypeResolver** as typeResolver parameter.\n```csharp\nvar typeResolver = new AssemblyTypeResolver(typeof(UnityEngine.Application).Assembly);\n```\n\n\u003e ℹ️ For security reasons any method/property calls on **System.Type** will throw exceptions until **System.Type** is added as known type.\n\n## AOT Execution\nYou can compile and evaluate expression created by **System.Linq.Expression** and execute it in AOT environment where it is usually impossible. \n```csharp\nvar expr = (Expression\u003cFunc\u003cVector3\u003e\u003e)(() =\u003e new Vector3(1.0f, 1.0f, 1.0f));\nvar fn = expr.CompileAot();\n\nfn; // -\u003e Func\u003cVector3\u003e\nfn(); // -\u003e Vector3(1.0f, 1.0f, 1.0f)\n```\n\niOS, WebGL and most console platforms use AOT compilation which imposes following restrictions on the dynamic code execution:\n\n* only **Expression\u0026lt;Func\u0026lt;...\u0026gt;\u0026gt;** delegate type could be used with **CompileAot()**.\n* only static methods using primitives (int, float, string, object ...) are optimized for fast calls, others are called with reflection.\n* all used classes/methods/properties should be visible to [Unity's static code analyser](https://docs.unity3d.com/Manual/ScriptingRestrictions.html)\n* ⚠️ An additional preparation should be made for AOT execution platforms. This [link.xml](https://github.com/deniszykov/csharp-eval-unity3d/blob/master/src/GameDevWare.Dynamic.Expressions.Unity.2021/Assets/Plugins/GameDevWare.Dynamic.Expressions/link.xml) should be added in project's root folder. Read more about [IL code stripping](https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html) in official documentation.\n\n**See Also**\n* [AOT Exception Patterns and Hacks](https://github.com/neuecc/UniRx/wiki/AOT-Exception-Patterns-and-Hacks)\n* [Ahead of Time Compilation (AOT)](http://www.mono-project.com/docs/advanced/runtime/docs/aot/)\n\n### WebGL and iOS\n\n* Only [Func\u003c\u003e](https://msdn.microsoft.com/en-us/library/bb534960(v=vs.110).aspx) (up to 4 arguments) lambdas are supported with `CompileAot()`.\n* Instance methods calls performs slowly due reflection\n* Moderate boxing for value types (see roadmap)\n\nYou can prepare [Func\u003c\u003e](https://msdn.microsoft.com/en-us/library/bb534960(v=vs.110).aspx) lambda for AOT compilation/execution by registering it with **AotCompilation.RegisterFunc**.\n\n```csharp\nAotCompilation.RegisterFunc\u003cint, bool\u003e(); // will enable Func\u003cint, bool\u003e lambdas anywhere in expressions\n```\n\n### Unity 2020.3.2 Issues\nThis version of Unity has runtime bug related to lambda compilation. Please use following workaround for IL2CPP/AOT runtime:\n```cs\n#if ((UNITY_WEBGL || UNITY_IOS || ENABLE_IL2CPP) \u0026\u0026 !UNITY_EDITOR)\nGameDevWare.Dynamic.Expressions.AotCompilation.IsAotRuntime = true;\n#endif\n```\n\n\n**Improving Performance**\n\nYou can improve the performance of methods invocation by registering their signatures in **AotCompilation.RegisterForFastCall()**. \n\n```\n// Supports up to 3 arguments.\n// First generic argument is your class type.\n// Last generic argument is return type.\n\nAotCompilation.RegisterForFastCall\u003cInstanceT, ResultT\u003e()\nAotCompilation.RegisterForFastCall\u003cInstanceT, Arg1T, ResultT\u003e()\nAotCompilation.RegisterForFastCall\u003cInstanceT, Arg1T, Arg2T, ResultT\u003e()\nAotCompilation.RegisterForFastCall\u003cInstanceT, Arg1T, Arg2T, Arg3T, ResultT\u003e()\n```\n\nExample:\n```csharp\npublic class MyVectorMath\n{\n    public Vector4 Dot(Vector4 vector, Vector4 vector);\n    public Vector4 Cross(Vector4 vector, Vector4 vector);\n    public Vector4 Scale(Vector4 vector, float scale);    \n}\n\n// register Dot and Cross method signatures\nAotCompilation.RegisterForFastCall\u003cMyVectorMath, Vector4, Vector4, Vector4\u003e();\n// register Scale method signature\nAotCompilation.RegisterForFastCall\u003cMyVectorMath, Vector4, float, Vector4\u003e();\n```\n\n## Roadmap\n\nYou can send suggestions at support@gamedevware.com\n\n* Expression serialization (in-progress)\n* Void expressions (`System.Action` delegates) (done)\n* Parser: Delegate construction from method reference\n* Parser: Type inference for generics\t\n* Parser: Full C#6 syntax\n* Parser: Extension methods\n* Parser: Type initializers, List initializers\n* Custom editor with auto-completion for Unity\n\n## Changes\n# 2.3.0\n* fix: fixed netcore related error with enumerable.empty\u003cT\u003e\n* feature: added  optional `global` parameter to all CSharpExpression methods to allow specify global object for expression.\n* test: removed flaky test with double.tostring() comparison\n* fix: fixed typo in `arg4Name` in `CSharpExpression.ParseFunc{4}` and `CSharpExpression.ParseAction{4}`\n\n# 2.2.9\n* fix: fixed error with instantiated generic method on types (which is impossible in normal conditions, but fine for Unity AOT runtime).\n\n# 2.2.8\n* feature:made AotCompilation.IsAotRuntime is mutable, this will allow to signal for AOT runtime and suppress further checks.\n\n# 2.2.7\n* feature: added public CSharpExpression.Format method for SyntaxTreeNode\n\n# 2.2.6\n* changed order or SyntaxTreeNode fields and added \"original C# expression\" field to parsed AST.\n* refactored C# expression rendering to support null-propagation expressions, type aliases (int, byte, object ...),\n* renamed \"Render\" methods to \"FormatAsCSharp\". Now it is \"formatting\"\n* moved c# \"formatting\" methods to CSharpExpression class\n* mark old \"Parse\" functions as errors\n* mark old \"Render\" methods as obsolete\n* renamed CSharpExpressionFormatter to CSharpExpressionFormatter\n* fixed indexer experssion rendering\n* refactored NameUtils to properly render C# type names\n\n# 2.2.5\n* renamed ParseTreeNode.Lexeme to .Token\n* renamed few member of TokenType for better clarity\n* added documentation file in Unity project assets\n* changed 'propertyOrFieldName' attribute to 'name' in SyntaxTreeNode\n* renamed PropertyOfFieldBinder to MemberBinder\n* changed 'PropertyOrField' expression type to 'MemberResolve' in SyntaxTreeNode\n* added backward compatibility checks in all related classes\n\n# 2.2.4\n* added protection against wrong expressions like 'a b' which later bound as 'b'\n* fixed some tokenization errors:\n* * 'issa'scanned as 'is'[Operator] and 'sa'[Identifier], now as 'issa'\n* * '.09' scanned as '.'[Operator] and '09'[Number], now as '0.09'\n* * '0.1x' scanned as '0.1'[Number] and 'x'[Identifier], now cause error\n* added *method calls* on numbers (example 1.ToString())\n* added short number notation (example '.9' for '0.9')\n* added '@' prefix for identifiers (example '@is') https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/verbatim\n* done small Tokenizer optimization (reduced string allocation during scanning)\n\n# 2.2.3\n* added ExpressionPacker type. This type allows packing/unpacking expressions into primitive structures (Dictionaries, Arrays...). These structures  could be serialized and wired by network or stored for future use.\n* added better error message for some binding cases\n* denying call to 'Type.InvokeMember' if 'Type' is not within 'known types'.\n\n# 2.2.2\n* fixed conditional operator (a ? b : c) parsing with method call in place of 'b'\n\n# 2.2.1\n* fixed IL2CPP compilation error due _Attribute interface complilation failure\n* added few interfaces to AOT.cs file for better AOT coverage\n\n# 2.2.0\nFeatures\n* added support for void expressions (Action\u003c\u003e delegates)\n* added support of '.NET Standart 1.3' and '.NET Core 2.0' platforms\n\n# 2.1.4\n* Release version, no actual changes except readme.md\n\n# 2.1.2-rc\n### Features\n* added more descriptive message for member binding error\n* added autodoc comments for public members\n* hid `ReadOnlyDictionary` from public access\n* removed Unity WebGL #if for unsigned types. Unity's bug was fixed.\n* added support for generic types and generic methods\n* added nullable types and `?` suffix support\n```csharp\nCSharpExpression.Evaluate\u003cint?\u003e(\"default(int?)\"); // -\u003e null\n```\n* added lambda expressions. Syntax is `() =\u003e x` and `new Func(a =\u003e x)`\n* added support for expression's parameter re-mapping with lambda expression syntax:\n```csharp\nCSharpExpression.Evaluate\u003cint, int, int\u003e(\"(x,y) =\u003e x + y\", 2, 2); // -\u003e 4\n```\n* added support for `Func\u003c\u003e` lambdas for AOT environments\n* added additional constructor to Binder class\n```csharp\npublic Binder(Type lambdaType, ITypeResolver typeResolver = null);\n```\n* added `ArgumentsTree.ToString()` method\n* added aliases for build-in types. Aliases resolved during binding phase inside `Binder.Bind()` method.\n```csharp\nCSharpExpression.Evaluate\u003cint\u003e(\"int.MaxValue\");\n```\n\n### Bugs\n* fixed error with wrongly resolved types (only by name) in KnownTypeResolver\n* fixed bug with ACCESS_VIOLATION on iOS (Unity 5.x.x IL2CPP)\n* fixed few Unity 3.4 related errors in code\n* fixed 'new' expression parsed with error on chained calls new a().b().c()\n* fixed some cases of lifted binary/unary/conversion operations\n* fixed some AOT'ed operations on System.Boolean type\n* fixed null-propagation chains generate invalid code\n* fixed some edge cases of resolving nested generic types\n* fixed error with types without type.FullName value\n* fixed Condition operator types promotion\n* fixed Power operator types promotion and null-lifting\n* fixed enum constants threated as underlying types during binary/unary operations\n\n\n### Breaking changes in 2.0\n* ParserNode renamed to ParseTreeNode\n* ExpressionTree renamed to SyntaxTreeNode\n* ExpressionBuilder renamed to Binder\n* ITypeResolutionService renamed to ITypeResolver\n* ITypeResolver.GetType removed\n* ITypeResolver now could be configured with TypeDiscoveryOptions\n\n# 1.0.1.11\n* fixed error them creating nullable types via \"new\" keyword\n* fixed Embedded Resource addressing problem on IL2CPP WebGL (localized error messages)\n* fixed some cases of nullable types binding\n* fixed Enum member resolution\n* added Power(``**``) operator into C# syntax\n```csharp\nCSharpExpression.Evaluate\u003cint\u003e(\"2 ** 2\"); // -\u003e 4\n```\n* added TypeResolutionService chaining for better KnownTypes re-use\n\n# 1.0.1.10\n* fixed error with nulled constants after first call for AOT-ted expression.\n* added ToString() impl for ExpressionTree\n\n# 1.0.1.9\n* added [Null-conditional Operators](https://msdn.microsoft.com/en-us/library/dn986595.aspx) (example: a.?b.?.c)\n* fixed array indexing expressions\n* added array types support in type expressions ('convert', 'typeof', 'is' etc.)\n\n## Installation\n[Nuget](https://www.nuget.org/packages/GameDevWare.Dynamic.Expressions/):\n```\nInstall-Package GameDevWare.Dynamic.Expressions\n```\nUnity:\n\n[Package at Unity Asset Store](https://assetstore.unity.com/packages/tools/visual-scripting/c-eval-56706)\n\n## Contacts\nPlease send any questions at support@gamedevware.com\n\n## License\n\n[Asset Store Terms of Service and EULA](LICENSE.md)\n","funding_links":[],"categories":["Open Source Repositories","C\\#"],"sub_categories":["Utilities"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeniszykov%2Fcsharp-eval-unity3d","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeniszykov%2Fcsharp-eval-unity3d","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeniszykov%2Fcsharp-eval-unity3d/lists"}