ExpressionEvaluator icon indicating copy to clipboard operation
ExpressionEvaluator copied to clipboard

A Simple Math and Pseudo C# Expression Evaluator in One C# File. Can also execute small C# like scripts

Results 31 ExpressionEvaluator issues
Sort by recently updated
recently updated
newest added

&& || operator not short-circuit as C# did

[{"_id":"6380b8b15ae95c7a2230138f","body":"Hello @PingMyCat. Thanks to reporting this issue and sorry for my late response.\r\nI will look what I can do for this but it' looks tricky as it is link to issues #56 and #81.\r\nSo I don't know if it's possible to correct this bug without breaking others corrections.\r\n\r\nI am also currently investigating the possibility to compile to expression tree. see(#58).\r\nIf I manage to make it work it should manage automatically this kind of issues.\r\nThe drawdown is that it's a big rewrite of ExpressionEvaluator so it take time, and a lot of functionalities that are based on the on the fly evaluation and duck typing need to be rewrite and\/or manage\/call differently.","issue_id":1660251387217,"origin_id":905205330,"user_origin_id":15038327,"create_time":1629870966,"update_time":1629870966,"id":1669380273050,"updated_at":"2022-11-25T12:44:33.049000Z","created_at":"2022-11-25T12:44:33.049000Z"},{"_id":"6380b8b15ae95c7a22301390","body":"Your work is amazing. It's the best embedded script solution I found. Wish to see 2.0 soon. My project depend on the \"on the fly\" feature. Wish you can make it more.\r\n\r\nBest reguards,\r\n\r\nSnowCat\r\n[<Time is ocean in the storm>]\r\n\r\n\u5728 2021\u5e748\u670825\u65e5\uff0c13:56\uff0cCoding Seb ***@***.***> \u5199\u9053\uff1a\r\n\r\n\ufeff\r\n\r\nHello @PingMyCat<https:\/\/github.com\/PingMyCat>. Thanks to reporting this issue and sorry for my late response.\r\nI will look what I can do for this but it' looks tricky as it is link to issues #56<https:\/\/github.com\/codingseb\/ExpressionEvaluator\/issues\/56> and #81<https:\/\/github.com\/codingseb\/ExpressionEvaluator\/issues\/81>.\r\nSo I don't know if it's possible to correct this bug without breaking others corrections.\r\n\r\nI am also currently investigating the possibility to compile to expression tree. see(#58<https:\/\/github.com\/codingseb\/ExpressionEvaluator\/issues\/58>).\r\nIf I manage to make it work it should manage automatically this kind of issues.\r\nThe drawdown is that it's a big rewrite of ExpressionEvaluator so it take time, and a lot of functionalities that are based on the on the fly evaluation and duck typing need to be rewrite and\/or manage\/call differently.\r\n\r\n\u2014\r\nYou are receiving this because you were mentioned.\r\nReply to this email directly, view it on GitHub<https:\/\/github.com\/codingseb\/ExpressionEvaluator\/issues\/114#issuecomment-905205330>, or unsubscribe<https:\/\/github.com\/notifications\/unsubscribe-auth\/AVHQIYZ4SH6XS2ZBXZSYFODT6SAYDANCNFSM5CJFJJ4A>.\r\nTriage notifications on the go with GitHub Mobile for iOS<https:\/\/apps.apple.com\/app\/apple-store\/id1477376905?ct=notification-email&mt=8&pt=524675> or Android<https:\/\/play.google.com\/store\/apps\/details?id=com.github.android&utm_campaign=notification-email>.\r\n","issue_id":1660251387217,"origin_id":905210008,"user_origin_id":89064547,"create_time":1629871484,"update_time":1629871484,"id":1669380273052,"updated_at":"2022-11-25T12:44:33.052000Z","created_at":"2022-11-25T12:44:33.052000Z"}] comment

x = 100; if( false && (x=50) > 100 ) return 0; return x; // --------------------------// x = 100; if( true || (x=50) < 0 ) return x; return 0;...

bug

`OptionForceIntegerNumbersEvaluationsAsDoubleByDefault` leads to not recognising three parameter version of Math.Round

[{"_id":"6380af05bc25e83db00a94d7","body":"Yes of course as in C# You can't put a `double` as second argument in `Math.Round(double,int,MidpointRounding)`.\r\nAnd when you set `OptionForceIntegerNumbersEvaluationsAsDoubleByDefault = true` it's what you are doing so it's like `Math.Round(1d,0d,MidpointRounding.AwayFromZero)`. This is not possible in C#.\r\nThe bug in version 1.4.30.0 is that it forced a conversion of numbers where C# do not. And so it selected sometime wrong methods because of conversions that shouldn't append automatically. So I think current version is more accurate as it is more C# like. I am sorry but there is no way to manage all these cases directly in the code of EE without breaking something or creating very specific conditions that should not be in the code of EE but customized by the user.\r\n\r\nSo for your case there are 5 solutions to manage it.\r\n1. You can use the build in and shorter version of `Round` (without `Math`, [description here](https:\/\/github.com\/codingseb\/ExpressionEvaluator\/wiki\/Variables-and-Functions#standard-functions)) it still make the conversion for you.\r\n```c#\r\nRound(1,0,MidpointRounding.AwayFromZero)\r\n```\r\n2. You can cast back the second parameter to int\r\n```c#\r\nMath.Round(1,(int)0,MidpointRounding.AwayFromZero)\r\n```\r\n3. You can manage the call of `Math.Round` in the event:\r\n```c#\r\nevaluator.PreEvaluateFunction+= PreEvaluateFunction;\r\nprivate void PreEvaluateFunction(object sender, FunctionEvaluationEventArg e)\r\n{\r\n if(e.Name.Equals(\"Round\") && e.This is ClassOrEnumType classOrTypeName && classOrTypeName.Type == typeof(Math))\r\n \/\/ use e.EvaluateArgs() that you can cast and use how you want.\r\n \/\/ and return the result in e.Value\r\n}\r\n```\r\n4. You can specify yourself how you want to cast parameters in specific case with the event : (There is no documentation for this one yet, just a talk in an other issue that I didn't found again. but everything is manageable with the e argument)\r\n```c#\r\nevaluator.EvaluateParameterCast += EvaluateParameterCast;\r\n```\r\n\r\n5. You keep : `OptionForceIntegerNumbersEvaluationsAsDoubleByDefault = false` and use the C# writing:\r\n```c#\r\nMath.Round(1d,0,MidpointRounding.AwayFromZero)\r\n```","issue_id":1660251387220,"origin_id":892954199,"user_origin_id":15038327,"create_time":1628109110,"update_time":1628109556,"id":1669377797720,"updated_at":"2022-11-25T12:03:17.720000Z","created_at":"2022-11-25T12:03:17.720000Z"},{"_id":"6380af05bc25e83db00a94d8","body":"Thanks, it works well with:\r\n```cs\r\nevaluator.EvaluateParameterCast += Evaluator_EvaluateParameterCast;\r\n\r\n[...]\r\n\r\nprivate static void Evaluator_EvaluateParameterCast(object? sender, ParameterCastEvaluationEventArg e)\r\n{\r\n if (e.MethodInfo.DeclaringType == typeof(Math) && e.MethodInfo.Name == \"Round\" && e.ParameterType == typeof(int) && e.OriginalArg is double original)\r\n {\r\n e.Argument = (int) original;\r\n }\r\n}\r\n```\r\n","issue_id":1660251387220,"origin_id":893284135,"user_origin_id":25565697,"create_time":1628153453,"update_time":1628153453,"id":1669377797724,"updated_at":"2022-11-25T12:03:17.723000Z","created_at":"2022-11-25T12:03:17.723000Z"}] comment

The code ``` var evaluator = new ExpressionEvaluator() { OptionForceIntegerNumbersEvaluationsAsDoubleByDefault = true }; string expression = "Math.Round(1,0,MidpointRounding.AwayFromZero)"; Console.WriteLine(expression); Console.WriteLine(evaluator.Evaluate(expression)); ``` gives the error > [System.Math] object has no Method named...

explanation

[suggestion] anonymous array declaration, relax object syntax (JS/Json syntax)

[{"_id":"6380b492bc25e83db00a993f","body":"Good idea. I was just thinking about this these days.\r\nA JS\/JSON syntax could be great.\r\n\r\nI will probably create a few options for this.\r\n\r\nlike :\r\n```c#\r\nOptionJsonSyntaxForAnonymousObjectInit = true;\r\n\/\/ for\r\nx = new {a: 10, b: 20, c: 30}\r\n\/\/ ...\r\n\r\nOptionAllowStringForPropertiesInAnonymousObjectInit = true;\r\n\/\/ for\r\nx = new {\"a\": 10, \"b\": 20, \"c\": 30}\r\n\r\nOptionAllowToOmitInitializationKeywordForAnonymousObjectInit = true;\r\n\/\/ for\r\nx = {\"a\": 10, \"b\": 20, \"c\": 30}\r\n```\r\n> `InitSimpleObjet` (we should rename that to `InitSimpleObject`) \r\n\r\nOops this is my French that popup.\r\n","issue_id":1660251387223,"origin_id":799176884,"user_origin_id":15038327,"create_time":1615792555,"update_time":1615792555,"id":1669379218531,"updated_at":"2022-11-25T12:26:58.530000Z","created_at":"2022-11-25T12:26:58.530000Z"},{"_id":"6380b492bc25e83db00a9940","body":"@codingseb great idea. To keep consistency with newly added `OptionNewKeywordAliases` and `OptionScriptEndOfExpression` and allow for a broader range of usages I think this would be better as:\r\n\r\n```csharp\r\nEE.OptionSyntaxRules.ObjectInitPropertyValueDelimiter = string[] {'='}\r\n .ObjectInitAllowPropertyAsString = false\r\n .KeywordNew = string[] {'new'}\r\n .StatementTerminalPunctuators = string[] {';'}\r\n```\r\n\r\n- Introduce class `OptionSyntaxRules` which would hold all syntactic options to improve discoverability by end user (instead of going trough all options I can just list members of this class).\r\n- By default all options would be `string[]` (where makes sense) to support free mix and match of multiple styles.\r\n\r\n```csharp\r\nOptionSyntaxRules.ObjectInitPropertyValueDelimiter = new {\"=\", \":\"};\r\n\r\nx = new {a: 10, b = 20}\r\n```\r\n\r\n- Naming of members would follow _noun first_ pattern.\r\n- `StatementTerminalPunctuators` could replace `OptionScriptEndOfExpression`, as semicolons are formally called punctuators in c++ spec:\r\n\r\n> The lexical representation of C++ programs includes a number of preprocessing tokens which are used in the syntax of the preprocessor or are converted into tokens for operators and **punctuators**\r\n\r\n- `KeywordNew` could replace `OptionNewKeywordAliases` 'aliases' here (at least for me) sounds like we always keep and enforce original `new` and only allow to add aliases for it, which in fact is not true as we already allow for example:\r\n\r\n```csharp\r\nOptionNewKeywordAliases = new {\"->\"};\r\n```\r\nin which case only `->` can be used instead of `new` and `new` is not recognized as a keyword.","issue_id":1660251387223,"origin_id":799253285,"user_origin_id":10260230,"create_time":1615799705,"update_time":1615799794,"id":1669379218534,"updated_at":"2022-11-25T12:26:58.534000Z","created_at":"2022-11-25T12:26:58.534000Z"},{"_id":"6380b492bc25e83db00a9941","body":"I am currently reflecting about this. \r\nI try to start the implementation. \r\n\r\nI agree that Options need to be refactor to offer a better intellisense experience. \r\nBut as it introduce breaking changes. It means that it will be included in next major version and consequently Json\/JS syntax stuff too. So I will work on this in branch `MakeScriptEvaluationMoreFlexible` with others stuffs that need to be finish in it.\r\n\r\nAlso, for the arrays options I am not sure that it will be possible everywhere without changing a lot of stuffs (and taking a lot of time) so to go forward with this, maybe I will firstly propose simpler version of some options. I mean maybe just a simple string option to start.","issue_id":1660251387223,"origin_id":804236380,"user_origin_id":15038327,"create_time":1616432818,"update_time":1616432903,"id":1669379218537,"updated_at":"2022-11-25T12:26:58.537000Z","created_at":"2022-11-25T12:26:58.537000Z"},{"_id":"6380b492bc25e83db00a9942","body":"I already published an alpha version for v.1.5 from branch `MakeScriptEvaluationMoreFlexible` ([See on nuget](https:\/\/www.nuget.org\/packages\/CodingSeb.ExpressionEvaluator\/1.5.0-alpha0001)) to test some early features.\r\n[We can test it here](https:\/\/dotnetfiddle.net\/qpQEei)\r\nIt already contains some cool script customization stuff and support Json syntax.\r\n\r\n```c#\r\nevaluator.OptionsSyntaxRules.IsNewKeywordForAnonymousExpandoObjectOptional = true;\r\nevaluator.OptionsSyntaxRules.InitializerPropertyValueSeparators = new[] { \"=\", \":\" };\r\nevaluator.OptionsSyntaxRules.InitializerAllowStringForProperties = true;\r\nevaluator.OptionsSyntaxRules.AllowSimplifiedCollectionSyntax = true;\r\n\r\n\/\/ And we can also use (To do a List<object> in place of a object[]): \r\nevaluator.OptionsSyntaxRules.SimplifiedCollectionMode = SimplifiedCollectionMode.List;\r\n```\r\n\r\n*Take note that it introduce some breaking changes with previous versions and some others breaking changes can still happend until the official 1.5.0.0 release*\r\n*For now there is no documentation for new features*","issue_id":1660251387223,"origin_id":848020487,"user_origin_id":15038327,"create_time":1621959675,"update_time":1621961089,"id":1669379218540,"updated_at":"2022-11-25T12:26:58.540000Z","created_at":"2022-11-25T12:26:58.540000Z"},{"_id":"6380b492bc25e83db00a9943","body":"Great news @codingseb thanks for all the effort you are putting into this!","issue_id":1660251387223,"origin_id":848621477,"user_origin_id":10260230,"create_time":1622021604,"update_time":1622021604,"id":1669379218543,"updated_at":"2022-11-25T12:26:58.542000Z","created_at":"2022-11-25T12:26:58.542000Z"}] comment

Currently EE can evaluate anonymous object declarations: ```csharp x = new {a = 10, b = 20, c = 30} ``` `property = value` is enforced in method `InitSimpleObjet` (we...

enhancement

[suggestion] Implement async / await

[{"_id":"6380b0eabc25e83db00a9610","body":"Yes it would be great.\r\nI need some reflection on how to do it.\r\nI keep it open as a todo \ud83d\ude03","issue_id":1660251387226,"origin_id":760216033,"user_origin_id":15038327,"create_time":1610632975,"update_time":1610632975,"id":1669378282205,"updated_at":"2022-11-25T12:11:22.204000Z","created_at":"2022-11-25T12:11:22.204000Z"},{"_id":"6380b0eabc25e83db00a9611","body":"Core of the problem here is that we need to \"await\" `EventHandler` which we can't do as it returns void. Something like DefferedEvents would be needed here - https:\/\/pedrolamas.github.io\/DeferredEvents\/\r\n\r\nwhat do you think?","issue_id":1660251387226,"origin_id":760392134,"user_origin_id":10260230,"create_time":1610649589,"update_time":1610649589,"id":1669378282209,"updated_at":"2022-11-25T12:11:22.209000Z","created_at":"2022-11-25T12:11:22.209000Z"},{"_id":"6380b0eabc25e83db00a9612","body":"+1 to this feature","issue_id":1660251387226,"origin_id":890121991,"user_origin_id":840042,"create_time":1627675094,"update_time":1627675094,"id":1669378282213,"updated_at":"2022-11-25T12:11:22.212000Z","created_at":"2022-11-25T12:11:22.212000Z"}] comment

~~Currently this is not included in todo / roadmap document here~~ - [https://github.com/codingseb/ExpressionEvaluator/wiki/ExpressionEvaluator-Todo-List](https://github.com/codingseb/ExpressionEvaluator/wiki/ExpressionEvaluator-Todo-List) Implementing `async` / `await` (with priority on `await`) would greatly increase flexibility of EE. C# is becoming...

enhancement
Need Investigations

Named arguments support

[{"_id":"6380b8a570db72139b1151b4","body":"Hello @ko-vasilev. Thanks for this issue.\r\nFor now named arguments are not supported. \r\nI think it could be nice to have.\r\nI am on vacation for the next 2 weeks. \r\nI will look how to implement it when I come back.","issue_id":1660251387228,"origin_id":883195317,"user_origin_id":15038327,"create_time":1626768871,"update_time":1626768871,"id":1669380261629,"updated_at":"2022-11-25T12:44:21.629000Z","created_at":"2022-11-25T12:44:21.629000Z"},{"_id":"6380b8a570db72139b1151b5","body":"@codingseb enjoy your vacation :)\r\n","issue_id":1660251387228,"origin_id":883324443,"user_origin_id":10260230,"create_time":1626781254,"update_time":1626781254,"id":1669380261632,"updated_at":"2022-11-25T12:44:21.632000Z","created_at":"2022-11-25T12:44:21.632000Z"}] comment

Hello, Couldn't find anything about this - but is there a support for named optional arguments in function calls? Here is something I'm trying to do: ``` public class Program...

enhancement

[suggestion] allow remapping of "new"

[{"_id":"6380bea970db72139b115799","body":"I will do it with #73 and it will be part of the next \"Script customization\" version of EE","issue_id":1660251387231,"origin_id":765191823,"user_origin_id":15038327,"create_time":1611300065,"update_time":1611300164,"id":1669381801239,"updated_at":"2022-11-25T13:10:01.239000Z","created_at":"2022-11-25T13:10:01.239000Z"},{"_id":"6380bea970db72139b11579a","body":"I'm a fan of sticking to the c # standard. then you can know exactly what you can and cannot do. ( just googling it ). If not, things can be complicated and messy by having too many parameters, too many interpretations, too many requirements.","issue_id":1660251387231,"origin_id":870814552,"user_origin_id":16392893,"create_time":1624990785,"update_time":1624990785,"id":1669381801243,"updated_at":"2022-11-25T13:10:01.242000Z","created_at":"2022-11-25T13:10:01.242000Z"}] comment

This is a followup suggestion for #73. Now to instantiate, only standard c# syntax can be used (on right hand of expression): ```csharp myList = new List(); ``` Keyword `new`...

enhancement

[suggestion] return instead of throw

[{"_id":"6380bc954b97542c9a30bd68","body":"@codingseb what do you think about this? Should you give this a go, I can prepare a PR. This is a breaking change but should be an easy one to migrate to.","issue_id":1660251387233,"origin_id":764919994,"user_origin_id":10260230,"create_time":1611261266,"update_time":1611261266,"id":1669381269562,"updated_at":"2022-11-25T13:01:09.562000Z","created_at":"2022-11-25T13:01:09.562000Z"},{"_id":"6380bc954b97542c9a30bd69","body":"if you have A PR you can submit it.\r\nBut for this issue, I think we need a way to keep compatibility with Exceptions. \r\nCould be an option and\/or override of methods `EE.Evaluate()` and `EE.ScriptEvaluate()`.\r\nAlso take note that a bunch of tests are relying on this.\r\nSome projects too.\r\n\r\nWe also need to take care of the way it behave when [Evaluate() or ScriptEvaluate()](https:\/\/github.com\/codingseb\/ExpressionEvaluator\/wiki\/Variables-and-Functions#standard-functions) method are used in Expressions or scripts with respectively options [OptionEvaluateFunctionActive](https:\/\/github.com\/codingseb\/ExpressionEvaluator\/wiki\/Options#OptionEvaluateFunctionActive) and [OptionScriptEvaluateFunctionActive](https:\/\/github.com\/codingseb\/ExpressionEvaluator\/wiki\/Options#OptionScriptEvaluateFunctionActive).","issue_id":1660251387233,"origin_id":765181952,"user_origin_id":15038327,"create_time":1611298922,"update_time":1611298922,"id":1669381269565,"updated_at":"2022-11-25T13:01:09.564000Z","created_at":"2022-11-25T13:01:09.564000Z"},{"_id":"6380bc954b97542c9a30bd6a","body":"I have done some tests on the use of try catch and is not more expensive or heavy.\r\nby definition an exception should hardly ever happen. only if there was a syntax error ... but that shouldn't happen often","issue_id":1660251387233,"origin_id":870086147,"user_origin_id":16392893,"create_time":1624919008,"update_time":1624919008,"id":1669381269571,"updated_at":"2022-11-25T13:01:09.571000Z","created_at":"2022-11-25T13:01:09.571000Z"}] comment

Now when invalid token / expression is encountered during evaluation `throw` statement is used to notify user something went wrong. In scenarios where EE is "proxied" behind some interface (for...

enhancement
Need Investigations

[question] Declare methods in scripts

[{"_id":"6380b9b770db72139b115311","body":"It's not directly possible with the standard syntax of a method for now. But it's possible to declare some multiline lambda like function. I know it's not well documented. \r\nBut you can write something like :\r\n```c#\r\nvar myMethod = (a) => \r\n{\r\n \/\/Do something with a\r\n};\r\n\r\nmyMethod(1);\r\n```\r\n\r\nI will add some docs about this.","issue_id":1660251387235,"origin_id":754155152,"user_origin_id":15038327,"create_time":1609786842,"update_time":1609787996,"id":1669380535740,"updated_at":"2022-11-25T12:48:55.740000Z","created_at":"2022-11-25T12:48:55.740000Z"},{"_id":"6380b9b770db72139b115312","body":"Also take note that variables declared in a lambda are scoped (only available) in the lambda block.\r\nBut for now variables declared in other types of blocks are not scoped to their block. \r\n\r\n```c#\r\nvar x = 1;\r\n\r\nvar myMethod = () => \r\n{\r\n var a = x + 1;\r\n};\r\n\r\nmyMethod();\r\n\r\n\/\/ x will be available here but not a.\r\n```\r\nBut\r\n```c#\r\n\r\nvar x = 1;\r\n\r\nif(x == 1)\r\n{\r\n var a = x+1;\r\n}\r\n\r\n\/\/ both x and a will be available here.\r\n```\r\n\r\nIt's in my todo list to scope variables in each blocks to behave more like in C# but in current version (1.4.18.0) it's not done.","issue_id":1660251387235,"origin_id":754171716,"user_origin_id":15038327,"create_time":1609788770,"update_time":1609793626,"id":1669380535743,"updated_at":"2022-11-25T12:48:55.742000Z","created_at":"2022-11-25T12:48:55.742000Z"},{"_id":"6380b9b770db72139b115313","body":"Thanks for the reply, multiline lambda will do for now. For the sake of backwards compatibility it would be nice to have another setting to toggle this.\r\n\r\n> It's in my todo list to scope variables in each blocks to behave more like in C# but in current version (1.4.18.0) it's not done.\r\n\r\nIf possible it would be fine to leave this open for now, for other newcomers around, I guess this would be a frequent question.","issue_id":1660251387235,"origin_id":754178717,"user_origin_id":10260230,"create_time":1609789613,"update_time":1609789654,"id":1669380535745,"updated_at":"2022-11-25T12:48:55.744000Z","created_at":"2022-11-25T12:48:55.744000Z"},{"_id":"6380b9b770db72139b115314","body":"> it would be nice to have another setting to toggle this. \r\n\r\nYes good idea. I will add an option for this.\r\n\r\n> If possible it would be fine to leave this open for now, for other newcomers around, I guess this would be a frequent question.\r\n\r\nYes I leave this open.","issue_id":1660251387235,"origin_id":754181787,"user_origin_id":15038327,"create_time":1609789979,"update_time":1609828201,"id":1669380535749,"updated_at":"2022-11-25T12:48:55.748000Z","created_at":"2022-11-25T12:48:55.748000Z"},{"_id":"6380b9b770db72139b115315","body":"I added a small documentation about [using lambda for method simulation here](https:\/\/github.com\/codingseb\/ExpressionEvaluator\/wiki\/Variables-and-Functions#simulate-function-and-methods-declaration-with-lambda-and-multiline-lambda)\r\n\r\nI always keep this issue open","issue_id":1660251387235,"origin_id":784161423,"user_origin_id":15038327,"create_time":1614082776,"update_time":1614082789,"id":1669380535752,"updated_at":"2022-11-25T12:48:55.752000Z","created_at":"2022-11-25T12:48:55.752000Z"},{"_id":"6380b9b770db72139b115316","body":"Great job, thanks!","issue_id":1660251387235,"origin_id":784167529,"user_origin_id":10260230,"create_time":1614083445,"update_time":1614083445,"id":1669380535754,"updated_at":"2022-11-25T12:48:55.754000Z","created_at":"2022-11-25T12:48:55.754000Z"}] comment

Hi, I'm not quite sure if I missed this in the docs, but is something like this possible? ```csharp [void] myMethod([int] a) { } myMethod(1); ``` running the above from...

question
documentation
explanation

[suggestion] Allow bracketless version of if/while/for/foreach

[{"_id":"6380b4a04b97542c9a30b4bc","body":"Yes it's a good idea. I will look how to integrate this kind of option.\r\n\r\nTake note that \"EE\" also support one expression blocks for these keywords :\r\n```c#\r\nfor(x = 0; x < 5;x++)\r\n result += $\"{x},\";\r\n\/\/...\r\nwhile(somethingIsTrue)\r\n DoSomethingElse();\r\n\/\/...\r\nforeach(stuff in collectionOfThings)\r\n DoSomethingWith(stuff);\r\n\/\/...\r\nif(y != 0)\r\n result = 1;\r\nelse if(x == 0)\r\n result = 2;\r\nelse\r\n result = 4;\r\n```\r\nSo in in these cases, if we want to remove brackets we need a at least a character to separate the keyword condition expressions of it's \"action\" expression.\r\n\r\nI could make it an `enum` option in combination with a \"separator\" property to specify how to separate these two parts.\r\nIt could be `':'` by default to get a little closer to python like scripting. \r\n\r\nThe idea :\r\n```C#\r\npublic enum OptionSyntaxForScriptKeywords\r\n{\r\n CScharpSyntax, \/\/ ScriptKeywordsSeparator not used here\r\n OptionalParenthesesAndMandatorySeparatorWithoutCurlyBrackets,\r\n OptionalParenthesesAndAlwaysMandatorySeparator\r\n}\r\n\r\n\/\/ ... in ExpressionEvaluator ...\r\npublic OptionSyntaxForScriptKeywords OptionSyntaxForScriptKeywords { get; set; } = OptionSyntaxForScriptKeywords.CScharpSyntax;\r\n\r\npublic string ScriptKeywordsSeparator { get; set; } = \":\";\r\n```\r\nSo stuff like this could be possible : \r\n```c#\r\nif x > 2:\r\n DoSomething();\r\n\r\n\/\/ or\r\nif x > 2:\r\n{\r\n \/\/ Do a lot of stuff\r\n}\r\n```\r\n\r\n_(Just keep in mind that the first goal of EE is to be as near as possible of C# by default)_ \r\n \r\nWe could also reflect later for an other option to do blocks with indentation in place of curly brackets. But I don't know what it would imply in EE code for now.","issue_id":1660251387237,"origin_id":755191429,"user_origin_id":15038327,"create_time":1609925766,"update_time":1609925955,"id":1669379232432,"updated_at":"2022-11-25T12:27:12.432000Z","created_at":"2022-11-25T12:27:12.432000Z"},{"_id":"6380b4a04b97542c9a30b4bd","body":"I've took a quick peek at the regexes currently being used to describe bracketless keywords but I'm not sure how hard would it be to implement the proposed change. Being C# first is definitely great but allowing for deriving hyperspecific languages from that with a few options is another great feature of EE and this would further improve the situation.\r\n\r\nI think that setting default delimiter to : instead of whitespace is wise as it would probably be more commonly used.\r\n\r\nExamples at the bottom look really great! ","issue_id":1660251387237,"origin_id":755352461,"user_origin_id":10260230,"create_time":1609945559,"update_time":1609945592,"id":1669379232435,"updated_at":"2022-11-25T12:27:12.435000Z","created_at":"2022-11-25T12:27:12.435000Z"},{"_id":"6380b4a04b97542c9a30b4be","body":"Just a note, instead of:\r\n\r\n```csharp\r\npublic enum OptionSyntaxForScriptKeywords\r\n{\r\n CScharpSyntax, \/\/ ScriptKeywordsSeparator not used here\r\n OptionalParenthesesAndMandatorySeparatorWithoutCurlyBrackets,\r\n OptionalParenthesesAndAlwaysMandatorySeparator\r\n}\r\n```\r\n\r\nconsider:\r\n\r\n```csharp\r\nstring keywordHeadParenthesesStart = \"(\";\r\nstring keywordHeadParenthesesEnd = \")\";\r\n\r\nstring keywordBodyParenthesesStart = \"{\";\r\nstring keywordBodyParenthesesEnd = \"}\";\r\n\r\n\r\npublic enum OptionSyntaxKeywordExpression\r\n{\r\n MandatoryParentheses,\r\n OptionalParentheses\r\n}\r\n\r\nOptionSyntaxKeywordExpression keywordHeadParenthesesStyle = OptionSyntaxKeywordExpression.MandatoryParentheses;\r\nOptionSyntaxKeywordExpression keywordBodyParenthesesStyle = OptionSyntaxKeywordExpression.MandatoryParentheses;\r\n```\r\n\r\n_Another possibility here would be expression\/statement instead of head\/body._\r\n\r\nMain point of this is to keep naming simple and language agnostic and allow for all possible permutations of these two styles.\r\nHence:\r\n\r\n```csharp\r\n\/\/ 1. headStyle is mandatory and body style is mandatory\r\nif (expr) {\r\n statement\r\n}\r\n\r\n\/\/ 2. headStyle is optional and body style is mandatory\r\nif expr : {\r\n statement\r\n}\r\n\r\n\/\/ 3. headStyle is optional and body style is optional\r\nif expr : statement\r\n\r\n\/\/ 4. headStyle is mandatory and body style is optional\r\nif (expr) statement\r\n```\r\nAt `style 1` `keywordHeadParenthesesStart`, `keywordHeadParenthesesEnd`, `keywordBodyParenthesesStart ` and `keywordBodyParenthesesEnd` are at their default (proposed) values.\r\nAt `style 2` `keywordHeadParenthesesStart = \" \"` and `keywordHeadParenthesesEnd = \":\"`\r\nAt `style 3` all four values are `\" \"`\r\n\r\nBy `\" \"` I mean a token consisting of 1..N consecutive whitespace \/ new line characters (\\n, \\r\\n, \\r) - any combination of these.\r\n\r\nDo you think this would be possible?\r\n\r\n\r\n","issue_id":1660251387237,"origin_id":755653336,"user_origin_id":10260230,"create_time":1609965314,"update_time":1609965348,"id":1669379232440,"updated_at":"2022-11-25T12:27:12.439000Z","created_at":"2022-11-25T12:27:12.439000Z"},{"_id":"6380b4a04b97542c9a30b4bf","body":"Yes your solution is more flexible and the language agnostic style is good.\r\nI think it is possible but it will take some refactoring of the script part first to allow this.\r\nFor now the script part is more rigid than the expression part.\r\n\r\nI will take this as the next improvement of the lib.","issue_id":1660251387237,"origin_id":755951850,"user_origin_id":15038327,"create_time":1610006291,"update_time":1610006291,"id":1669379232443,"updated_at":"2022-11-25T12:27:12.443000Z","created_at":"2022-11-25T12:27:12.443000Z"},{"_id":"6380b4a04b97542c9a30b4c0","body":"OK I am currently working on this.\r\nAnd your solution is good but I can not implement it in this strict manner.\r\nHere a few reasons :\r\n1. I will need a notion of brackets and a notion separator for head and body separation. This because brackets can be nested `((something) - (otherThing))` and a separator not so the parsing process is different.\r\n2. We need at least one of these 2 notions to be mandatory otherwise it is very hard to know what is the head and what is the body in some cases.\r\n3. The parsing process for the different kind of syntaxes of the head part is different of the parsing process of the different kind of syntaxes for the body (especially if we want to be able to use indentation for body blocks like in python).\r\n\r\nAlso take note that this is include in a refactoring of the script evaluation part of EE to be more flexible.\r\nI also try to add the following features : \r\n1. An option to chose how to separate expressions `;` or something else like end of line.\r\n2. A way to redefine scripts keywords or create a custom one\r\n\r\nSo here is what I came up with so far : \r\n(I try to be language agnostic but also to prevent syntax evaluation conflicts or errors so it's a little bit different of your proposition)\r\n```c#\r\npublic enum SyntaxForHeadExpressionInScriptBlocksKeywords\r\n{\r\n HeadBrackets,\r\n SeparatorBetweenHeadAndBlock,\r\n Both,\r\n Any\r\n}\r\n\r\npublic enum SyntaxForScriptBlocksIdentifier\r\n{\r\n OptionalBracketsForStartAndEndWhenSingleStatement,\r\n MandatoryBracketsForStartAndEnd,\r\n Indentation\r\n}\r\n\r\n\/\/ ...\r\n\r\n\/\/\/ <summary>\r\n\/\/\/ To specify the character or string that begin the head statements of script blocks keywords (if, else if, for, foreach while, do.. while)\r\n\/\/\/ Default value : <c>\"(\"<\/c>\r\n\/\/\/ <\/summary>\r\npublic string OptionScriptBlocksKeywordsHeadStatementsStartBracket { get; set; } = \"(\";\r\n\r\n\/\/\/ <summary>\r\n\/\/\/ To specify the character or string that end the head statements of script blocks keywords (if, else if, for, foreach while, do.. while)\r\n\/\/\/ Default value : <c>\")\"<\/c>\r\n\/\/\/ <\/summary>\r\npublic string OptionScriptBlocksKeywordsHeadExpressionEndBracket { get; set; } = \")\";\r\n\r\n\/\/\/ <summary>\r\n\/\/\/ To specify the character or string that separate the head statements and the block statements of script blocks keywords (if, else if, for, foreach while, do.. while)\r\n\/\/\/ Default value : <c>\":\"<\/c>\r\n\/\/\/ <\/summary>\r\npublic string OptionScriptBlockKeywordsHeadExpressionAndBlockSeparator { get; set; } = \":\";\r\n\r\n\/\/\/ <summary>\r\n\/\/\/ Specify how to detect the separation between head expression and the block of code is made in script block keyword (if, else if, for, foreach while, do.. while)\r\n\/\/\/ Default value : <c>HeadBrackets<\/c>\r\n\/\/\/ <\/summary>\r\npublic SyntaxForHeadExpressionInScriptBlocksKeywords OptionSyntaxForHeadExpressionInScriptBlocksKeywords { get; set; } = SyntaxForHeadExpressionInScriptBlocksKeywords.HeadBrackets;\r\n\r\n\/\/\/ <summary>\r\n\/\/\/ To specify the character or string that start a block of code used in script blocks keywords (if, else if, for, foreach while, do.. while) and multiline lambda.\r\n\/\/\/ Default value : <c>\"{\"<\/c>\r\n\/\/\/ <\/summary>\r\npublic string OptionScriptBlockStartBrackets { get; set; } = \"{\";\r\n\r\n\/\/\/ <summary>\r\n\/\/\/ To specify the character or string that end a block of code used in script blocks keywords (if, else if, for, foreach while, do.. while) and multiline lambda.\r\n\/\/\/ Default value : <c>\"}\"<\/c>\r\n\/\/\/ <\/summary>\r\npublic string OptionScriptBlockEndBrackets { get; set; } = \"}\";\r\n\r\n\/\/\/ <summary>\r\n\/\/\/ Specify the syntax to use to detect a block of code in script blocks keywords (if, else if, for, foreach while, do.. while) and multiline lambda\r\n\/\/\/ Default value\r\n\/\/\/ <\/summary>\r\npublic SyntaxForScriptBlocksIdentifier OptionSyntaxForScriptBlocksIdentifier { get; set; } = SyntaxForScriptBlocksIdentifier.OptionalBracketsForStartAndEndWhenSingleStatement;\r\n```\r\n\r\nIt should already allow a few different syntaxes :\r\n\r\n__C# like syntax__\r\n```c#\r\nif(condition) DoSomeThingElse();\r\n\r\nif(condition)\r\n{\r\n \/\/ Do a lot of stuff or only one\r\n}\r\n```\r\n\r\n__Python like syntax__\r\n```python\r\nif condition:\r\n DoSomething\r\n```\r\n\r\n__Pascal like syntax__\r\n```pascal\r\nif condition then\r\nbegin\r\n DoSomething();\r\nend\r\n```\r\n\r\n__Some exotic syntax__\r\n```\r\nif |condition|\r\n DoSomething()\r\n```\r\n","issue_id":1660251387237,"origin_id":759299915,"user_origin_id":15038327,"create_time":1610527656,"update_time":1610527806,"id":1669379232447,"updated_at":"2022-11-25T12:27:12.447000Z","created_at":"2022-11-25T12:27:12.447000Z"},{"_id":"6380b4a04b97542c9a30b4c1","body":"This looks really great! After reading this the only thing I'm wondering about it whether it would be possible to have\r\n\r\n```csharp\r\npublic string[] OptionScriptBlocksKeywordsHeadStatementsStartBracket = new {\"(\"};\r\n ```\r\n\r\nThen internally detect which arrays are only one token - and treat these as simple strings for increased performance and iterate others. Hence:\r\n\r\n```csharp\r\npublic string[] OptionScriptBlockKeywordsHeadExpressionAndBlockSeparator { get; set; } = new {\":\", \"|\"};\r\n```\r\n**Some exotic syntax:**\r\n```csharp\r\n if condition: \/\/ this is valid\r\n MyFn();\r\n\r\n if condition| \/\/ this is also valid\r\n MyFn();\r\n```\r\n\r\nDo you think this would be possible, worth the effort and without significant perf impact? My idea here is to allow for multiple styles to be intermixed, as we can do in c#:\r\n\r\n```csharp\r\nif (expr) {\r\n statement();\r\n}\r\n\r\nif (expr) \r\n statement();\r\n```","issue_id":1660251387237,"origin_id":759428716,"user_origin_id":10260230,"create_time":1610542290,"update_time":1610542304,"id":1669379232450,"updated_at":"2022-11-25T12:27:12.450000Z","created_at":"2022-11-25T12:27:12.450000Z"},{"_id":"6380b4a04b97542c9a30b4c2","body":"Yes I already thought about this too.\r\nIn place of an array I would add a way to use the string as a Regex with some option like `OptionScriptBlocksKeywordsHeadStatementsAsRegex = true;\" \r\nOr directly make these Properties as Regex What do you think ?\r\n\r\n```c#\r\npublic Regex OptionScriptBlockKeywordsHeadExpressionAndBlockSeparator { get; set; } = new Regex(@\"^[:|]|then(?=\\s)\", RegexOptions.IgnoreCase);\r\n```","issue_id":1660251387237,"origin_id":759436439,"user_origin_id":15038327,"create_time":1610543178,"update_time":1610543382,"id":1669379232452,"updated_at":"2022-11-25T12:27:12.452000Z","created_at":"2022-11-25T12:27:12.452000Z"},{"_id":"6380b4a04b97542c9a30b4c3","body":"I'm concerned about performance impact here. If possible, could you please run a test so we could see how much cpu power are we using here? Regex vs plain string (and possibly vs array).","issue_id":1660251387237,"origin_id":759513846,"user_origin_id":10260230,"create_time":1610550881,"update_time":1610550881,"id":1669379232455,"updated_at":"2022-11-25T12:27:12.454000Z","created_at":"2022-11-25T12:27:12.454000Z"},{"_id":"6380b4a04b97542c9a30b4c4","body":"Some small breaking changes are linked to this issue. So I think the next version of EE that will come with all of these scripts customization stuff will be a 1.5.x.x major version.\r\n\r\nAlso, the possibility to set arrays for block keywords syntax options seem harder than I thought especially for all brackets stuff that support nesting (imbrication) and for what we need to now which end bracket close which start bracket. ","issue_id":1660251387237,"origin_id":765201945,"user_origin_id":15038327,"create_time":1611301061,"update_time":1611301121,"id":1669379232457,"updated_at":"2022-11-25T12:27:12.457000Z","created_at":"2022-11-25T12:27:12.457000Z"},{"_id":"6380b4a04b97542c9a30b4c5","body":"Here is an Idea to allow block keywords customization \r\n(as asked in [OptionKeywordForInstanceCreation => OptionNewKeywordAliases commit](https:\/\/github.com\/codingseb\/ExpressionEvaluator\/commit\/71f3de20c1283b1b2578ec16896f4ea77c79f37b))\r\n\r\n```c#\r\nIDictionary<string, Func<...>> blockKeywords { get; set; } = new Dictionary<string, Func<...>>()\r\n{\r\n {\"while\", (keywordAttributes, subScript, ref isReturn, ref isBreak, ref isContinue, ref lastResult ...) => \r\n {\r\n while (!isReturn && (bool)ManageJumpStatementsOrExpressionEval(keywordAttributes[0]))\r\n {\r\n lastResult = ScriptEvaluate(subScript, ref isReturn, ref isBreak, ref isContinue);\r\n\r\n if (isBreak)\r\n {\r\n isBreak = false;\r\n break;\r\n }\r\n if (isContinue)\r\n {\r\n isContinue = false;\r\n }\r\n }\r\n }},\r\n\/\/...\r\n};\r\n```\r\n\r\nIt's always a reflection in progress and of course it will need some adaptations for things like if-else if -else and try-catch-finally famillies of keywords.\r\n\r\nThe idea is that for creating aliases we could just do :\r\n```c#\r\nblockKeywords[\"whileAlias\"] = blockKeywords[\"while\"];\r\n```\r\nBut it would also allow creating quite easily custom block keyword :\r\n```c#\r\nblockKeywords[\"myNewKeyword\"] = (keywordAttributes, subScript, ref isReturn, ref isBreak, ref isContinue, ref lastResult ...) => \r\n{\r\n \/\/ My custom interpretation of the custom keyword\r\n};\r\n```\r\n","issue_id":1660251387237,"origin_id":766657928,"user_origin_id":15038327,"create_time":1611564830,"update_time":1611564830,"id":1669379232460,"updated_at":"2022-11-25T12:27:12.459000Z","created_at":"2022-11-25T12:27:12.459000Z"},{"_id":"6380b4a04b97542c9a30b4c6","body":"And for more python like `for`loops :\r\n```c#\r\nblockKeywords[\"for\"] = blockKeywords[\"foreach\"];\r\nblockKeywords.Remove(\"foreach\");\r\n```","issue_id":1660251387237,"origin_id":766663070,"user_origin_id":15038327,"create_time":1611565319,"update_time":1611565319,"id":1669379232462,"updated_at":"2022-11-25T12:27:12.462000Z","created_at":"2022-11-25T12:27:12.462000Z"}] comment

Instead of mandatory `()` around an expression in listed keywords an option would exist to parse them without brackets. Now: ```csharp if (expr) { } ``` With suggestion option toggled...

enhancement

Escaping variable names

[{"_id":"6380b3f74b97542c9a30b3ee","body":"Hello @cantacuzene.\r\nI am sorry it's hard for me to give fast answer for now because I am in vacations and I only have my smartphone. \r\nI don't know if I fully understand your question but the answer is that there is no integrated solution to escape variables. But by inheritance you could define your own syntax for this by modifying the parsing process. For a first example for your case [look here](https:\/\/dotnetfiddle.net\/nyoWXN)\r\n\r\nYou can find some documentation on the wiki [Here](https:\/\/github.com\/codingseb\/ExpressionEvaluator\/wiki\/Advanced-Customization-and-Hacking#add-a-complex-operator-or-change-the-parsing-process)\r\n\r\nAn other way to do it could be with \"on the fly\" function. Something like `getVar(net-pv)` For the doc look [here](https:\/\/github.com\/codingseb\/ExpressionEvaluator\/wiki\/Variables-and-Functions#on-the-fly-variables-and-functions-evaluation).","issue_id":1660251387241,"origin_id":663262395,"user_origin_id":15038327,"create_time":1595543192,"update_time":1595572969,"id":1669379063622,"updated_at":"2022-11-25T12:24:23.621000Z","created_at":"2022-11-25T12:24:23.621000Z"},{"_id":"6380b3f74b97542c9a30b3ef","body":"Hi @codingseb this was exactly what I was looking for.\r\nI guess I should have digged further into the manual, I totally missed this parsing customization section ...\r\nI am not a big fan of inheritence but it'll work just fine :)\r\nThanks a lot for your reply!\r\n","issue_id":1660251387241,"origin_id":669968188,"user_origin_id":2272699,"create_time":1596724637,"update_time":1596724637,"id":1669379063625,"updated_at":"2022-11-25T12:24:23.625000Z","created_at":"2022-11-25T12:24:23.625000Z"},{"_id":"6380b3f74b97542c9a30b3f0","body":"I reopen this because it could be useful for others.","issue_id":1660251387241,"origin_id":754182656,"user_origin_id":15038327,"create_time":1609790079,"update_time":1609790079,"id":1669379063628,"updated_at":"2022-11-25T12:24:23.628000Z","created_at":"2022-11-25T12:24:23.628000Z"}] comment

Hi Seb! First of all I'd like to say this library is quite a marvel compared to the alternatives we have in the dotnet world!. Keep up the good work!!...

question
explanation