Exemple #1
0
        /// <summary>
        /// Step through a Range of objects that are not Numeric or String.
        /// </summary>
        private static object StepObject(EachStorage /*!*/ storage, BlockParam /*!*/ block, Range /*!*/ self, object begin, object end, int step)
        {
            Assert.NotNull(storage, block, self);
            CheckStep(storage, step);
            CheckBegin(storage, self.Begin);

            object item = begin, result;
            int    comp;

            var succSite = storage.SuccSite;

            while ((comp = Protocols.Compare(storage, item, end)) < 0)
            {
                if (block.Yield(item, out result))
                {
                    return(result);
                }

                for (int i = 0; i < step; ++i)
                {
                    item = succSite.Target(succSite, item);
                }
            }

            if (comp == 0 && !self.ExcludeEnd)
            {
                if (block.Yield(item, out result))
                {
                    return(result);
                }
            }
            return(self);
        }
Exemple #2
0
        /// <summary>
        /// Step through a Range of objects that are not Numeric or String.
        /// </summary>
        private static IEnumerable <object> EachStepObject(EachStorage /*!*/ storage, Range /*!*/ self, int step)
        {
            Assert.NotNull(storage, self);
            CheckStep(storage, step);

            int    comp;
            object begin = self.Begin;

            CheckBegin(storage, begin);

            object end      = self.End;
            object item     = begin;
            var    succSite = storage.SuccSite;

            while ((comp = Protocols.Compare(storage, item, end)) < 0)
            {
                yield return(item);

                for (int i = 0; i < step; ++i)
                {
                    item = succSite.Target(succSite, item);
                }
            }

            if (comp == 0 && !self.ExcludeEnd)
            {
                yield return(item);
            }
        }
Exemple #3
0
        public static IEnumerable <object> EachInRange(EachStorage /*!*/ storage, Range /*!*/ self, object step)
        {
            if (self.Begin is int && self.End is int)
            {
                // self.begin is Fixnum; directly call item = item + 1 instead of succ
                return(EachStepFixnum(self, ConvertStepToInt(storage, step)));
            }
            else if (self.Begin is MutableString)
            {
                // self.begin is String; use item.succ and item <=> self.end but make sure you check the length of the strings
#if SILVERLIGHT
                return(EachStepString(storage, self, ConvertStepToInt(storage, step)).Cast <object>());
#else
                return(CollectionUtils.ToCovariant <MutableString, object>(EachStepString(storage, self, ConvertStepToInt(storage, step))));
#endif
            }
            else if (storage.Context.IsInstanceOf(self.Begin, storage.Context.GetClass(typeof(Numeric))))
            {
                // self.begin is Numeric; invoke item = item + 1 instead of succ and invoke < or <= for compare
                return(EachStepNumeric(storage, self, step));
            }
            else
            {
                // self.begin is not Numeric or String; just invoke item.succ and item <=> self.end
                return(EachStepObject(storage, self, ConvertStepToInt(storage, step)));
            }
        }
Exemple #4
0
 /// <summary>
 /// Check that the object responds to "succ".
 /// </summary>
 private static void CheckBegin(EachStorage /*!*/ storage, object begin)
 {
     if (!Protocols.RespondTo(storage.RespondToSite, storage.Context, begin, "succ"))
     {
         throw RubyExceptions.CreateTypeError("can't iterate from {0}", storage.Context.GetClassDisplayName(begin));
     }
 }
Exemple #5
0
        public static object GetMinimum(EachStorage /*!*/ comparisonStorage, Range /*!*/ self)
        {
            if (IsBeginGreatherThanEnd(comparisonStorage, self))
            {
                return(null);
            }

            return(self.Begin);
        }
Exemple #6
0
        private static int ConvertStepToInt(EachStorage storage, object step)
        {
            if (step is int)
            {
                return((int)step);
            }

            var site = storage.FixnumCastSite;

            return(site.Target(site, step));
        }
Exemple #7
0
        public static object GetMaximum(EachStorage /*!*/ comparisonStorage, Range /*!*/ self)
        {
            if (IsBeginGreatherThanEnd(comparisonStorage, self))
            {
                return(null);
            }

            if (!self.ExcludeEnd)
            {
                return(self.End);
            }

            return(EachInRange(comparisonStorage, self, 1).Last());
        }
Exemple #8
0
 public static object Each(EachStorage /*!*/ storage, [NotNull] BlockParam /*!*/ block, Range /*!*/ self)
 {
     if (self.Begin is int && self.End is int)
     {
         return(StepFixnum(block, self, (int)self.Begin, (int)self.End, 1));
     }
     else if (self.Begin is MutableString)
     {
         return(StepString(storage, block, self, (MutableString)self.Begin, (MutableString)self.End, 1));
     }
     else
     {
         return(StepObject(storage, block, self, self.Begin, self.End, 1));
     }
 }
Exemple #9
0
        /// <summary>
        /// Check that the object, when converted to an integer, is not less than or equal to zero.
        /// </summary>
        private static void CheckStep(EachStorage /*!*/ storage, object step)
        {
            var equals = storage.EqualsSite;

            if (Protocols.IsTrue(equals.Target(equals, step, 0)))
            {
                throw RubyExceptions.CreateArgumentError("step can't be 0");
            }

            var lessThan = storage.LessThanSite;

            if (RubyOps.IsTrue(lessThan.Target(lessThan, step, 0)))
            {
                throw RubyExceptions.CreateArgumentError("step can't be negative");
            }
        }
Exemple #10
0
        public static object Each(EachStorage /*!*/ storage, [NotNull] BlockParam /*!*/ block, Range /*!*/ self)
        {
            Assert.NotNull(block);
            CheckBegin(storage, self.Begin);

            var each = EachInRange(storage, self, 1);

            foreach (var item in each)
            {
                object result;
                if (block.Yield(item, out result))
                {
                    return(result);
                }
            }

            return(self);
        }
Exemple #11
0
        /// <summary>
        /// Step through a Range of Strings.
        /// </summary>
        /// <remarks>
        /// This method requires step to be a Fixnum.
        /// It uses a hybrid string comparison to prevent infinite loops and calls String#succ to get each item in the range.
        /// </remarks>
        private static object StepString(EachStorage /*!*/ storage, BlockParam /*!*/ block, Range /*!*/ self, MutableString begin, MutableString end, int step)
        {
            Assert.NotNull(storage, block, self);
            CheckStep(step);
            object        result;
            MutableString item = begin;
            int           comp;

            while ((comp = Protocols.Compare(storage, item, end)) < 0)
            {
                if (block.Yield(item.Clone(), out result))
                {
                    return(result);
                }

                if (ReferenceEquals(item, begin))
                {
                    item = item.Clone();
                }

                // TODO: this can be optimized
                for (int i = 0; i < step; i++)
                {
                    MutableStringOps.SuccInPlace(item);
                }

                if (item.Length > end.Length)
                {
                    return(self);
                }
            }

            if (comp == 0 && !self.ExcludeEnd)
            {
                if (block.Yield(item.Clone(), out result))
                {
                    return(result);
                }
            }
            return(self);
        }
Exemple #12
0
        public static object GetMinimumBy(EachStorage /*!*/ comparisonStorage, BlockParam /*!*/ block, Range /*!*/ self)
        {
            if (IsBeginGreatherThanEnd(comparisonStorage, self))
            {
                return(null);
            }

            var each = EachInRange(comparisonStorage, self, 1);

            return(each.Aggregate((x, y) => {
                object blockResult;
                if (block.Yield(y, x, out blockResult))
                {
                    return blockResult;
                }

                int r = Protocols.ConvertCompareResult(comparisonStorage, blockResult);

                return r < 0 ? y : x;
            }));
        }
Exemple #13
0
        public static object Step(EachStorage /*!*/ storage, [NotNull] BlockParam /*!*/ block, Range /*!*/ self, [Optional] object step)
        {
            if (step == Missing.Value)
            {
                step = ClrInteger.One;
            }

            Assert.NotNull(block);

            var each = EachInRange(storage, self, step);

            foreach (var item in each)
            {
                object result;
                if (block.Yield(item, out result))
                {
                    return(result);
                }
            }

            return(self);
        }
Exemple #14
0
        /// <summary>
        /// Step through a Range of Numerics.
        /// </summary>
        private static IEnumerable <object> EachStepNumeric(EachStorage /*!*/ storage, Range /*!*/ self, object step)
        {
            Assert.NotNull(storage, self);
            CheckStep(storage, step);

            object item = self.Begin;
            object end  = self.End;

            int comp;

            while ((comp = Protocols.Compare(storage, item, end)) < 0)
            {
                yield return(item);

                var add = storage.AddSite;
                item = add.Target(add, item, step);
            }

            if (comp == 0 && !self.ExcludeEnd)
            {
                yield return(item);
            }
        }
Exemple #15
0
        public static object GetMinimumBy(EachStorage/*!*/ comparisonStorage, BlockParam/*!*/ block, Range/*!*/ self) {
            if (IsBeginGreatherThanEnd(comparisonStorage, self)) {
                return null;
            }

            var each = EachInRange(comparisonStorage, self, 1);

            return each.Aggregate((x, y) => {
                object blockResult;
                if (block.Yield(y, x, out blockResult)) {
                    return blockResult;
                }

                int r = Protocols.ConvertCompareResult(comparisonStorage, blockResult);

                return r < 0 ? y : x;
            });
        }
Exemple #16
0
        public static object GetMinimum(EachStorage/*!*/ comparisonStorage, Range/*!*/ self) {
            if (IsBeginGreatherThanEnd(comparisonStorage, self)) {
                return null;
            }

            return self.Begin;
        }
Exemple #17
0
        public static object GetMaximum(EachStorage/*!*/ comparisonStorage, Range/*!*/ self) {
            if (IsBeginGreatherThanEnd(comparisonStorage, self)) {
                return null;
            }

            if (!self.ExcludeEnd) {
                return self.End;
            }

            return EachInRange(comparisonStorage, self, 1).Last();
        }
Exemple #18
0
        /// <summary>
        /// Step through a Range of objects that are not Numeric or String.
        /// </summary>
        private static IEnumerable<object> EachStepObject(EachStorage/*!*/ storage, Range/*!*/ self, int step) {
            Assert.NotNull(storage, self);
            CheckStep(storage, step);

            int comp;
            object begin = self.Begin;

            CheckBegin(storage, begin);

            object end = self.End;
            object item = begin;
            var succSite = storage.SuccSite;

            while ((comp = Protocols.Compare(storage, item, end)) < 0) {
                yield return item;

                for (int i = 0; i < step; ++i) {
                    item = succSite.Target(succSite, item);
                }
            }

            if (comp == 0 && !self.ExcludeEnd) {
                yield return item;
            }
        }
Exemple #19
0
        /// <summary>
        /// Step through a Range of Numerics.
        /// </summary>
        private static IEnumerable<object> EachStepNumeric(EachStorage/*!*/ storage, Range/*!*/ self, object step) {
            Assert.NotNull(storage, self);
            CheckStep(storage, step);

            object item = self.Begin;
            object end = self.End;

            int comp;
            while ((comp = Protocols.Compare(storage, item, end)) < 0) {
                yield return item;

                var add = storage.AddSite;
                item = add.Target(add, item, step);
            }

            if (comp == 0 && !self.ExcludeEnd) {
                yield return item;
            }
        }
Exemple #20
0
        /// <summary>
        /// Step through a Range of Strings.
        /// </summary>
        /// <remarks>
        /// This method requires step to be a Fixnum.
        /// It uses a hybrid string comparison to prevent infinite loops and calls String#succ to get each item in the range.
        /// </remarks>
        private static object StepString(EachStorage/*!*/ storage, BlockParam/*!*/ block, Range/*!*/ self, MutableString begin, MutableString end, int step) {
            Assert.NotNull(storage, block, self);
            CheckStep(step);
            object result;
            MutableString item = begin;
            int comp;

            var succSite = storage.SuccSite;
            while ((comp = Protocols.Compare(storage, item, end)) < 0) {
                if (block.Yield(item.Clone(), out result)) {
                    return result;
                }

                if (ReferenceEquals(item, begin)) {
                    item = item.Clone();
                }

                // TODO: this can be optimized 
                for (int i = 0; i < step; i++) {
                    MutableStringOps.SuccInPlace(item);
                }

                if (item.Length > end.Length) {
                    return self;
                }
            }

            if (comp == 0 && !self.ExcludeEnd) {
                if (block.Yield(item.Clone(), out result)) {
                    return result;
                }
            }
            return self;
        }
Exemple #21
0
        private static int ConvertStepToInt(EachStorage storage, object step) {
            if (step is int) {
                return (int)step;
            }

            var site = storage.FixnumCastSite;
            return site.Target(site, step);
        }
Exemple #22
0
        public static IEnumerable<object> EachInRange(EachStorage/*!*/ storage, Range/*!*/ self, object step) {
            if (self.Begin is int && self.End is int) {
                // self.begin is Fixnum; directly call item = item + 1 instead of succ
                return EachStepFixnum(self, ConvertStepToInt(storage, step));
            } else if (self.Begin is MutableString) {
                // self.begin is String; use item.succ and item <=> self.end but make sure you check the length of the strings
#if SILVERLIGHT
                return EachStepString(storage, self, ConvertStepToInt(storage, step)).Cast<object>();
#else
                return EachStepString(storage, self, ConvertStepToInt(storage, step));
#endif
            } else if (storage.Context.IsInstanceOf(self.Begin, storage.Context.GetClass(typeof(Numeric)))) {
                // self.begin is Numeric; invoke item = item + 1 instead of succ and invoke < or <= for compare
                return EachStepNumeric(storage, self, step);
            } else {
                // self.begin is not Numeric or String; just invoke item.succ and item <=> self.end
                return EachStepObject(storage, self, ConvertStepToInt(storage, step));
            }
        }
Exemple #23
0
 public static Enumerator /*!*/ GetStepEnumerator(EachStorage /*!*/ storage, Range /*!*/ self, [Optional] object step)
 {
     return(new Enumerator((_, block) => Step(storage, block, self, step)));
 }
Exemple #24
0
        /// <summary>
        /// Check that the object, when converted to an integer, is not less than or equal to zero.
        /// </summary>
        private static void CheckStep(EachStorage/*!*/ storage, object step) {
            var equals = storage.EqualsSite;
            if (Protocols.IsTrue(equals.Target(equals, step, 0))) {
                throw RubyExceptions.CreateArgumentError("step can't be 0");
            }

            var lessThan = storage.LessThanSite;
            if (RubyOps.IsTrue(lessThan.Target(lessThan, step, 0))) {
                throw RubyExceptions.CreateArgumentError("step can't be negative");
            }
        }
Exemple #25
0
 public static Enumerator/*!*/ GetEachEnumerator(EachStorage/*!*/ storage, Range/*!*/ self) {
     return new Enumerator((_, block) => Each(storage, block, self));
 }
Exemple #26
0
 public static Enumerator/*!*/ GetStepEnumerator(EachStorage/*!*/ storage, Range/*!*/ self, [Optional]object step) {
     return new Enumerator((_, block) => Step(storage, block, self, step));
 }
Exemple #27
0
 public static object Each(EachStorage/*!*/ storage, [NotNull]BlockParam/*!*/ block, Range/*!*/ self) {
     if (self.Begin is int && self.End is int) {
         return StepFixnum(block, self, (int)self.Begin, (int)self.End, 1);
     } else if (self.Begin is MutableString) {
         return StepString(storage, block, self, (MutableString)self.Begin, (MutableString)self.End, 1);
     } else {
         return StepObject(storage, block, self, self.Begin, self.End, 1);
     }
 }
Exemple #28
0
        public static object Step(EachStorage/*!*/ storage, [NotNull]BlockParam/*!*/ block, Range/*!*/ self, [Optional]object step) {
            if (step == Missing.Value) {
                step = ClrInteger.One;
            }

            Assert.NotNull(block);

            var each = EachInRange(storage, self, step);

            foreach (var item in each) {
                object result;
                if (block.Yield(item, out result)) {
                    return result;
                }
            }

            return self;
        }
Exemple #29
0
        /// <summary>
        /// Step through a Range of objects that are not Numeric or String.
        /// </summary>
        private static object StepObject(EachStorage/*!*/ storage, BlockParam/*!*/ block, Range/*!*/ self, object begin, object end, int step) {
            Assert.NotNull(storage, block, self);
            CheckStep(storage, step);
            CheckBegin(storage, self.Begin);

            object item = begin, result;
            int comp;

            var succSite = storage.SuccSite;
            while ((comp = Protocols.Compare(storage, item, end)) < 0) {
                if (block.Yield(item, out result)) {
                    return result;
                }

                for (int i = 0; i < step; ++i) {
                    item = succSite.Target(succSite, item);
                }
            }

            if (comp == 0 && !self.ExcludeEnd) {
                if (block.Yield(item, out result)) {
                    return result;
                }
            }
            return self;
        }
Exemple #30
0
 public static Enumerator /*!*/ GetEachEnumerator(EachStorage /*!*/ storage, Range /*!*/ self)
 {
     return(new Enumerator((_, block) => Each(storage, block, self)));
 }
Exemple #31
0
 /// <summary>
 /// Check that the object responds to "succ".
 /// </summary>
 private static void CheckBegin(EachStorage/*!*/ storage, object begin) {
     if (!Protocols.RespondTo(storage.RespondToSite, storage.Context, begin, "succ")) {
         throw RubyExceptions.CreateTypeError("can't iterate from {0}", storage.Context.GetClassDisplayName(begin));
     }
 }
Exemple #32
0
        public static object Each(EachStorage/*!*/ storage, [NotNull]BlockParam/*!*/ block, Range/*!*/ self) {
            Assert.NotNull(block);
            CheckBegin(storage, self.Begin);

            var each = EachInRange(storage, self, 1);

            foreach (var item in each) {
                object result;
                if (block.Yield(item, out result)) {
                    return result;
                }
            }

            return self;
        }