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); } }
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()); }