Esempio n. 1
0
        public static Value FoldL(INSGenerator generator, Arguments arguments)
        {
            var iterator = new NSIterator(generator);

            using var assistant = new ParameterAssistant(arguments);
            var block = assistant.Block();

            if (block == null)
            {
                return(NilValue);
            }

            iterator.Reset();

            assistant.TwoValueParameters();
            var initialFromArguments = arguments[0];
            var initialValue         = initialFromArguments.IsEmpty ? iterator.Next() : initialFromArguments;

            if (initialValue.IsNil)
            {
                return(initialValue);
            }

            var secondValue = iterator.Next();

            if (secondValue.IsNil)
            {
                return(initialValue);
            }

            assistant.SetParameterValues(initialValue, secondValue);
            var value  = block.Evaluate();
            var signal = Signal();

            if (signal == Breaking)
            {
                return(value);
            }

            switch (signal)
            {
            case ReturningNull:
                return(null);

            case Continuing:
                return(value);
            }

            var next = iterator.Next();

            if (next.IsNil)
            {
                return(value);
            }

            for (var i = 0; i < MAX_LOOP; i++)
            {
                assistant.SetParameterValues(value, next);
                value  = block.Evaluate();
                signal = Signal();
                if (signal == Breaking)
                {
                    break;
                }

                switch (signal)
                {
                case ReturningNull:
                    return(null);

                case Continuing:
                    continue;
                }

                next = iterator.Next();
                if (next.IsNil)
                {
                    return(value);
                }
            }

            return(value);
        }