using System;
using System.Collections.Generic;
using System.Reflection;
using System.Dynamic;
using System.Linq;
using Z.Expressions;
using Newtonsoft.Json;
using System.Text;
// https://eval-expression.net/
// https://eval-expression.net/online-examples
namespace TopNugetPackages
{
public class MainMetaProgrammingDriver
{
public class ConcreteType
{
public int ID { get; set; }
}
private void TestSimple()
{
// Parameter: Anonymous Type
int result = Eval.Execute<int>("X + Y", new { X = 1, Y = 6 });
Console.WriteLine(result);
// Parameter: Argument Position
result = Eval.Execute<int>("{0} + {1}", 1, 8);
Console.WriteLine(result);
// Parameter: Class Member
dynamic expandoObject = new ExpandoObject();
expandoObject.X = 1;
expandoObject.Y = 9;
result = Eval.Execute<int>("X + Y", expandoObject);
Console.WriteLine(result);
// Parameter: Dictionary Key
var values = new Dictionary<string, object>() { { "X", 4 }, { "Y", 2 } };
result = Eval.Execute<int>("X + Y", values);
Console.WriteLine(result);
}
private void TestComplex()
{
try
{
List<string> expressions = new List<string>()
{
"Math.Pow(2, 3)",
"Math.pOW(2, 3)"
};
var context = new EvalContext();
context.UseCache = false;
foreach (var expression in expressions)
{
var result = context.Execute(expression);
Console.WriteLine("{0}: {1}", expression, result);
}
Console.WriteLine("\nAfter context.IsCaseSensitive = false; \n");
context.IsCaseSensitive = true;
foreach (var expression in expressions)
{
var result = context.Execute(expression);
Console.WriteLine("{0}: {1}", expression, result);
}
Console.WriteLine("\nAfter context.BindingFlags = BindingFlags.IgnoreCase; \n");
context.BindingFlags = BindingFlags.Public;
foreach (var expression in expressions)
{
var result = context.Execute(expression);
Console.WriteLine("{0}: {1}", expression, result);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
// demonstrate new object creation and assignment
private void TestConcreteType()
{
EvalManager.DefaultContext.RegisterType(typeof(ConcreteType));
var list = new List<int>() { 1, 2, 3, 4, 5 };
var list2 = list.SelectDynamic(x => "new ConcreteType() { ID = x }").Cast<ConcreteType>().ToList();
var json = JsonConvert.SerializeObject(list2, Formatting.Indented);
Console.WriteLine(json);
}
// demonstrate list of meta-program
private void TestMyMetaExpression()
{
try
{
var exprs = new List<string>()
{
"Math.Pow(2, 3)",
"Math.Max(3, 9)",
"Console.WriteLine(\"Hello World\")",
};
var context = new EvalContext() { UseCache = false };
foreach (var expr in exprs)
{
var result = context.Execute(expr);
Console.WriteLine("{0}: {1}", expr, result);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
// demonstrate simple if-else conditional statements
private void TestMetaIsPosOrNeg(int num)
{
try
{
var context = new EvalContext() { UseCache = false };
var metacode = new StringBuilder();
metacode.Append($"int x = {num};");
metacode.Append("if (x > 0)");
metacode.Append("{ Console.WriteLine($\"POSITIVE. X = {x}\"); }");
metacode.Append("else");
metacode.Append("{ Console.WriteLine($\"NEGATIVE. X = {x}\"); }");
var result = context.Execute(metacode.ToString());
Console.WriteLine(result);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
// Demonstrate meta-programming with calculating factorial and returning the result
private long TestMetaFactorial(int number)
{
try
{
var context = new EvalContext() { UseCache = false };
var metacode = new StringBuilder();
metacode.Append($"long fact = 1;");
metacode.Append($"int numb = {number};");
metacode.Append("Console.WriteLine($\"Calculating Factorial of {numb}.\");");
metacode.Append("for (int i = 1; i <= numb; i++) {");
metacode.Append(" fact = fact * i;");
metacode.Append("}");
metacode.Append("Console.WriteLine($\"{numb}! = {fact}.\");");
metacode.Append("return fact;");
var result = context.Execute(metacode.ToString());
Console.WriteLine($"Return value is: {result}\r\n");
return Convert.ToInt64(result);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return 0;
}
public void DoIt()
{
TestSimple();
TestComplex();
TestConcreteType();
TestMyMetaExpression();
TestMetaIsPosOrNeg(2);
TestMetaIsPosOrNeg(-12);
TestMetaIsPosOrNeg(8);
TestMetaIsPosOrNeg(-27);
TestMetaIsPosOrNeg(28);
TestMetaIsPosOrNeg(-81);
TestMetaFactorial(3);
TestMetaFactorial(5);
TestMetaFactorial(12);
}
}
}