//todo working on scope for better emit public System.Delegate Compile(System.Type target, IExpressionVisitor <object> visitor) { //pass scoped arguments // refer System.Linq.Expression.Compiler folder var context = TypeContext.Default; System.Type returnType; if (ReturnSyntax != null) { returnType = ReturnSyntax.ResolveType(context); } else { returnType = TypeProvider.AnyType; } var names = Parameters.Map(para => para.Name).AddFirst("closure"); int length = Parameters.Count; System.Type[] types = new System.Type[length]; var parameters = new ParameterInfo[length]; for (int i = 0; i < Parameters.Count; i++) { var para = Parameters[i]; System.Type type = para.Type == null ? TypeProvider.AnyType : para.Type.ResolveType(context); parameters[i] = new ParameterInfo(para.Name, i + 1, type, para.IsVarArgs); types[i] = type; } // Emit First Argument var lamdaVisit = new LamdaVisitor(names); Body.Accept(lamdaVisit); var parameterTypes = types.AddFirst(typeof(Closure)); var method = new System.Reflection.Emit.DynamicMethod("lambda_method", returnType, parameterTypes, true); var methodGen = new Generators.DynamicMethodGenerator(method, parameters, target) { SyntaxBody = Body, Context = context }; methodGen.EmitParameterInfo(); var bodyGen = new MethodBodyGenerator(methodGen, method.GetILGenerator()); object[] values = new object[lamdaVisit.HoistedLocals.Count]; if (values.Length > 0) { int index = 0; var field = typeof(Closure).GetField("Values"); foreach (var item in lamdaVisit.HoistedLocals) { var value = item.Value; values[index] = value.Accept(visitor); var variable = bodyGen.DeclareVariable(value.Type, item.Key); bodyGen.LoadArgument(0); bodyGen.LoadField(field); bodyGen.LoadInt32(index); bodyGen.LoadArrayElement(typeof(object)); bodyGen.UnboxObject(value.Type); bodyGen.StoreVariable(variable); index++; } } bodyGen.Compile(); var delgateType = DelegateGen.MakeNewDelegate(types, returnType); Type = delgateType; return(method.CreateDelegate(delgateType, new Runtime.Closure(values))); }