public override DynamicMetaObject FallbackUnaryOperation(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue)
            {
                return(Defer(target));
            }

            DynamicMetaObject firstVarargs;

            if (RuntimeHelpers.TryGetFirstVarargs(target, out firstVarargs))
            {
                return(FallbackUnaryOperation(firstVarargs, errorSuggestion));
            }

            Expr expression;

            switch (Operation)
            {
            case ExprType.Negate:
                expression = NegateOp(target);
                break;

            case ExprType.Not:
                expression = NotOp(target);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(new DynamicMetaObject(Expr.Convert(expression, typeof(object)), RuntimeHelpers.MergeTypeRestrictions(target)));
        }
        public override DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue || !arg.HasValue)
            {
                return(Defer(target, arg));
            }

            DynamicMetaObject targetFirst, argFirst;

            if (RuntimeHelpers.TryGetFirstVarargs(target, out targetFirst) | RuntimeHelpers.TryGetFirstVarargs(arg, out argFirst))
            {
                return(FallbackBinaryOperation(targetFirst, argFirst, errorSuggestion));
            }

            Expr expression = null;

            switch (BinaryExprTypes[Operation])
            {
            case BinaryOpType.Relational:
                expression = Relational(target, arg);
                break;

            case BinaryOpType.Logical:
                expression = Logical(target, arg);
                break;

            case BinaryOpType.Numeric:
                expression = Numeric(target, arg);
                break;
            }

            if (expression == null)
            {
                expression = MetamethodFallbacks.BinaryOp(context, Operation, target, arg);
            }

            return(new DynamicMetaObject(Expr.Convert(expression, typeof(object)), RuntimeHelpers.MergeTypeRestrictions(target, arg)));
        }