/// <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()); }
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); } }
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); } }