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); }