示例#1
0
        public ForeachBuilder(ActionSet actionSet, IWorkshopTree array, bool recursive = false)
        {
            ActionSet  = actionSet;
            IndexStore = actionSet.VarCollection.Assign("foreachIndex,", actionSet.IsGlobal, !recursive);
            Recursive  = recursive;

            if (recursive)
            {
                RecursiveIndexReference recursiveStore = new RecursiveIndexReference(IndexStore);
                IndexStore = recursiveStore;

                actionSet.InitialSet().AddAction(recursiveStore.Reset());
                actionSet.AddAction(recursiveStore.Push(0));
                actionSet.ReturnHandler.AdditionalPopOnReturn.Add(recursiveStore);
            }
            else
            {
                actionSet.AddAction(IndexStore.SetVariable(0));
            }

            Array      = array;
            Condition  = Element.Compare(IndexStore.GetVariable(), Operator.LessThan, Element.CountOf(Array));
            Index      = (Element)IndexStore.GetVariable();
            IndexValue = Element.ValueInArray(Array, IndexStore.GetVariable());

            actionSet.AddAction(Element.While(Condition));
        }
        public static void Assign(ActionSet actionSet, Var var)
        {
            // Get the initial value.
            IWorkshopTree initialValue = new V_Number(0);

            if (var.InitialValue != null)
            {
                initialValue = var.InitialValue.Parse(actionSet);
            }

            // Add the variable to the assigner.
            actionSet.IndexAssigner.Add(actionSet.VarCollection, var, actionSet.IsGlobal, initialValue);

            // Set the initial value.
            if (var.Settable())
            {
                IndexReference reference = (IndexReference)actionSet.IndexAssigner[var];

                if (reference is RecursiveIndexReference recursive)
                {
                    actionSet.InitialSet().AddAction(recursive.Reset());
                    actionSet.AddAction(recursive.Push((Element)initialValue));
                }
                else
                {
                    actionSet.AddAction(reference.SetVariable((Element)initialValue));
                }
            }
        }
        /// <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());
        }
示例#4
0
        // 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);
        }