public static Expression MakeExpression(bool nullable, string members, Expression[] args) { // Warning: modifies args if (args.Length == 0) { throw new LispException("Member accessor invoked without a target: {0}", members); } var names = members.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries); var code = args[0]; if (nullable) { var temp = Expression.Parameter(typeof(object)); for (var i = 0; i < names.Length; ++i) { Expression code2; if (i < names.Length - 1) { var binder = Runtime.GetInvokeMemberBinder(new InvokeMemberBinderKey(names[i], 0)); code2 = Runtime.CompileDynamicExpression(binder, typeof(object), new Expression[] { code }); } else { var binder = Runtime.GetInvokeMemberBinder(new InvokeMemberBinderKey(names[i], args.Length - 1)); args[0] = code; code2 = Runtime.CompileDynamicExpression(binder, typeof(object), args); } code = Expression.Condition(Runtime.WrapBooleanTest(Expression.Assign(temp, code)), code2, Expression.Constant(null)); } code = Expression.Block(typeof(object), new ParameterExpression[] { temp }, code); } else { for (var i = 0; i < names.Length; ++i) { if (i < names.Length - 1) { var binder = Runtime.GetInvokeMemberBinder(new InvokeMemberBinderKey(names[i], 0)); code = Runtime.CompileDynamicExpression(binder, typeof(object), new Expression[] { code }); } else { var binder = Runtime.GetInvokeMemberBinder(new InvokeMemberBinderKey(names[i], args.Length - 1)); args[0] = code; code = Runtime.CompileDynamicExpression(binder, typeof(object), args); } } } return(code); }
public override DynamicMetaObject FallbackInvoke( DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) { var argexprs = new Expression[args.Length + 1]; for (var i = 0; i < args.Length; i++) { argexprs[i + 1] = args[i].Expression; } argexprs[0] = target.Expression; return(new DynamicMetaObject( Runtime.CompileDynamicExpression( Runtime.GetInvokeBinder(args.Length), typeof(object), argexprs), target.Restrictions.Merge( BindingRestrictions.Combine(args)))); }
object IApply.Apply(object[] args) { if (args.Length > 12) { var binder = Runtime.GetInvokeBinder(args.Length); var exprs = new List <Expression>(); exprs.Add(Expression.Constant(this)); exprs.AddRange(args.Select(Expression.Constant)); var code = Runtime.CompileDynamicExpression(binder, typeof(object), exprs); var proc = Runtime.CompileToFunction(code); return(proc()); } else { switch (args.Length) { case 0: { return(Proc0()); } case 1: { return(Proc1(args[0])); } case 2: { return(Proc2(args[0], args[1])); } case 3: { return(Proc3(args[0], args[1], args[2])); } case 4: { return(Proc4(args[0], args[1], args[2], args[3])); } case 5: { return(Proc5(args[0], args[1], args[2], args[3], args[4])); } case 6: { return(Proc6(args[0], args[1], args[2], args[3], args[4], args[5])); } case 7: { return(Proc7(args[0], args[1], args[2], args[3], args[4], args[5], args[6])); } case 8: { return(Proc8(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7])); } case 9: { return(Proc9(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8])); } case 10: { return(Proc9(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9])); } case 11: { return(Proc9(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10])); } case 12: { return(Proc9(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11])); } default: { throw new NotImplementedException("Apply supports up to 12 arguments"); } } } }