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); }
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()); }
public void Finish() { SkipEndMarker endMarker = new SkipEndMarker(); ActionSet.AddAction(endMarker); SkipMarker.SkipCount = SkipMarker.GetSkipCount(endMarker); }
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); } }
public virtual void ApplyReturnSkips() { SkipEndMarker methodEndMarker = new SkipEndMarker(); _actionSet.AddAction(methodEndMarker); foreach (var returnSkip in _skips) { returnSkip.SetEndMarker(methodEndMarker); } }
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 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)); }
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); } }
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); } }
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); }
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()); } }
public DynamicSkip(SkipStartMarker startMarker, SkipEndMarker endMarker) { StartMarker = startMarker; EndMarker = endMarker; }
public V_Number GetSkipCount(SkipEndMarker endMarker) { CheckSetup(); return(Skipper.GetSkipCount(endMarker)); }
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); } }
public DynamicSkip GetSkipCount(SkipEndMarker marker) => new DynamicSkip(this, marker);
public void SetSkipCount(ActionSet actionSet, SkipEndMarker endMarker) { SetSkipCount(actionSet, GetSkipCount(endMarker)); }