public SubroutineCatalogItem Initiate() { // Setup the subroutine element. Subroutine subroutine = _deltinScript.SubroutineCollection.NewSubroutine(_context.ElementName); // Create the rule. _subroutineRule = new TranslateRule(_deltinScript, subroutine, _context.RuleName, _context.VariableGlobalDefault); // Setup the return handler. _actionSet = _subroutineRule.ActionSet .ContainVariableAssigner() .SetThisTypeLinker(_context.TypeLinker) .New(_context.Controller.Attributes.IsRecursive); // Create the function builder. var controller = _context.Controller; // Create the parameter handlers. _parameterHandler = controller.CreateParameterHandler(_actionSet, null); // If the subroutine is an object function inside a class, create a variable to store the class object. if (controller.Attributes.IsInstance) { _objectStore = _actionSet.VarCollection.Assign(_context.ObjectStackName, true, !controller.Attributes.IsRecursive); // Set the objectStore as an empty array if the subroutine is recursive. if (controller.Attributes.IsRecursive) { // Initialize as empty array. _actionSet.InitialSet().AddAction(_objectStore.SetVariable(Element.EmptyArray())); // Add to assigner with the last of the objectStore stack being the object instance. _context.ContainingType?.AddObjectVariablesToAssigner(_actionSet.ToWorkshop, Element.LastOf(_objectStore.GetVariable()), _actionSet.IndexAssigner); // Set the actionSet. _actionSet = _actionSet.New(Element.LastOf(_objectStore.Get())).PackThis().New(_objectStore.CreateChild(Element.CountOf(_objectStore.Get()) - 1)); } else { // Add to assigner with the objectStore being the object instance. _context.ContainingType?.AddObjectVariablesToAssigner(_actionSet.ToWorkshop, _objectStore.GetVariable(), _actionSet.IndexAssigner); // Set the actionSet. _actionSet = _actionSet.New(_objectStore.Get()).PackThis().New(_objectStore); } } _functionBuilder = new WorkshopFunctionBuilder(_actionSet, controller); _functionBuilder.ModifySet(a => a.PackThis()); // TODO: is this required? _functionBuilder.SetupReturnHandler(); _parameterHandler.AddParametersToAssigner(_actionSet.IndexAssigner); // Done. return(Result = new SubroutineCatalogItem( subroutine: subroutine, parameterHandler: _parameterHandler, objectStack: _objectStore, returnHandler: _functionBuilder.ReturnHandler)); }
public IWorkshopTree Call(ICallInfo call) { // Get the subroutine. _subroutine = Controller.GetSubroutine(); if (_subroutine) { ParameterHandler = _subroutine.ParameterHandler; SetParameters(call); // Store the object the subroutine is executing with. if (Controller.Attributes.IsInstance) { // Normal if (!Controller.Attributes.IsRecursive) { ActionSet.AddAction(_subroutine.ObjectStack.SetVariable((Element)ActionSet.CurrentObject)); } // Recursive: Stack else { ActionSet.AddAction(_subroutine.ObjectStack.ModifyVariable(Operation.AppendToArray, Element.CreateArray(ActionSet.CurrentObject))); } } call.ExecuteSubroutine(ActionSet, _subroutine.Subroutine); // If a return handler was provided, bridge the return value. if (call.ProvidedReturnHandler != null && _subroutine.ReturnHandler != null) { call.ProvidedReturnHandler.ReturnValue(_subroutine.ReturnHandler.GetReturnedValue()); } return(_subroutine.ReturnHandler?.GetReturnedValue()); } else { // Inline // Recursive stack. if (Controller.Attributes.IsRecursive) { var lastCall = GetExistingStack(); // Function is not yet on the stack. if (lastCall == null) { return(BuildInline(call)); } else // Recursive call. { lastCall.RecursiveCall(call, ActionSet); return(ActionSet.ReturnHandler.GetReturnedValue()); } } else { return(BuildInline(call)); } } }
public SetupSubroutine(SubroutineCatalogItem item, Action completeSetup) { Item = item; CompleteSetup = completeSetup; }
public SetupSubroutine(SubroutineBuilder builder) { Item = builder.Initiate(); CompleteSetup = builder.Complete; }