Пример #1
0
        public bool Iterate(Interpreter ii, RepeaterBlueprint bp)
        {
            if (Finished)
            {
                ii.PopRepeater();
                return false;
            }

            // Queue the next iteration on the current state
            ii.CurrentState.AddPreBlueprint(bp);

            // Push separator if applicable
            if (!IsLast && _attribs.Separator != null && _attribs.Separator.Any())
            {
                var sepState = Interpreter.State.CreateDerivedDistinct(
                    ii.CurrentState.Reader.Source,
                    _attribs.Separator,
                    ii,
                    ii.CurrentState.Output);

                // Make sure that the repeater is not available to the separator pattern
                sepState.AddPreBlueprint(new RepeaterStackBlueprint(ii, this, RepeaterStackAction.Pop));
                sepState.AddPostBlueprint(new RepeaterStackBlueprint(ii, this, RepeaterStackAction.Push));

                ii.PushState(sepState);
            }

            // Push postfix if applicable
            if (_attribs.After != null && _attribs.After.Any())
            {
                ii.PushState(Interpreter.State.CreateDerivedDistinct(
                    ii.CurrentState.Reader.Source,
                    _attribs.After,
                    ii,
                    ii.CurrentState.Output));
            }

            // Push next item
            var itemState = Interpreter.State.CreateDerivedDistinct(ii.CurrentState.Reader.Source,
                _items[_attribs.Sync != null ? _attribs.Sync.NextItem(_items.Length) : ii.RNG.Next(_items.Length)],
                ii,
                ii.CurrentState.Output);

            // Add a blueprint that iterates the repeater just before reading the item. This makes sure that tags like [first] can run before this happens.
            itemState.AddPostBlueprint(new FunctionBlueprint(ii, _ =>
            {
                Next();
                return false;
            }));

            ii.PushState(itemState);

            // Push prefix if applicable
            if (_attribs.Before != null && _attribs.Before.Any())
            {
                ii.PushState(Interpreter.State.CreateDerivedDistinct(
                    ii.CurrentState.Reader.Source,
                    _attribs.Before,
                    ii,
                    ii.CurrentState.Output));
            }
            
            return true;
        }