/// <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); }
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 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)); }
public static object Abs(RubyContext /*!*/ context, object self) { if (RubyOps.IsTrue(LibrarySites.LessThan(context, self, 0))) { return(LibrarySites.UnaryMinus(context, self)); } return(self); }
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"); } }
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); }
/// <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"); } }
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 IsNonZero(RubyContext /*!*/ context, object self) { if (LibrarySites.IsZero(context, self)) { return(null); } else { 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); }
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); }
public static object Div(RubyContext /*!*/ context, object self, object other) { return(Floor(context, LibrarySites.Divide(context, self, other))); }
public static object Next(RubyContext /*!*/ context, object /*!*/ self) { return(LibrarySites.Add(context, self, 1)); }
public static object PrecFloat(RubyContext /*!*/ context, object self) { return(LibrarySites.InvokePrec(context, context.GetClass(typeof(double)), self)); }
public static object PrecInteger(RubyContext /*!*/ context, object self) { return(LibrarySites.InvokePrec(context, context.GetClass(typeof(Integer)), self)); }
public static object Prec(object self, [NotNull] RubyClass /*!*/ klass) { return(LibrarySites.InvokeInducedFrom(klass.Context, klass, self)); }
public static object Quo(RubyContext /*!*/ context, object self, object other) { return(LibrarySites.Divide(context, self, other)); }
public static object Modulo(RubyContext /*!*/ context, object self, object other) { return(LibrarySites.ModuloOp(context, self, other)); }