/// <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());
        }
Beispiel #2
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);
            }
        }
Beispiel #3
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);
            }
        }