Created
July 30, 2015 02:25
-
-
Save earthengine/797bb9c23c4fde293b95 to your computer and use it in GitHub Desktop.
Transforming c# expression tree in CPS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CPSExpressionVisitor : ExpressionVisitor | |
{ | |
delegate R SFunc<T, R>(T v); | |
delegate SFunc<T2, R> SFunc<T1, T2, R>(T1 v); | |
delegate SFunc<T2, T3, R> SFunc<T1, T2, T3, R>(T1 v); | |
delegate SFunc<T2, T3, T4, R> SFunc<T1, T2, T3, T4, R>(T1 v); | |
delegate dynamic FDynamic(FDynamic s); | |
private static FDynamic ConstFDynamic<T>(T v) | |
{ | |
return new FDynamic(_ => v); | |
} | |
private static dynamic SelfRunDynamic(FDynamic f) | |
{ | |
return f(f); | |
} | |
private static FDynamic InvokeDynamic(FDynamic f, FDynamic v) | |
{ | |
return new FDynamic(u => f(InvokeDynamic(v, u))); | |
} | |
protected Expression Visit(Expression exp) | |
{ | |
switch (exp.NodeType) | |
{ | |
case ExpressionType.Call: | |
case ExpressionType.Lambda: | |
case ExpressionType.Parameter: | |
return base.Visit(exp); | |
default: | |
throw new NotImplementedException(exp.Type.ToString()); | |
} | |
} | |
private Func<Expression, Expression> context; | |
private ParameterExpression standardContinuation; | |
override protected Expression VisitParameter(ParameterExpression exp){ | |
if (exp.Type != typeof(FDynamic)) | |
throw new NotImplementedException(exp.Type.ToString()); | |
return context(exp); | |
} | |
protected override Expression VisitLambda<T>(Expression<T> node) | |
{ | |
var c = context; | |
var x = Expression.Parameter(node.Parameters[0].Type, "x"); | |
standardContinuation = Expression.Parameter(typeof(FDynamic), "k"); | |
context = x1 => Expression.Call(this.GetType(), "InvokeDynamic", new Type[0], standardContinuation, x); | |
return c(Expression.Lambda(Expression.Lambda(Visit(node.Body), standardContinuation), x)); | |
} | |
protected override Expression VisitMethodCall(MethodCallExpression exp) | |
{ | |
var c = context; | |
var k = standardContinuation; | |
context = m => | |
{ | |
context = n => | |
{ | |
var v = Expression.Call(this.GetType(), "InvokeDynamic", new Type[0], m, n); | |
if (k != null) | |
return Expression.Call(this.GetType(), "InvokeDynamic", new Type[0], v, k); | |
else | |
{ | |
var v1 = Expression.Parameter(typeof(FDynamic), "v"); | |
return Expression.Call(this.GetType(), "InvokeDynamic", new Type[0], v, Expression.Lambda(c(v1), v1)); | |
} | |
}; | |
standardContinuation = null; | |
return Visit(exp.Arguments[1]); | |
}; | |
standardContinuation = null; | |
return Visit(exp.Arguments[0]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment