コード例 #1
0
        protected List <Parsed.Object> MultiDivert()
        {
            Whitespace();

            List <Parsed.Object> diverts = null;

            // Try single thread first
            var threadDivert = Parse(StartThread);

            if (threadDivert)
            {
                diverts = new List <Object> ();
                diverts.Add(threadDivert);
                return(diverts);
            }

            // Normal diverts and tunnels
            var arrowsAndDiverts = Interleave <object> (
                ParseDivertArrowOrTunnelOnwards,
                DivertIdentifierWithArguments);

            if (arrowsAndDiverts == null)
            {
                return(null);
            }

            diverts = new List <Parsed.Object> ();

            // Possible patterns:
            //  ->                   -- explicit gather
            //  ->->                 -- tunnel onwards
            //  -> div               -- normal divert
            //  ->-> div             -- tunnel onwards, followed by override divert
            //  -> div ->            -- normal tunnel
            //  -> div ->->          -- tunnel then tunnel continue
            //  -> div -> div        -- tunnel then divert
            //  -> div -> div ->     -- tunnel then tunnel
            //  -> div -> div ->->
            //  -> div -> div ->-> div    (etc)

            // Look at the arrows and diverts
            for (int i = 0; i < arrowsAndDiverts.Count; ++i)
            {
                bool isArrow = (i % 2) == 0;

                // Arrow string
                if (isArrow)
                {
                    // Tunnel onwards
                    if ((string)arrowsAndDiverts [i] == "->->")
                    {
                        bool tunnelOnwardsPlacementValid = (i == 0 || i == arrowsAndDiverts.Count - 1 || i == arrowsAndDiverts.Count - 2);
                        if (!tunnelOnwardsPlacementValid)
                        {
                            Error("Tunnel onwards '->->' must only come at the begining or the start of a divert");
                        }

                        var tunnelOnwards = new TunnelOnwards();
                        if (i < arrowsAndDiverts.Count - 1)
                        {
                            var tunnelOnwardDivert = arrowsAndDiverts [i + 1] as Parsed.Divert;
                            tunnelOnwards.divertAfter = tunnelOnwardDivert;
                        }

                        diverts.Add(tunnelOnwards);

                        // Not allowed to do anything after a tunnel onwards.
                        // If we had anything left it would be caused in the above Error for
                        // the positioning of a ->->
                        break;
                    }
                }

                // Divert
                else
                {
                    var divert = arrowsAndDiverts [i] as Divert;

                    // More to come? (further arrows) Must be tunnelling.
                    if (i < arrowsAndDiverts.Count - 1)
                    {
                        divert.isTunnel = true;
                    }

                    diverts.Add(divert);
                }
            }

            // Single -> (used for default choices)
            if (diverts.Count == 0 && arrowsAndDiverts.Count == 1)
            {
                var gatherDivert = new Divert((Parsed.Object)null);
                gatherDivert.isEmpty = true;
                diverts.Add(gatherDivert);

                if (!_parsingChoice)
                {
                    Error("Empty diverts (->) are only valid on choices");
                }
            }

            return(diverts);
        }
コード例 #2
0
        protected List <Parsed.Object> MultiDivert()
        {
            Whitespace();

            List <Parsed.Object> diverts = null;

            // Try single thread first
            var threadDivert = Parse(StartThread);

            if (threadDivert)
            {
                diverts = new List <Object> ();
                diverts.Add(threadDivert);
                return(diverts);
            }

            // Normal diverts and tunnels
            var arrowsAndDiverts = Interleave <object> (
                ParseDivertArrowOrTunnelOnwards,
                DivertIdentifierWithArguments);

            if (arrowsAndDiverts == null)
            {
                return(null);
            }

            diverts = new List <Parsed.Object> ();

            // Possible patterns:
            //  ->                   -- explicit gather
            //  ->->                 -- tunnel onwards
            //  -> div               -- normal divert
            //  ->-> div             -- tunnel onwards, followed by override divert
            //  -> div ->            -- normal tunnel
            //  -> div ->->          -- tunnel then tunnel continue
            //  -> div -> div        -- tunnel then divert
            //  -> div -> div ->     -- tunnel then tunnel
            //  -> div -> div ->->   (etc)

            bool hasInitialTunnelOnwards = false;
            bool hasFinalTunnelOnwards   = false;

            // Look at the arrows and diverts
            for (int i = 0; i < arrowsAndDiverts.Count; ++i)
            {
                bool isArrow = (i % 2) == 0;

                // Arrow string
                if (isArrow)
                {
                    string arrow = arrowsAndDiverts [i] as string;
                    if (arrow == "->->")
                    {
                        if (i == 0)
                        {
                            hasInitialTunnelOnwards = true;
                        }
                        else if (i == arrowsAndDiverts.Count - 1)
                        {
                            hasFinalTunnelOnwards = true;
                        }
                        else
                        {
                            Error("Tunnel onwards '->->' must only come at the begining or the start of a divert");
                        }
                    }
                }

                // Divert
                else
                {
                    var divert = arrowsAndDiverts [i] as Divert;

                    // More to come? (further arrows) Must be tunnelling.
                    if (i < arrowsAndDiverts.Count - 1)
                    {
                        divert.isTunnel = true;
                    }

                    diverts.Add(divert);
                }
            }

            // ->-> (with optional override divert)
            if (hasInitialTunnelOnwards)
            {
                if (arrowsAndDiverts.Count > 2)
                {
                    Error("Tunnel onwards '->->' must either be on its own or followed by a single target");
                }

                var tunnelOnwards = new TunnelOnwards();

                // Optional override target to divert to after tunnel onwards?
                // Replace divert with the tunnel onwards to that target.
                if (arrowsAndDiverts.Count > 1)
                {
                    var overrideDivert = diverts [0] as Parsed.Divert;
                    tunnelOnwards.overrideReturnPath = overrideDivert.target;
                    diverts.RemoveAt(0);
                }

                diverts.Add(tunnelOnwards);
            }

            // Single ->
            else if (diverts.Count == 0 && arrowsAndDiverts.Count == 1)
            {
                var gatherDivert = new Divert((Parsed.Object)null);
                gatherDivert.isToGather = true;
                diverts.Add(gatherDivert);
            }

            // Divert that terminates in ->->
            else if (hasFinalTunnelOnwards)
            {
                diverts.Add(new TunnelOnwards());
            }

            return(diverts);
        }