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