override public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context)
        {
            IndexedVar store = context.VarCollection.AssignVar(scope, Name + " store", context.IsGlobal, null);

            store.Type = this;
            ScopeGroup typeScope = GetRootScope(store, context.ParserData);

            SetupNew(getter, scope, store, typeScope, context, node);

            return(store.GetVariable());
        }
        override public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context)
        {
            // Get the index to store the class.
            IndexedVar index = context.VarCollection.AssignVar(scope, "New " + Name + " class index", context.IsGlobal, null); // Assigns the index variable.

            // Get the index of the next free spot in the class array.
            context.Actions.AddRange(
                index.SetVariable(
                    Element.Part <V_IndexOfArrayValue>(
                        WorkshopArrayBuilder.GetVariable(true, null, Variable.C),
                        new V_Null()
                        )
                    )
                );
            // Set the index to the count of the class array if the index equals -1.
            context.Actions.AddRange(
                index.SetVariable(
                    Element.TernaryConditional(
                        new V_Compare(index.GetVariable(), Operators.Equal, new V_Number(-1)),
                        Element.Part <V_CountOf>(
                            WorkshopArrayBuilder.GetVariable(true, null, Variable.C)
                            ),
                        index.GetVariable()
                        )
                    )
                );
            // The direct reference to the class variable.
            IndexedVar store = new IndexedVar(
                scope,
                Name + " root",
                true,
                Variable.C,
                new Element[] { index.GetVariable() },
                context.VarCollection.WorkshopArrayBuilder,
                null
                );

            store.Index[0].SupportedType = store;
            store.Type = this;

            ScopeGroup typeScope = GetRootScope(store, context.ParserData);

            SetupNew(getter, scope, store, typeScope, context, node);

            return(index.GetVariable());
        }
 abstract public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context);
        protected void SetupNew(ScopeGroup getter, ScopeGroup scope, IndexedVar store, ScopeGroup typeScope, TranslateRule context, CreateObjectNode node)
        {
            // Set the default variables in the struct
            for (int i = 0; i < DefinedVars.Length; i++)
            {
                if (DefinedVars[i].Value != null)
                {
                    context.Actions.AddRange(
                        store.SetVariable(context.ParseExpression(typeScope, typeScope, DefinedVars[i].Value), null, new V_Number(i))
                        );
                }
            }

            Constructor constructor = Constructors.FirstOrDefault(c => c.Parameters.Length == node.Parameters.Length);

            if (constructor == null && !(node.Parameters.Length == 0 && Constructors.Length == 0))
            {
                throw SyntaxErrorException.NotAConstructor(TypeKind, Name, node.Parameters.Length, node.Location);
            }

            if (constructor != null)
            {
                ScopeGroup constructorScope = typeScope.Child();

                IWorkshopTree[] parameters = context.ParseParameters(
                    getter,
                    scope,
                    constructor.Parameters,
                    node.Parameters,
                    node.TypeName,
                    node.Location
                    );

                context.AssignParameterVariables(constructorScope, constructor.Parameters, parameters, node);
                context.ParseBlock(typeScope, constructorScope, constructor.BlockNode, true, null);
                constructorScope.Out(context);
            }
        }
Exemple #5
0
        override public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context)
        {
            context.ParserData.SetupClasses();

            // Get the index to store the class.
            IndexedVar index        = IndexedVar.AssignInternalVarExt(context.VarCollection, scope, "New " + Name + " class index", context.IsGlobal); // Assigns the index variable.
            Element    takenIndexes = context.ParserData.ClassIndexes.GetVariable();

            // Get an empty index in the class array to store the new class.
            Element firstFree = (
                Element.Part <V_FirstOf>(
                    Element.Part <V_FilteredArray>(
                        // Sort the taken index array.
                        Element.Part <V_SortedArray>(takenIndexes, new V_ArrayElement()),
                        // Filter
                        Element.Part <V_And>(
                            // If the previous index was not taken, use that index.
                            !(Element.Part <V_ArrayContains>(
                                  takenIndexes,
                                  new V_ArrayElement() - 1
                                  )),
                            // Make sure the index does not equal 0 so the resulting index is not -1.
                            new V_Compare(new V_ArrayElement(), Operators.NotEqual, new V_Number(0))
                            )
                        )
                    ) -
                1 // Subtract 1 to get the previous index
                );

            // If the taken index array has 0 elements, just use the length of the class array subtracted by 1.
            firstFree = Element.TernaryConditional(
                new V_Compare(Element.Part <V_CountOf>(takenIndexes), Operators.NotEqual, new V_Number(0)),
                firstFree,
                Element.Part <V_CountOf>(context.ParserData.ClassArray.GetVariable()) - 1
                );

            context.Actions.AddRange(index.SetVariable(firstFree));

            context.Actions.AddRange(
                index.SetVariable(
                    Element.TernaryConditional(
                        // If the index equals -1, use the length of the class array instead.
                        new V_Compare(index.GetVariable(), Operators.Equal, new V_Number(-1)),
                        Element.Part <V_CountOf>(context.ParserData.ClassArray.GetVariable()),
                        index.GetVariable()
                        )
                    )
                );

            // Add the selected index to the taken indexes array.
            context.Actions.AddRange(
                context.ParserData.ClassIndexes.SetVariable(
                    Element.Part <V_Append>(
                        context.ParserData.ClassIndexes.GetVariable(),
                        index.GetVariable()
                        )
                    )
                );

            // The direct reference to the class variable.
            IndexedVar store = context.ParserData.ClassArray.CreateChild(scope, Name + " root", new Element[] { index.GetVariable() }, null);

            store.Index[0].SupportedType = store;
            store.Type = this;

            ScopeGroup typeScope = GetRootScope(index.GetVariable(), store, context.ParserData);

            SetupNew(getter, scope, store, typeScope, context, node);

            return(index.GetVariable());
        }