示例#1
0
        /// <summary>
        /// Step through a Range of Numerics.
        /// </summary>
        /// <remarks>
        /// </remarks>
        private static object StepNumeric(RubyContext /*!*/ context, BlockParam block, Range /*!*/ self, object begin, object end, object step)
        {
            CheckStep(context, step);

            object item = begin;

            Protocols.DynamicInvocation compareOp;
            if (self.ExcludeEnd)
            {
                compareOp = LibrarySites.LessThan;
            }
            else
            {
                compareOp = LibrarySites.LessThanOrEqual;
            }

            object result;

            while (RubyOps.IsTrue(compareOp(context, item, end)))
            {
                if (block == null)
                {
                    throw RubyExceptions.NoBlockGiven();
                }

                if (block.Yield(item, out result))
                {
                    return(result);
                }

                item = LibrarySites.Add(context, item, step);
            }

            return(self);
        }
示例#2
0
        public static object UpTo(RubyContext /*!*/ context, BlockParam block, object /*!*/ self, object other)
        {
            object i       = self;
            object compare = null;

            while (RubyOps.IsFalse(compare))
            {
                // Rather than test i <= other we test !(i > other)
                compare = LibrarySites.GreaterThan(context, i, other);

                // If the comparison failed (i.e. returned null) then we throw an error.
                if (compare == null)
                {
                    throw RubyExceptions.MakeComparisonError(context, i, other);
                }

                // If the comparison worked but returned false then we carry on
                if (RubyOps.IsFalse(compare))
                {
                    if (block == null)
                    {
                        throw RubyExceptions.NoBlockGiven();
                    }

                    object result;
                    if (block.Yield(i, out result))
                    {
                        return(result);
                    }
                    i = LibrarySites.Add(context, i, 1);
                }
            }
            return(self);
        }
示例#3
0
        public static RubyArray DivMod(RubyContext /*!*/ context, object self, object other)
        {
            object div = Div(context, self, other);
            object mod = LibrarySites.Modulo(context, self, other);

            return(RubyOps.MakeArray2(div, mod));
        }
示例#4
0
 public static object Abs(RubyContext /*!*/ context, object self)
 {
     if (RubyOps.IsTrue(LibrarySites.LessThan(context, self, 0)))
     {
         return(LibrarySites.UnaryMinus(context, self));
     }
     return(self);
 }
示例#5
0
 public static int Bit(RubyContext /*!*/ context, int self, object index)
 {
     try {
         object intIndex = Protocols.ConvertToInteger(context, index);
         return(LibrarySites.BitRef(context, self, intIndex));
     } catch (FloatDomainError) {
         throw RubyExceptions.CreateRangeError("float " + index.ToString() + " out of range of integer");
     }
 }
示例#6
0
 public static bool Eql(RubyContext /*!*/ context, Range /*!*/ self, [NotNull] Range /*!*/ other)
 {
     if (self == other)
     {
         return(true);
     }
     return(LibrarySites.Eql(context, self.Begin, other.Begin) &&
            LibrarySites.Eql(context, self.End, other.End) &&
            self.ExcludeEnd == other.ExcludeEnd);
 }
示例#7
0
 /// <summary>
 /// Check that the object, when converted to an integer, is not less than or equal to zero.
 /// </summary>
 private static void CheckStep(RubyContext /*!*/ context, object step)
 {
     if (RubySites.Equal(context, step, 0))
     {
         throw RubyExceptions.CreateArgumentError("step can't be 0");
     }
     if (RubyOps.IsTrue(LibrarySites.LessThan(context, step, 0)))
     {
         throw RubyExceptions.CreateArgumentError("step can't be negative");
     }
 }
示例#8
0
 public static object Step(RubyContext /*!*/ context, BlockParam block, object self, object limit, object step)
 {
     if (self is double || limit is double || step is double)
     {
         // At least one of the arguments is double so convert all to double and run the Float version of Step
         double floatSelf  = Protocols.ConvertToFloat(context, self);
         double floatLimit = Protocols.ConvertToFloat(context, limit);
         double floatStep  = Protocols.ConvertToFloat(context, step);
         return(Step(context, block, floatSelf, floatLimit, floatSelf));
     }
     else
     {
         #region The generic step algorithm:
         // current = self
         // if step is postive then
         //   while current < limit do
         //     yield(current)
         //     current = current + step
         //   end
         // else
         //   while current > limit do
         //     yield(current)
         //     current = current + step
         //   end
         // return self
         #endregion
         bool isStepZero = Protocols.IsEqual(context, step, 0);
         if (isStepZero)
         {
             throw RubyExceptions.CreateArgumentError("step can't be 0");
         }
         bool isStepPositive = RubyOps.IsTrue(LibrarySites.GreaterThan(context, step, 0));
         Protocols.DynamicInvocation compare;
         if (isStepPositive)
         {
             compare = LibrarySites.GreaterThan;
         }
         else
         {
             compare = LibrarySites.LessThan;
         }
         object current = self;
         while (!RubyOps.IsTrue(compare.Invoke(context, current, limit)))
         {
             object result;
             if (YieldStep(block, current, out result))
             {
                 return(result);
             }
             current = LibrarySites.Add(context, current, step);
         }
         return(self);
     }
 }
示例#9
0
 public static object IsNonZero(RubyContext /*!*/ context, object self)
 {
     if (LibrarySites.IsZero(context, self))
     {
         return(null);
     }
     else
     {
         return(self);
     }
 }
示例#10
0
        public static object Remainder(RubyContext /*!*/ context, object self, object other)
        {
            object modulo = LibrarySites.Modulo(context, self, other);

            if (!Protocols.IsEqual(context, modulo, 0))
            {
                // modulo is not zero
                if (RubyOps.IsTrue(LibrarySites.LessThan(context, self, 0)) && RubyOps.IsTrue(LibrarySites.GreaterThan(context, other, 0)) ||
                    RubyOps.IsTrue(LibrarySites.GreaterThan(context, self, 0)) && RubyOps.IsTrue(LibrarySites.LessThan(context, other, 0)))
                {
                    // (self is negative and other is positive) OR (self is positive and other is negative)
                    return(LibrarySites.Minus(context, modulo, other));
                }
            }
            // Either modulo is zero or self and other are not of the same sign
            return(modulo);
        }
示例#11
0
        public static object Times(RubyContext /*!*/ context, BlockParam block, object /*!*/ self)
        {
            object i = 0;

            while (RubyOps.IsTrue(LibrarySites.LessThan(context, i, self)))
            {
                if (block == null)
                {
                    throw RubyExceptions.NoBlockGiven();
                }

                object result;
                if (block.Yield(i, out result))
                {
                    return(result);
                }

                i = LibrarySites.Add(context, i, 1);
            }
            return(self);
        }
示例#12
0
 public static object Div(RubyContext /*!*/ context, object self, object other)
 {
     return(Floor(context, LibrarySites.Divide(context, self, other)));
 }
示例#13
0
 public static object Next(RubyContext /*!*/ context, object /*!*/ self)
 {
     return(LibrarySites.Add(context, self, 1));
 }
示例#14
0
 public static object PrecFloat(RubyContext /*!*/ context, object self)
 {
     return(LibrarySites.InvokePrec(context, context.GetClass(typeof(double)), self));
 }
示例#15
0
 public static object PrecInteger(RubyContext /*!*/ context, object self)
 {
     return(LibrarySites.InvokePrec(context, context.GetClass(typeof(Integer)), self));
 }
示例#16
0
 public static object Prec(object self, [NotNull] RubyClass /*!*/ klass)
 {
     return(LibrarySites.InvokeInducedFrom(klass.Context, klass, self));
 }
示例#17
0
 public static object Quo(RubyContext /*!*/ context, object self, object other)
 {
     return(LibrarySites.Divide(context, self, other));
 }
示例#18
0
 public static object Modulo(RubyContext /*!*/ context, object self, object other)
 {
     return(LibrarySites.ModuloOp(context, self, other));
 }