Skip to content

Instantly share code, notes, and snippets.

@rauhryan
Created October 25, 2011 15:08
Show Gist options
  • Save rauhryan/1313071 to your computer and use it in GitHub Desktop.
Save rauhryan/1313071 to your computer and use it in GitHub Desktop.
Future AST post
public int add(int a, int b)
{
return a + b;
}
public int subtract(int a, int b)
{
return a - b;
}
public Func<int, int> boo(int b)
{
var plus = new Func<int, int>(a => add(a, b));
var minus = new Func<int, int>(a => subtract(a, b));
return (b > 0) ? plus : minus;
}
if (b > 0) return a + b;
return a - b;
[TestFixture]
public class ExpressionTreeFixture
{
[Test]
public void a_plus_abs_b_should_equal_9()
{
5.PlusAbs(-4).ShouldEqual(9);
}
}
public static class IntExtension
{
public static int PlusAbs(this int a, int b)
{
var operation = b > 0
? ExpressionType.Add
: ExpressionType.Subtract;
var maths = Expression
.MakeBinary(operation,
Expression.Constant(a),
Expression.Constant(b));
return Expression.Lambda<Func<int>>(maths).Compile()();
}
}
[TestFixture]
public class ExpressionTreeFixture
{
[Test]
public void a_plus_abs_b_should_equal_9()
{
5.PlusAbs(-4).ShouldEqual(9);
}
}
public static class IntExtension
{
public static int PlusAbs(this int a, int b)
{
var operation = b > 0
? ExpressionType.Add
: ExpressionType.Subtract;
var maths = Expression
.MakeBinary(operation,
Expression.Constant(a),
Expression.Constant(b));
return Expression.Lambda<Func<int>>(maths).Compile()();
}
}
public Func<int,int,int> a_plus_abs_b ()
{
ParameterExpression a = Expression.Parameter(typeof (int), "a");
ParameterExpression b = Expression.Parameter(typeof (int), "b");
var greaterThanZero = Expression.MakeBinary(ExpressionType.GreaterThan, b, Expression.Constant(0));
var maths = Expression.Condition(greaterThanZero,
Expression.MakeBinary(ExpressionType.Add, a, b),
Expression.MakeBinary(ExpressionType.Subtract, a, b));
return Expression.Lambda<Func<int, int, int>>(maths, a, b).Compile();
}
public class ASTTester
{
[Test]
public void fun_with_ast()
{
/*
* (define (a-plus-abs-b a b)
* ((if (> b 0) + -) a b))
*/
a_plus_abs_b(5, -4)().ShouldEqual(9);
5.PlusAbs(-4).ShouldEqual(9);
cool()(5, -4).ShouldEqual(9);
cool()(5, 0).ShouldEqual(5);
boo(-4)(5).ShouldEqual(9);
var func = GetPredicateBuilder<MyClass>(
ReflectionHelper.GetProperty<MyClass>(x => x.Name).ToMemberExpression<MyClass>());
func("something").Compile()(new MyClass(){Name = "has something in it"}).ShouldBeTrue();
}
public int add(int a, int b)
{
return a + b;
}
public int subtract(int a, int b)
{
return a - b;
}
public Func<int, int> boo(int b)
{
var plus = new Func<int, int>(a => add(a, b));
var minus = new Func<int, int>(a => subtract(a, b));
return (b > 0) ? plus : minus;
}
public class MyClass
{
public string Name { get; set; }
}
private Func<int> a_plus_abs_b(int a, int b)
{
// if (b > 0) return a + b;
// return a - b;
var operation = b > 0 ? ExpressionType.Add : ExpressionType.Subtract;
var maths = Expression.MakeBinary(operation, Expression.Constant(a), Expression.Constant(b));
return Expression.Lambda<Func<int>>(maths).Compile();
}
private Func<int,int,int> cool ()
{
ParameterExpression a = Expression.Parameter(typeof (int), "a");
ParameterExpression b = Expression.Parameter(typeof (int), "b");
var greaterThanZero = Expression.MakeBinary(ExpressionType.GreaterThan, b, Expression.Constant(0));
var maths = Expression.Condition(greaterThanZero,
Expression.MakeBinary(ExpressionType.Add, a, b),
Expression.MakeBinary(ExpressionType.Subtract, a, b));
return Expression.Lambda<Func<int, int, int>>(maths, a, b).Compile();
}
private static readonly MethodInfo _indexOfMethod =
ReflectionHelper.GetMethod<string>(s => s.IndexOf("", StringComparison.InvariantCultureIgnoreCase));
public Func<object, Expression<Func<T, bool>>> GetPredicateBuilder<T>(MemberExpression propertyPath)
{
return valueToCheck =>
{
ConstantExpression valueToCheckConstant = Expression.Constant(valueToCheck);
//THECALL(x) = (x.Name ?? "").IndexOf("something", StringComparison.InvariantCultureIgnoreCase)
MethodCallExpression indexOfCall =
Expression.Call(Expression.Coalesce(propertyPath, Expression.Constant(String.Empty)), _indexOfMethod,
valueToCheckConstant,
Expression.Constant(StringComparison.InvariantCultureIgnoreCase));
// let THEOPERATION(x) = [>, THECALL(x), 0 ]
var operation = false ? ExpressionType.LessThan : ExpressionType.GreaterThanOrEqual;
BinaryExpression comparison = Expression.MakeBinary(operation, indexOfCall,
Expression.Constant(0));
// let THEFUNC = (x) => THEOPERATION(X)
ParameterExpression lambdaParameter = propertyPath.GetParameter<T>();
// ParameterExpression lambdaParameter = Expression.Parameter(typeof (T), "entity");
return Expression.Lambda<Func<T, bool>>(comparison, lambdaParameter);
};
}
}
public static class IntExtension
{
public static int PlusAbs(this int a, int b)
{
var operation = b > 0 ? ExpressionType.Add : ExpressionType.Subtract;
var maths = Expression.MakeBinary(operation, Expression.Constant(a), Expression.Constant(b));
return Expression.Lambda<Func<int>>(maths).Compile()();
}
}
[TestFixture]
public class ExpressionTreeFixture
{
[Test]
public void a_plus_abs_b_should_equal_9()
{
a_plus_abs_b(5, -4).ShouldEqual(9);
}
private int a_plus_abs_b(int a, int b)
{
var operation = b > 0
? ExpressionType.Add
: ExpressionType.Subtract;
var maths = Expression
.MakeBinary(operation,
Expression.Constant(a),
Expression.Constant(b));
return Expression.Lambda<Func<int>>(maths).Compile()();
}
}
[TestFixture]
public class ExpressionTreeFixture
{
[Test]
public void a_plus_abs_b_should_equal_9()
{
a_plus_abs_b(5, -4).ShouldEqual(9);
}
private int a_plus_abs_b(int a, int b)
{
var operation = b > 0
? ExpressionType.Add
: ExpressionType.Subtract;
var maths = Expression
.MakeBinary(operation,
Expression.Constant(a),
Expression.Constant(b));
return Expression.Lambda<Func<int>>(maths).Compile()();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment