How do you do dynamic script evaluation in C#? - c#

What is the state of dynamic code evaluation in C#? For a very advanced feature of an app I'm working on, I'd like the users to be able to enter a line of C# code that should evaluate to a boolean.
Something like:
DateTime.Now.Hours > 12 && DateTime.Now.Hours < 14
I want to dynamically eval this string and capture the result as a boolean.
I tried Microsoft.JScript.Eval.JScriptEvaluate, and this worked, but it's technically deprecated and it only works with Javascript (not ideal, but workable). Additionally, I'd like to be able to push objects into the script engine so that they can be used in the evaluation.
Some resources I find mentioned dynamically compiling assemblies, but this is more overhead than I think I want to deal with.
So, what is the state of dynamic script evaluation in C#? Is it possible, or am I out of luck?

You use the DLR's ScriptEngine, here is an example:
http://www.codeproject.com/KB/codegen/ScriptEngine.aspx

The most informative link is this one:
Execute a string in C# 4.0
Expression Trees might also be of interest:
http://community.bartdesmet.net/blogs/bart/archive/2009/08/10/expression-trees-take-two-introducing-system-linq-expressions-v4-0.aspx
Alternatively these links:
http://www.codeproject.com/KB/dotnet/Expr.aspx
How can I evaluate a C# expression dynamically?
How can I evaluate C# code dynamically?

Related

Math equation as a string [duplicate]

I need to locate a fast, lightweight expression parser.
Ideally I want to pass it a list of name/value pairs (e.g. variables) and a string containing the expression to evaluate. All I need back from it is a true/false value.
The types of expressions should be along the lines of:
varA == "xyz" and varB==123
Basically, just a simple logic engine whose expression is provided at runtime.
UPDATE
At minimum it needs to support ==, !=, >, >=, <, <=
Regarding speed, I expect roughly 5 expressions to be executed per request. We'll see somewhere in the vicinity of 100/requests a second. Our current pages tend to execute in under 50ms. Usually there will only be 2 or 3 variables involved in any expression. However, I'll need to load approximately 30 into the parser prior to execution.
UPDATE 2012/11/5
Update about performance. We implemented nCalc nearly 2 years ago. Since then we've expanded it's use such that we average 40+ expressions covering 300+ variables on post backs. There are now thousands of post backs occurring per second with absolutely zero performance degradation.
We've also extended it to include a handful of additional functions, again with no performance loss. In short, nCalc met all of our needs and exceeded our expectations.
Have you seen https://ncalc.codeplex.com/ and https://github.com/sheetsync/NCalc ?
It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.
It also supports logical operators, date/time's strings and if statements.
How about the Fast Lightweight Expression Evaluator? It lets you set variables and supports logical operators.
If you need something beefier and have the time, you could also design your own expression language with Irony.
Hisystems' Interpreter supports custom functions, operators and literals, is lightweight pure c# portable code. Currently runs on iOS via MonoTouch and should run on any other Mono environment as well as windows. Free for commercial use. Available on GitHub at https://github.com/hisystems/Interpreter.
I fully appreciate how late this answer is however I would like to throw in my solution because I believe it can add more above the accepted answer of using NCalc should someone wish to use the expressions across multiple platforms.
-- Update --
I have created a parser for C# with plans to also implement it for Java and Swift over the next few months. This would mean that you can evaluate the expressions on multi-platforms without the need for tweaking per platform.
While Java and Swift was planned it never made it in to a fully fledge release. Instead there is now support for .NET Standard enabling support for Xamarin apps.
-- End update --
Expressive is the tool and it is available at:
GitHub or Nuget.
The site has a fair amount of documentation on it but to prevent link rot here is an example on how to use it:
Variable support
var expression = new Expression("1 * [variable]");
var result = expression.Evaluate(new Dictionary<string, object> { ["variable"] = 2);
Functions
var expression = new Expression("sum(1,2,3,4)");
var result = expression.Evaluate();
It was designed to match NCalc as best as possible however it has added support for things like a 'null' keyword.
self promotion here
i wrote aa generic parser generator for c# https://github.com/b3b00/csly
you can find an expression parseras example on my github. you may need to customize it to fit your needs

C#, User defined formula

I need to enable user that he can write own formula in datagridview. Something like a function in Excel.
Example of formula definition:
So, user write his own formula in formula cell and then in other table is shown result for each. How I can do this?
I would try NCalc
NCalc is a mathematical expressions evaluator in .NET. NCalc can parse any expression and evaluate the result, including static or dynamic parameters and custom functions.
Dictionary<string, int> dict = new Dictionary<string, int>() { { "Income", 1000 }, { "Tax", 5 } };
string expressionString = "Income * Tax";
NCalc.Expression expr = new NCalc.Expression(expressionString);
expr.EvaluateParameter += (name, args) =>
{
args.Result = dict[name];
};
int result = (int)expr.Evaluate();
Your formula could be manipulated to C# and dynamically compiled using SystemCodeCom.Compiler and you could run it on the fly feeding in your variable values.
Otherwise you are going to have to impliment some kind of mini parser/compiler - which is a rather particular skill and which could quickly get complicated - especially if your formulas become more complicated (which maybe likely).
There is are codeproject articles on dynamic complilation here and here. But there are plenty of other examples around on the web.
There are a number of ways you can do that, they all revolve around translating the formula into executable code.
Do you want to write your own parser or do you wnat to use an existing one. C# itself, IronPython, IronRuby, some off the shelf component. If you use a full parser you might want to look at how to restrict what the user can do with it, inadvertantly or otherwise...
If they are as simple as they look, some sort of expression builder, (pick two named values and an operator) might be the way to go, but modularise, both building the expression and evaluating it so you can beef up at some later point.
However given how simple they appear to be, I'd be tempted to predefine expressions (loaded as meta data from some sort of backing store, and make it select one of these as opposed to user entering it. You could easily spend months at this aspect of the design, is it worth it?
I had a similar requirement (dynamic parsing of expressions) recently in a project I am working on and ended up using VB expressions from WF (Windows Workflow Foundation). It certainly depends on how important this functionality is for you and how much effort are you willing to put into it. In my case it turned out better than NCalc for several reasons:
it supports more complex expressions than NCalc
the resulting expression trees can be analyzed to determine dependencies for individual expressions
it's the same language for expressions as in WF (which I already use elsewhere in the project)
Anyway, here is a short blogpost I've written on the subject.
I created the albatross expression parser a few years back. It has been open sourced for a while but I finally get around and published v2.02 and added documentation recently. It is being actively maintained. It has a couple nice features:
Circular reference detection
Source variable from external object directly
Reversed generation of expressions
Properly documented

C# string translation

Does C# offer a way to translate strings on-the-fly or something similiar?
I'm now working on some legacy code, which has some parts like this:
section.AddParagraph(String.Format("Premise: {0}", currentReport.Tenant.Code));
section.AddParagraph(String.Format("Description: {0}", currentReport.Tenant.Name));
section.AddParagraph();
section.AddParagraph(String.Format("Issued: #{0:D5}", currentReport.Id));
section.AddParagraph(String.Format("Date: {0}", currentReport.Timestamp.ToString(
"dd MMM yyyy", CultureInfo.InvariantCulture)));
section.AddParagraph(String.Format("Time: {0:HH:mm}", currentReport.Timestamp));
So, I want to implement the translation of these strings on-the-fly based on some substitution table (for example, as Qt does).
Is this possible (probably, using something what C# already has or using some post-processing - may be possible with PostSharp)?
Does some generic internalization approach for applications built with C# (from scratch) exist?
Does some generic internalization approach for applications built with C# (from scratch) exist?
Yes, using resource files. And here's another article on MSDN.
In the C# project I currently work on, we wrote a helper function that works like this:
section.AddParagraph(I18n.Translate("Premise: {0}", currentReport.Tenant.Code));
section.AddParagraph(I18n.Translate("That's all");
At build time, a script searches all I18n.Translate invocations, as well as all UI controls, and populates a table with all english phrases. This gets translated.
At runtime, the english text is looked up in a dictionary, and replaced with the translated text.
Something similar happens to our winforms Dialog resources: they are constructed in english and then translated using the same dictionary.
The biggest strength of this scheme, is also the biggest weakness: If you use the same string in two places, it gets translated the same. This shortens the file you send to translater which helps to reduce cost. If you ever need to force a different translation of the same english word, you need to work around that. As long as we have the system (4ish years or so), we never had the need for it. There's also benefits: You read the english UI text inline with the source (so not hiding behind an identifier you need to name), and if you delete code, its automatically removed from the translated resources as well.

Is Ironpython suitable for value calculation?

I want to allow the users to define a formula based on two variables. Say I have a Quantity and Value and I want to allow the users of my app to write something like
Quantity*20+Value*0,005
in a textbox and pass the result back to the C# app. I thought of embedding the IronPython interpreter in my app, but I'm not sure it's worth the effort. Is this the way to go or should I consider another option?
Update
To clarify, users may also write more complex formulae like:
if Value > 10000:
return Value*0,05
elif Value > 1000:
return Value*0,02
else
return 0
I think I'll go this way. Embedding the Python runtime is easy enough and the syntax is really simple for users to write simple scripts.
If that is all that you want to do, to evaluate a simple expression you could just dynamically compile C# code:
http://msdn.microsoft.com/en-us/magazine/cc188948.aspx
It's something like 20 lines of code.

Pretty-printing C# from Python

Suppose I wrote a compiler in Python or Ruby that translates a language into a C# AST.
How do I pretty-print this AST from Python or Ruby to get nicely indented C# code?
Thanks, Joel
In python the pprint module is available.
Depending on how your data is structured it may not return the result your looking for.
Once you have an AST, this should be very easy. When you walk your AST, all you have to do is keep track of what your current indent level is -- you could use a global for this. The code that's walking the tree simply needs to increment the indent level every time you enter a block, and decrement it when you exit a block. Then, whenever you print a line of code, you call it like this:
print "\t"*indentlevel + code
You should end up with nicely formatted code. However, I'm a bit confused that you're asking this question -- if you have the skills to parse C# into an AST, I can't imagine you wouldn't be able to write a pretty-printing output function. :-)
One way would be to just print it and then invoke a code formatter.

Categories

Resources