Пример #1
0
        public int NumberOfActionsToMarker(SkipEndMarker marker)
        {
            int  count      = 0;
            bool foundStart = false;

            for (int i = 0; i < ActionSet.ActionList.Count; i++)
            {
                if (object.ReferenceEquals(ActionSet.ActionList[i], this))
                {
                    if (foundStart)
                    {
                        throw new Exception("Skip start marker is on the action list multiple times.");
                    }
                    foundStart = true;
                }

                if (object.ReferenceEquals(ActionSet.ActionList[i], marker))
                {
                    if (!foundStart)
                    {
                        throw new Exception("Skip start marker not found.");
                    }
                    break;
                }

                if (foundStart && ActionSet.ActionList[i].IsAction)
                {
                    count++;
                }
            }

            return(count - 1);
        }
Пример #2
0
        public void NextCase(IWorkshopTree value)
        {
            // If the state is on a case and the action count was changed, create new skip that will skip to the end of the switch.
            if (AutoBreak && State == SwitchBuilderState.OnCase && actionSet.ActionCount != LastCaseStart)
            {
                // Create the skip and add it to the actionset.
                SkipStartMarker skipToEnd = new SkipStartMarker(actionSet);
                actionSet.AddAction(skipToEnd);

                // Add it to the list of skips that need to skip to the end.
                SkipToEnd.Add(skipToEnd);
            }

            // Update the state.
            State = SwitchBuilderState.OnCase;

            // Mark the start of the case.
            SkipEndMarker startCase = new SkipEndMarker();

            actionSet.AddAction(startCase);

            // Add the skip length to the start of the case to the skipCounts.
            skipCounts.Add(Skipper.GetSkipCount(startCase));

            // Add the skip value.
            skipValues.Add(value);

            // Update the number of actions.
            LastCaseStart = actionSet.ActionCount;
        }
        /// <summary>The method was already called in the stack.</summary>
        private IWorkshopTree RecursiveCall(ActionSet actionSet, MethodCall methodCall)
        {
            // Push new parameters.
            for (int i = 0; i < method.ParameterVars.Length; i++)
            {
                var varReference = actionSet.IndexAssigner[method.ParameterVars[i]];
                if (varReference is RecursiveIndexReference)
                {
                    actionSet.AddAction(((RecursiveIndexReference)varReference).Push(
                                            (Element)methodCall.ParameterValues[i]
                                            ));
                }
            }

            // Add to the continue skip array.
            V_Number skipLength = new V_Number();

            actionSet.AddAction(continueArray.ModifyVariable(
                                    Operation.AppendToArray,
                                    skipLength
                                    ));

            // Restart the method.
            SkipStartMarker resetSkip = new SkipStartMarker(actionSet);

            resetSkip.SetEndMarker(endOfMethod);
            actionSet.AddAction(resetSkip);

            SkipEndMarker continueAtMarker = new SkipEndMarker();

            actionSet.AddAction(continueAtMarker);
            skipLength.Value = continueAt.NumberOfActionsToMarker(continueAtMarker);

            return(returnHandler.GetReturnedValue());
        }
Пример #4
0
        public void Finish()
        {
            SkipEndMarker endMarker = new SkipEndMarker();

            ActionSet.AddAction(endMarker);
            SkipMarker.SkipCount = SkipMarker.GetSkipCount(endMarker);
        }
Пример #5
0
 public void SetEndMarker(SkipEndMarker endMarker)
 {
     if (SkipCount != null)
     {
         throw new Exception("SkipCount not null.");
     }
     EndMarker = endMarker;
 }
        public void Translate(ActionSet actionSet)
        {
            SkipStartMarker ifStart = new SkipStartMarker(actionSet, Expression.Parse(actionSet));

            actionSet.AddAction(ifStart);

            Block.Translate(actionSet);

            List <SkipStartMarker> blockCaps = new List <SkipStartMarker>();

            if (ElseBlock != null || ElseIfs.Length > 0)
            {
                SkipStartMarker ifCap = new SkipStartMarker(actionSet);
                actionSet.AddAction(ifCap);
                blockCaps.Add(ifCap);
            }

            SkipEndMarker ifEnd = new SkipEndMarker();

            actionSet.AddAction(ifEnd);
            ifStart.SkipCount = ifStart.GetSkipCount(ifEnd);

            // Get the else-ifs.
            for (int i = 0; i < ElseIfs.Length; i++)
            {
                bool isLast = i == ElseIfs.Length - 1 && ElseBlock == null;

                SkipStartMarker elseIfStart = new SkipStartMarker(actionSet, ElseIfs[i].Expression.Parse(actionSet));
                actionSet.AddAction(elseIfStart);

                ElseIfs[i].Block.Translate(actionSet);

                if (!isLast)
                {
                    SkipStartMarker elseIfCap = new SkipStartMarker(actionSet);
                    actionSet.AddAction(elseIfCap);
                    blockCaps.Add(elseIfCap);
                }

                SkipEndMarker elseIfEnd = new SkipEndMarker();
                actionSet.AddAction(elseIfEnd);
                elseIfStart.SkipCount = elseIfStart.GetSkipCount(elseIfEnd);
            }

            if (ElseBlock != null)
            {
                ElseBlock.Translate(actionSet);
            }

            SkipEndMarker contextCap = new SkipEndMarker();

            actionSet.AddAction(contextCap);
            foreach (var blockCap in blockCaps)
            {
                blockCap.SkipCount = blockCap.GetSkipCount(contextCap);
            }
        }
Пример #7
0
        public virtual void ApplyReturnSkips()
        {
            SkipEndMarker methodEndMarker = new SkipEndMarker();

            _actionSet.AddAction(methodEndMarker);

            foreach (var returnSkip in _skips)
            {
                returnSkip.SetEndMarker(methodEndMarker);
            }
        }
Пример #8
0
        public override void Translate(ActionSet actionSet)
        {
            int actionCountPreCondition = actionSet.ActionCount;

            Element condition    = (Element)Condition.Parse(actionSet);
            bool    actionsAdded = actionSet.ActionCount > actionCountPreCondition;

            if (!actionsAdded)
            {
                // Create a normal while loop.
                actionSet.AddAction(Element.Part <A_While>(condition));

                // Translate the block.
                Block.Translate(actionSet.Indent());

                // Resolve continues.
                ResolveContinues(actionSet);

                // Cap the block.
                actionSet.AddAction(new A_End());

                // Resolve breaks.
                ResolveBreaks(actionSet);
            }
            else
            {
                // The while condition requires actions to get the value.
                actionSet.ActionList.Insert(actionCountPreCondition, new ALAction(Element.Part <A_While>(new V_True())));

                SkipStartMarker whileEndSkip = new SkipStartMarker(actionSet, condition);
                actionSet.Indent().AddAction(whileEndSkip);

                // Translate the block.
                Block.Translate(actionSet.Indent());

                // Resolve continues.
                ResolveContinues(actionSet);

                // Cap the block.
                actionSet.AddAction(new A_End());

                // Skip to the end when the condition is false.
                SkipEndMarker whileEnd = new SkipEndMarker();
                whileEndSkip.SetEndMarker(whileEnd);
                actionSet.AddAction(whileEnd);

                // Resolve breaks.
                ResolveBreaks(actionSet);
            }
        }
Пример #9
0
        public void AddDefault()
        {
            if (defaultAdded)
            {
                throw new Exception("Default already added.");
            }
            defaultAdded = true;

            // Mark the start of the case.
            SkipEndMarker startCase = new SkipEndMarker();

            actionSet.AddAction(startCase);
            skipCounts.Insert(0, Skipper.GetSkipCount(startCase));
        }
Пример #10
0
        private void Resolve(ActionSet actionSet, List <SkipStartMarker> skips)
        {
            // Create the end marker that marks the spot right before the End action (if continuing) or right after the End action (if breaking).
            SkipEndMarker endMarker = new SkipEndMarker();

            // Add the end marker to the action set.
            actionSet.AddAction(endMarker);

            // Assign the end marker to the continue/break skips.
            foreach (SkipStartMarker startMarker in skips)
            {
                startMarker.SetEndMarker(endMarker);
            }
        }
Пример #11
0
        public virtual void Finish()
        {
            if (!WasSetup)
            {
                throw new Exception("Pattern builder not set up yet.");
            }
            ActionSet.ContinueSkip.SetSkipCount(ActionSet, LoopStart);
            ActionSet.AddAction(Element.Part <A_Loop>());
            ActionSet.ContinueSkip.ResetSkipCount(ActionSet);

            SkipEndMarker loopEnd = new SkipEndMarker();

            ActionSet.AddAction(loopEnd);
            LoopSkipStart.SkipCount = LoopSkipStart.GetSkipCount(loopEnd);
        }
        public void ApplyReturnSkips()
        {
            if (!MultiplePaths)
            {
                return;
            }

            SkipEndMarker methodEndMarker = new SkipEndMarker();

            ActionSet.AddAction(methodEndMarker);

            foreach (var returnSkip in skips)
            {
                returnSkip.SkipCount = returnSkip.GetSkipCount(methodEndMarker);
            }
        }
Пример #13
0
        public virtual void Setup()
        {
            if (WasSetup)
            {
                throw new Exception("Pattern builder already set up.");
            }
            WasSetup = true;
            ActionSet.ContinueSkip.Setup(ActionSet);

            LoopStart = new SkipEndMarker();
            ActionSet.AddAction(LoopStart);

            if (GetCondition != null)
            {
                Condition = GetCondition();
            }

            LoopSkipStart = new SkipStartMarker(ActionSet, Condition);
            ActionSet.AddAction(LoopSkipStart);
        }
Пример #14
0
        public void Finish(Element switchValue)
        {
            // Set state to finished.
            State = SwitchBuilderState.Finished;

            // Mark the end of the switch.
            SkipEndMarker switchEnd = new SkipEndMarker();

            actionSet.AddAction(switchEnd);

            // Update switch skips to skip to the end of the switch.
            foreach (SkipStartMarker skipToEnd in SkipToEnd)
            {
                skipToEnd.SetEndMarker(switchEnd);
            }

            // Default insert.
            // TODO: Default case
            if (!defaultAdded)
            {
                skipCounts.Insert(0, Skipper.GetSkipCount(switchEnd));
            }

            // Skip to the case.
            Skipper.SetSkipCount(
                // Create an array of all skip counts.
                Element.CreateArray(skipCounts.ToArray())[
                    // Get the case with the value that matches.
                    // IndexOfArrayValue will return -1 if the case is not found,
                    // Add 1 and skip to the default case.
                    Element.IndexOfArrayValue(
                        Element.CreateArray(skipValues.ToArray()),
                        switchValue
                        ) + 1
                ]
                );
        }
 public RecursiveMethodStack(DefinedMethod method, ReturnHandler returnHandler, IndexReference continueSkipArray, SkipEndMarker methodStart) : base(method)
 {
     ReturnHandler     = returnHandler;
     ContinueSkipArray = continueSkipArray;
     MethodStart       = methodStart;
 }
        private IWorkshopTree ParseRecursive(ActionSet actionSet, IWorkshopTree[] parameterValues)
        {
            // Check the method stack to see if this method was already called.
            RecursiveMethodStack lastCall = actionSet.Translate.MethodStack.FirstOrDefault(ms => ms.Function == this) as RecursiveMethodStack;

            // If not, set up the stack and call the method.
            if (lastCall == null)
            {
                // Assign the parameters.
                AssignParameters(actionSet, ParameterVars, parameterValues, true);

                // Get the return handler if a value is returned.
                ReturnHandler returnHandler = new ReturnHandler(actionSet, Name, true);

                // Set up the condinue skip array.
                IndexReference continueSkipArray = actionSet.VarCollection.Assign("recursiveContinueArray", actionSet.IsGlobal, false);

                SkipEndMarker methodStart = new SkipEndMarker();
                actionSet.AddAction(methodStart);

                // Add the method to the stack.
                var stack = new RecursiveMethodStack(this, returnHandler, continueSkipArray, methodStart);
                actionSet.Translate.MethodStack.Add(stack);

                // Parse the method block.
                block.Translate(actionSet.New(returnHandler));

                // Apply the returns.
                if (returnHandler != null)
                {
                    returnHandler.ApplyReturnSkips();
                }

                // Pop the recursive parameters
                // TODO: Make this work with all sub scoped variables somehow
                for (int i = 0; i < ParameterVars.Length; i++)
                {
                    var pop = (actionSet.IndexAssigner[ParameterVars[i]] as RecursiveIndexReference)?.Pop();
                    if (pop != null)
                    {
                        actionSet.AddAction(pop);
                    }
                }

                // Setup the continue skip
                actionSet.ContinueSkip.Setup(actionSet);
                actionSet.ContinueSkip.SetSkipCount(actionSet, Element.Part <V_LastOf>(continueSkipArray.GetVariable()));

                // Remove the last recursive continue skip.
                actionSet.AddAction(continueSkipArray.SetVariable(
                                        // Pop
                                        Element.Part <V_ArraySlice>(
                                            continueSkipArray.GetVariable(),
                                            new V_Number(0),
                                            Element.Part <V_CountOf>(continueSkipArray.GetVariable()) - 1
                                            )
                                        ));

                // Loop if there are any values in the continue skip array.
                actionSet.AddAction(Element.Part <A_LoopIf>(
                                        Element.Part <V_CountOf>(continueSkipArray.GetVariable()) > 0
                                        ));

                // Reset the continue skip.
                actionSet.ContinueSkip.ResetSkipCount(actionSet);
                actionSet.AddAction(continueSkipArray.SetVariable(0));

                // Remove the method from the stack.
                actionSet.Translate.MethodStack.Remove(stack);

                return(returnHandler.GetReturnedValue());
            }
            // If it is, push the parameters to the stack.
            else
            {
                for (int i = 0; i < ParameterVars.Length; i++)
                {
                    var varReference = actionSet.IndexAssigner[ParameterVars[i]];
                    if (varReference is RecursiveIndexReference)
                    {
                        actionSet.AddAction(((RecursiveIndexReference)varReference).Push(
                                                (Element)parameterValues[i]
                                                ));
                    }
                }

                // Add to the continue skip array.
                V_Number skipLength = new V_Number();
                actionSet.AddAction(lastCall.ContinueSkipArray.SetVariable(
                                        Element.Part <V_Append>(lastCall.ContinueSkipArray.GetVariable(), skipLength)
                                        ));

                actionSet.ContinueSkip.Setup(actionSet);
                actionSet.ContinueSkip.SetSkipCount(actionSet, lastCall.MethodStart);
                actionSet.AddAction(new A_Loop());

                SkipEndMarker continueAt = new SkipEndMarker();
                actionSet.AddAction(continueAt);
                skipLength.Value = actionSet.ContinueSkip.GetSkipCount(continueAt).Value;

                return(lastCall.ReturnHandler.GetReturnedValue());
            }
        }
Пример #17
0
 public DynamicSkip(SkipStartMarker startMarker, SkipEndMarker endMarker)
 {
     StartMarker = startMarker;
     EndMarker   = endMarker;
 }
Пример #18
0
 public V_Number GetSkipCount(SkipEndMarker endMarker)
 {
     CheckSetup();
     return(Skipper.GetSkipCount(endMarker));
 }
Пример #19
0
        public void TranslateSkip(ActionSet actionSet)
        {
            // Create the skip for the start of the if statement.
            SkipStartMarker ifStart = new SkipStartMarker(actionSet, Expression.Parse(actionSet));

            actionSet.AddAction(ifStart);

            // Translate the if block.
            Block.Translate(actionSet);

            // 'block caps' are skips that are added to the end of the if block and each else-if block.
            // The skips skip to the end of the entire if/else-if/else.
            List <SkipStartMarker> blockCaps = new List <SkipStartMarker>();

            // Add the if cap if there is an else block or there is an else-if block.
            if (ElseBlock != null || ElseIfs.Length > 0)
            {
                SkipStartMarker ifCap = new SkipStartMarker(actionSet);
                actionSet.AddAction(ifCap);
                blockCaps.Add(ifCap);
            }

            // Marks the end of the if statement. If the if-condition is false, `ifStart` will skip to here.
            SkipEndMarker ifEnd = new SkipEndMarker();

            actionSet.AddAction(ifEnd);

            // Set the if-skip's count.
            ifStart.SetEndMarker(ifEnd);

            // Get the else-ifs.
            for (int i = 0; i < ElseIfs.Length; i++)
            {
                // This will equal true if this is at the last else-if and there is no else.
                bool isLast = i == ElseIfs.Length - 1 && ElseBlock == null;

                // Create the skip for the start of the else-if.
                SkipStartMarker elseIfStart = new SkipStartMarker(actionSet, ElseIfs[i].Expression.Parse(actionSet));
                actionSet.AddAction(elseIfStart);

                // Translate the else-if block.
                ElseIfs[i].Block.Translate(actionSet);

                // If this is not the last block in the entire if/else-if/else list, add the 'block cap'.
                if (!isLast)
                {
                    SkipStartMarker elseIfCap = new SkipStartMarker(actionSet);
                    actionSet.AddAction(elseIfCap);
                    blockCaps.Add(elseIfCap);
                }

                // Marks the end of the else-if statement. If the condition is false, `elseIfStart` will skip to here.
                SkipEndMarker elseIfEnd = new SkipEndMarker();
                actionSet.AddAction(elseIfEnd);
                elseIfStart.SetEndMarker(elseIfEnd);
            }

            // If there is an else block, translate it.
            if (ElseBlock != null)
            {
                ElseBlock.Translate(actionSet);
            }

            // contextCap marks the end of the entire if/else-if/list.
            SkipEndMarker contextCap = new SkipEndMarker();

            actionSet.AddAction(contextCap);

            // Set all the block caps so they skip to the end of the list.
            foreach (var blockCap in blockCaps)
            {
                blockCap.SetEndMarker(contextCap);
            }
        }
Пример #20
0
 public DynamicSkip GetSkipCount(SkipEndMarker marker) => new DynamicSkip(this, marker);
Пример #21
0
 public void SetSkipCount(ActionSet actionSet, SkipEndMarker endMarker)
 {
     SetSkipCount(actionSet, GetSkipCount(endMarker));
 }