Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
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);
     }
 }
Ejemplo n.º 3
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);
        }