public ActionSet New(ReturnHandler returnHandler) { var newActionSet = Clone(); newActionSet.ReturnHandler = returnHandler ?? throw new ArgumentNullException(nameof(returnHandler)); return(newActionSet); }
public SubroutineInfo(Subroutine routine, ReturnHandler returnHandler, IndexReference[] parameterStores, IndexReference objectStore) { Subroutine = routine; ReturnHandler = returnHandler; ParameterStores = parameterStores; ObjectStore = objectStore; }
public void SetupReturnHandler() { if (ReturnHandler == null) { ReturnHandler = new ReturnHandler(BuilderSet, Method.Name, (Method.Attributes.Virtual && Method.DoesReturnValue) || Method.MultiplePaths); BuilderSet = BuilderSet.New(ReturnHandler); } }
public void Apply() { // Apply returns. ReturnHandler.ApplyReturnSkips(); // Add the subroutine. _deltinScript.WorkshopRules.Add(Rule.GetRule()); }
public SubroutineStack(DeltinScript deltinScript, string subroutineName, string ruleName) { _deltinScript = deltinScript; // Setup the subroutine element. Subroutine = deltinScript.SubroutineCollection.NewSubroutine(subroutineName); // Create the rule. Rule = new TranslateRule(deltinScript, subroutineName, Subroutine); // Setup the return handler. ReturnHandler = new ReturnHandler(Rule.ActionSet, subroutineName, true); ActionSet = Rule.ActionSet.New(ReturnHandler); AsyncLock(); }
private IWorkshopTree ParseNormal(ActionSet actionSet, MethodCall methodCall) { // Create the return handler. ReturnHandler returnHandler = methodCall.ReturnHandler ?? new ReturnHandler(actionSet, Name, multiplePaths); actionSet = actionSet.New(returnHandler); // Assign the parameters and translate the block. AssignParameters(actionSet, ParameterVars, methodCall.ParameterValues); block.Translate(actionSet); if (methodCall.ResolveReturnHandler) { returnHandler.ApplyReturnSkips(); } return(returnHandler.GetReturnedValue()); }
// Sets up single-instance methods for methods with the 'rule' attribute. public void SetupSubroutine() { if (!IsSubroutine) { throw new Exception(Name + " does not have the subroutine attribute."); } // Setup the subroutine element. Subroutine subroutine = parseInfo.TranslateInfo.SubroutineCollection.NewSubroutine(Name); // Create the rule. TranslateRule subroutineRule = new TranslateRule(parseInfo.TranslateInfo, SubroutineName, subroutine); // Setup the return handler. ReturnHandler returnHandler = new ReturnHandler(subroutineRule.ActionSet, Name, multiplePaths); ActionSet actionSet = subroutineRule.ActionSet.New(returnHandler).New(subroutineRule.ActionSet.IndexAssigner.CreateContained()); // Get the variables that will be used to store the parameters. IndexReference[] parameterStores = new IndexReference[ParameterVars.Length]; for (int i = 0; i < ParameterVars.Length; i++) { parameterStores[i] = actionSet.IndexAssigner.Add(actionSet.VarCollection, ParameterVars[i], true, null, Attributes.Recursive) as IndexReference; } // If the subroutine is an object function inside a class, create a variable to store the class object. IndexReference objectStore = null; if (Attributes.ContainingType != null && !Static) { objectStore = actionSet.VarCollection.Assign("_" + Name + "_subroutineStore", true, true); Attributes.ContainingType.AddObjectVariablesToAssigner(objectStore.GetVariable(), actionSet.IndexAssigner); } // Set the subroutine info. subroutineInfo = new SubroutineInfo(subroutine, returnHandler, subroutineRule, parameterStores, objectStore); // Parse the block. block.Translate(actionSet); // Apply returns. returnHandler.ApplyReturnSkips(); // Add the subroutine. parseInfo.TranslateInfo.WorkshopRules.Add(subroutineRule.GetRule()); }
override public IWorkshopTree Parse(ActionSet actionSet, IWorkshopTree[] parameterValues, object[] additionalParameterData) { actionSet = actionSet .New(actionSet.IndexAssigner.CreateContained()); if (IsRecursive) { return(ParseRecursive(actionSet, parameterValues)); } ReturnHandler returnHandler = new ReturnHandler(actionSet, Name, multiplePaths); actionSet = actionSet.New(returnHandler); AssignParameters(actionSet, ParameterVars, parameterValues); block.Translate(actionSet); returnHandler.ApplyReturnSkips(); return(returnHandler.GetReturnedValue()); }
public TranslateRule(DeltinScript deltinScript, RuleAction ruleAction) { DeltinScript = deltinScript; IsGlobal = ruleAction.EventType == RuleEvent.OngoingGlobal; Name = ruleAction.Name; EventType = ruleAction.EventType; Team = ruleAction.Team; Player = ruleAction.Player; Disabled = ruleAction.Disabled; ContinueSkip = new ContinueSkip(this); ActionSet = new ActionSet(this, null, Actions); GetConditions(ruleAction); ReturnHandler returnHandler = new ReturnHandler(ActionSet, Name, false); ruleAction.Block.Translate(ActionSet.New(returnHandler)); returnHandler.ApplyReturnSkips(); }
/// <summary>Calls the method.</summary> private IWorkshopTree ParseCall(ActionSet actionSet, MethodCall methodCall) { // Create the array used for continuing after a recursive call. continueArray = actionSet.VarCollection.Assign("_" + method.Name + "_recursiveContinue", actionSet.IsGlobal, false); nextContinue = actionSet.VarCollection.Assign("_" + method.Name + "_nextContinue", actionSet.IsGlobal, true); actionSet.InitialSet().AddAction(continueArray.SetVariable(new V_EmptyArray())); ReturnHandler returnHandler = methodCall.ReturnHandler ?? new ReturnHandler(actionSet, method.Name, method.multiplePaths); this.returnHandler = returnHandler; DefinedMethod.AssignParameters(actionSet, method.ParameterVars, methodCall.ParameterValues, true); actionSet.AddAction(Element.Part <A_While>(new V_True())); continueAt = new SkipStartMarker(actionSet); continueAt.SetSkipCount((Element)nextContinue.GetVariable()); actionSet.AddAction(continueAt); method.block.Translate(actionSet); PopParameterStacks(actionSet); // Pop the continueArray. actionSet.AddAction(Element.Part <A_SkipIf>(new V_Compare( Element.Part <V_CountOf>(continueArray.GetVariable()), Operators.Equal, new V_Number(0) ), new V_Number(3))); actionSet.AddAction(nextContinue.SetVariable(Element.Part <V_LastOf>(continueArray.GetVariable()))); actionSet.AddAction(continueArray.ModifyVariable(Operation.RemoveFromArrayByIndex, Element.Part <V_CountOf>(continueArray.GetVariable()) - 1)); actionSet.AddAction(endOfMethod); actionSet.AddAction(new A_End()); actionSet.AddAction(nextContinue.SetVariable(0)); return(returnHandler.GetReturnedValue()); }
public MethodBuilder(DefinedMethod method, ActionSet builderSet, ReturnHandler returnHandler = null) { Method = method; this.BuilderSet = builderSet; ReturnHandler = returnHandler; }
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()); } }
// Sets up single-instance methods for methods with the 'rule' attribute. public void SetupSubroutine() { if (subroutineInfo != null || !IsSubroutine) { return; } // Setup the subroutine element. Subroutine subroutine = parseInfo.TranslateInfo.SubroutineCollection.NewSubroutine(Name); // Create the rule. TranslateRule subroutineRule = new TranslateRule(parseInfo.TranslateInfo, subroutine, SubroutineName, subroutineDefaultGlobal); // Setup the return handler. ReturnHandler returnHandler = new ReturnHandler(subroutineRule.ActionSet, Name, multiplePaths || Attributes.Virtual); ActionSet actionSet = subroutineRule.ActionSet.New(returnHandler).New(subroutineRule.ActionSet.IndexAssigner.CreateContained()); // Get the variables that will be used to store the parameters. IndexReference[] parameterStores = new IndexReference[ParameterVars.Length]; for (int i = 0; i < ParameterVars.Length; i++) { // Create the workshop variable the parameter will be stored as. IndexReference indexResult = actionSet.IndexAssigner.AddIndexReference(actionSet.VarCollection, ParameterVars[i], subroutineDefaultGlobal, Attributes.Recursive); parameterStores[i] = indexResult; // Assign virtual variables to the index reference. foreach (Var virtualParameterOption in VirtualVarGroup(i)) { actionSet.IndexAssigner.Add(virtualParameterOption, indexResult); } } // If the subroutine is an object function inside a class, create a variable to store the class object. IndexReference objectStore = null; if (Attributes.ContainingType != null && !Static) { objectStore = actionSet.VarCollection.Assign("_" + Name + "_subroutineStore", true, !Attributes.Recursive); // Set the objectStore as an empty array if the subroutine is recursive. if (Attributes.Recursive) { actionSet.InitialSet().AddAction(objectStore.SetVariable(new V_EmptyArray())); Attributes.ContainingType.AddObjectVariablesToAssigner(Element.Part <V_LastOf>(objectStore.GetVariable()), actionSet.IndexAssigner); actionSet = actionSet.New(Element.Part <V_LastOf>(objectStore.GetVariable())).PackThis(); } else { Attributes.ContainingType.AddObjectVariablesToAssigner(objectStore.GetVariable(), actionSet.IndexAssigner); actionSet = actionSet.New(objectStore.GetVariable()).PackThis(); } } // Set the subroutine info. subroutineInfo = new SubroutineInfo(subroutine, returnHandler, subroutineRule, parameterStores, objectStore); MethodBuilder builder = new MethodBuilder(this, actionSet, returnHandler); builder.BuilderSet = builder.BuilderSet.New(Attributes.Recursive); builder.ParseInner(); // Apply returns. returnHandler.ApplyReturnSkips(); // Pop object array and parameters if recursive. if (Attributes.Recursive) { if (objectStore != null) { actionSet.AddAction(objectStore.ModifyVariable(Operation.RemoveFromArrayByIndex, Element.Part <V_CountOf>(objectStore.GetVariable()) - 1)); } RecursiveStack.PopParameterStacks(actionSet, ParameterVars); } // Add the subroutine. Rule translatedRule = subroutineRule.GetRule(); parseInfo.TranslateInfo.WorkshopRules.Add(translatedRule); var codeLens = new ElementCountCodeLens(DefinedAt.range, parseInfo.TranslateInfo.OptimizeOutput); parseInfo.Script.AddCodeLensRange(codeLens); codeLens.RuleParsed(translatedRule); }
public ActionSet New(ReturnHandler returnHandler) => new ActionSet(this)