You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
6.2 KiB
188 lines
6.2 KiB
using System;
|
|
using System.CodeDom;
|
|
using System.CodeDom.Compiler;
|
|
using Microsoft.CSharp;
|
|
using System.Text;
|
|
using System.Reflection;
|
|
using System.Collections.Generic;
|
|
|
|
//Evaluator.EvaluateToBool("30 > 40 && 10<20 && 1>=1 || 1>2")
|
|
namespace GummingCommon
|
|
{
|
|
/// <summary>
|
|
/// Summary description for Class1.
|
|
/// </summary>
|
|
public class Evaluator
|
|
{
|
|
#region Construction
|
|
public Evaluator(EvaluatorItem[] items)
|
|
{
|
|
ConstructEvaluator(items);
|
|
}
|
|
|
|
public Evaluator(Type returnType, string expression, string name)
|
|
{
|
|
EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) };
|
|
ConstructEvaluator(items);
|
|
}
|
|
|
|
public Evaluator(EvaluatorItem item)
|
|
{
|
|
EvaluatorItem[] items = { item };
|
|
ConstructEvaluator(items);
|
|
}
|
|
|
|
private void ConstructEvaluator(EvaluatorItem[] items)
|
|
{
|
|
ICodeCompiler comp = (new CSharpCodeProvider().CreateCompiler());
|
|
CompilerParameters cp = new CompilerParameters();
|
|
cp.ReferencedAssemblies.Add("system.dll");
|
|
cp.ReferencedAssemblies.Add("system.data.dll");
|
|
cp.ReferencedAssemblies.Add("system.xml.dll");
|
|
cp.GenerateExecutable = false;
|
|
cp.GenerateInMemory = true;
|
|
|
|
StringBuilder code = new StringBuilder();
|
|
code.Append("using System; \n");
|
|
code.Append("using System.Data; \n");
|
|
code.Append("using System.Data.SqlClient; \n");
|
|
code.Append("using System.Data.OleDb; \n");
|
|
code.Append("using System.Xml; \n");
|
|
code.Append("namespace GummingCommon { \n");
|
|
code.Append(" public class _Evaluator { \n");
|
|
foreach (EvaluatorItem item in items)
|
|
{
|
|
code.AppendFormat(" public {0} {1}() ",
|
|
item.ReturnType.Name,
|
|
item.Name);
|
|
code.Append("{ ");
|
|
code.AppendFormat(" return ({0}); ", item.Expression);
|
|
code.Append("}\n");
|
|
}
|
|
code.Append("} }");
|
|
|
|
CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());
|
|
if (cr.Errors.HasErrors)
|
|
{
|
|
StringBuilder error = new StringBuilder();
|
|
error.Append("Error Compiling Expression: ");
|
|
foreach (CompilerError err in cr.Errors)
|
|
{
|
|
error.AppendFormat("{0}\n", err.ErrorText);
|
|
}
|
|
throw new Exception("Error Compiling Expression: " + error.ToString());
|
|
}
|
|
Assembly a = cr.CompiledAssembly;
|
|
_Compiled = a.CreateInstance("GummingCommon._Evaluator");
|
|
}
|
|
#endregion
|
|
|
|
#region Public Members
|
|
public int EvaluateInt(string name)
|
|
{
|
|
return (int)Evaluate(name);
|
|
}
|
|
|
|
public string EvaluateString(string name)
|
|
{
|
|
return (string)Evaluate(name);
|
|
}
|
|
|
|
public bool EvaluateBool(string name)
|
|
{
|
|
return (bool)Evaluate(name);
|
|
}
|
|
|
|
public object Evaluate(string name)
|
|
{
|
|
MethodInfo mi = _Compiled.GetType().GetMethod(name);
|
|
return mi.Invoke(_Compiled, null);
|
|
}
|
|
#endregion
|
|
|
|
#region Static Members
|
|
static public int EvaluateToInteger(string code)
|
|
{
|
|
Evaluator eval = new Evaluator(typeof(int), code, staticMethodName);
|
|
return (int)eval.Evaluate(staticMethodName);
|
|
}
|
|
|
|
static public double EvaluateToDouble(string code)
|
|
{
|
|
Evaluator eval = new Evaluator(typeof(double), code, staticMethodName);
|
|
return (double)eval.Evaluate(staticMethodName);
|
|
}
|
|
|
|
static public List<double> EvaluateToDouble(List<string> codes)
|
|
{
|
|
List<EvaluatorItem> items = new List<EvaluatorItem>();
|
|
for (int i = 0; i < codes.Count; i++)
|
|
{
|
|
items.Add(new EvaluatorItem(typeof(double), codes[i], staticMethodName + i.ToString()));
|
|
}
|
|
Evaluator eval = new Evaluator(items.ToArray());
|
|
List<double> rv = new List<double>();
|
|
for (int i = 0; i < codes.Count; i++)
|
|
{
|
|
rv.Add((double)eval.Evaluate(staticMethodName + i.ToString()));
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
static public string EvaluateToString(string code)
|
|
{
|
|
Evaluator eval = new Evaluator(typeof(string), code, staticMethodName);
|
|
return (string)eval.Evaluate(staticMethodName);
|
|
}
|
|
|
|
static public List<bool> EvaluateToBool(List<string> codes)
|
|
{
|
|
List<EvaluatorItem> items = new List<EvaluatorItem>();
|
|
for (int i = 0; i < codes.Count; i++)
|
|
{
|
|
items.Add(new EvaluatorItem(typeof(bool), codes[i], staticMethodName + i.ToString()));
|
|
}
|
|
Evaluator eval = new Evaluator(items.ToArray());
|
|
List<bool> rv = new List<bool>();
|
|
for (int i = 0; i < codes.Count; i++)
|
|
{
|
|
rv.Add((bool)eval.Evaluate(staticMethodName + i.ToString()));
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
static public bool EvaluateToBool(string code)
|
|
{
|
|
Evaluator eval = new Evaluator(typeof(bool), code, staticMethodName);
|
|
return (bool)eval.Evaluate(staticMethodName);
|
|
}
|
|
|
|
static public object EvaluateToObject(string code)
|
|
{
|
|
Evaluator eval = new Evaluator(typeof(object), code, staticMethodName);
|
|
return eval.Evaluate(staticMethodName);
|
|
}
|
|
#endregion
|
|
|
|
#region Private
|
|
const string staticMethodName = "__foo";
|
|
Type _CompiledType = null;
|
|
object _Compiled = null;
|
|
#endregion
|
|
}
|
|
|
|
public class EvaluatorItem
|
|
{
|
|
public EvaluatorItem(Type returnType, string expression, string name)
|
|
{
|
|
ReturnType = returnType;
|
|
Expression = expression;
|
|
Name = name;
|
|
}
|
|
|
|
public Type ReturnType;
|
|
public string Name;
|
|
public string Expression;
|
|
}
|
|
}
|