Click here to Skip to main content
6,631,404 members and growing! (17,616 online)
Email Password   helpLost your password?
General Programming » Algorithms & Recipes » General     Intermediate

Evaluating Mathematical Expressions by Compiling C# Code at Runtime

By Marcin Cuprjak (aka Vlad Tepes)

A completely new way of making a mathematical expression evaluator.
C#, Windows, .NET 1.0, Visual Studio, Dev
Posted:21 Apr 2003
Views:126,344
Bookmarked:67 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
45 votes for this article.
Popularity: 6.81 Rating: 4.12 out of 5
3 votes, 6.7%
1
1 vote, 2.2%
2
1 vote, 2.2%
3
8 votes, 17.8%
4
32 votes, 71.1%
5

Introduction

There are many articles on creating mathematical expression parsers (i.e. for displaying 3D functions where user inputs the formulas manually). Most of them are based on lexical analysis, grammar definitions etc. With C# there is a solution for making mathematical expression evaluator in a completely new way: by compiling code at runtime.

Let's assume that we want to create an application that would calculate 3D function like that:

z = f(x,y)

But we want to let the user input function formula manually (we don't know what the formula will look like).

A solution to deal with that task in 10 minutes is:

  1. Let the user input the function
  2. Compile that function into memory
  3. Run the function with given x and y
  4. Do something with result z value


To do that in a couple of minutes we would need a class with virtual method:

namespace MathEval
{
public class MyClassBase
{
public MyClassBase()
{
}
public virtual double eval(double x,double y)
{
return 0.0;
}
}
}

all we need more is a parser/evaluator class which would compile function body into assembly (created in memory) and calculate function result:


using System;
using System.Reflection;
using System.Windows.Forms;
namespace MathEval
{
public class MathExpressionParser
{
MyClassBase myobj = null;
public MathExpressionParser()
{
}
public bool init(string expr)
{
Microsoft.CSharp.CSharpCodeProvider cp
= new Microsoft.CSharp.CSharpCodeProvider();
System.CodeDom.Compiler.ICodeCompiler ic = cp.CreateCompiler();
System.CodeDom.Compiler.CompilerParameters cpar
= new System.CodeDom.Compiler.CompilerParameters();
cpar.GenerateInMemory = true;
cpar.GenerateExecutable = false;
cpar.ReferencedAssemblies.Add("system.dll");
cpar.ReferencedAssemblies.Add("matheval.exe");
string src = "using System;"+
"class myclass:MathEval.MyClassBase" +
"{"+
"public myclass(){}"+
"public override double eval(double x,double y)"+
"{"+
"return "+ expr +";"+
"}"+
"}";
System.CodeDom.Compiler.CompilerResults cr
= ic.CompileAssemblyFromSource(cpar,src);
foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
MessageBox.Show(ce.ErrorText);

if (cr.Errors.Count == 0 && cr.CompiledAssembly != null)
{
Type ObjType = cr.CompiledAssembly.GetType("myclass");
try
{
if (ObjType != null)
{
myobj = (MyClassBase)Activator.CreateInstance(ObjType);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return true;
}
else
return false;
}
public double eval(double x,double y)
{
double val = 0.0;
if (myobj != null)
{
val = myobj.eval(x,y);
}
return val;
}
}
}

Take a look at the init() method. All we need it to do is to create an assembly(in memory) with a class "myclass" derived from MyBaseClass. Note that "eval" method contains the formula given by the user at runtime. Also note that cpar.ReferencedAssemblies.Add("matheval.exe"); defines a reference to the application currently being created.
Then we can call myclass.eval method as many times as we want to:


MathExpressionParser mp = new MathExpressionParser();
mp.init("Math.Sin(x)*y");


for(int i=0;i<1000000;i++)
{
mp.eval((double)i,(double)i);
}

Compiled code is of course much faster than any other solution used to parse and evaluate expressions.

A few things to do:

  • Let the user input formulas as "xy*sin(x+y)" or "x^2+y^2" and convert them to c# "x*y*Math.Sin(x+y)" "x*x + y*y" etc...
  • Do some error checking/handling other than compiler errors.
  • Freeing and recreating the in-memory-assembly with another formula.
  • Enjoy the code :)

PS: special thanks to AcidRain for some ideas :)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Marcin Cuprjak (aka Vlad Tepes)


Member

Occupation: Architect
Location: Poland Poland

Other popular Algorithms & Recipes articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 22 of 22 (Total in Forum: 22) (Refresh)FirstPrevNext
GeneralCompletely New? PinmemberDewey15:28 21 Jan '08  
GeneralRe: Completely New? PinmemberMarcin Cuprjak (aka Vlad Tepes)10:33 23 Jan '08  
QuestionWhat is wrong with double FuncN (params double[] x) ? Pinmemberhreba4:40 22 Nov '06  
GeneralGood Work! Pinmembergajatko3:17 3 Oct '06  
GeneralNot applicable for ASP.NET2 applications PinmemberZuZuKin10:10 23 Feb '06  
GeneralVery Nice Pinmembermsaroka13:48 20 Apr '05  
General"matheval.exe" Pinmemberxorenko1:11 17 Apr '05  
GeneralExtremely insecure! Pinmemberekolis16:59 14 Jun '04  
GeneralHow to unload an assembly? PinmemberHeng Ma11:48 30 Jul '03  
GeneralRe: How to unload an assembly? Pinmembertuxic10:01 7 Mar '05  
GeneralWhat about Microsoft.JScript.Eval()? Pinmemberonc4:59 29 Apr '03  
GeneralGenerate IL directly Pinmemberhsauro20:48 22 Apr '03  
GeneralRe: Generate IL directly Pinmemberleppie8:02 23 Apr '03  
GeneralRe: Generate IL directly PinsussKris Vandermotten5:25 29 Apr '03  
GeneralCompiling In Memory PinmemberBlake Coverett17:26 22 Apr '03  
GeneralRe: Compiling In Memory PinmemberJonathan de Halleux0:02 23 Apr '03  
GeneralRe: Compiling In Memory PinmemberRama Krishna4:12 23 Apr '03  
GeneralRe: Compiling In Memory Pinmemberleppie8:00 23 Apr '03  
GeneralRe: Compiling In Memory PinmemberRama Krishna8:06 23 Apr '03  
GeneralRe: Compiling In Memory PinmemberBlake Coverett17:48 23 Apr '03  
GeneralRe: Compiling In Memory PinmemberRama Krishna2:46 24 Apr '03  
GeneralRe: Compiling In Memory PinmemberBlake Coverett14:41 24 Apr '03  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 21 Apr 2003
Editor: Chris Maunder
Copyright 2003 by Marcin Cuprjak (aka Vlad Tepes)
Everything else Copyright © CodeProject, 1999-2009
Web21 | Advertise on the Code Project