public override AstNode Visit(StructDefinition node) { // Use the generic scope. PseudoScope genScope = node.GetGenericScope(); if (genScope != null) { PushScope(genScope); } // Process the base structures. node.GetStructure().SetBase(currentModule.GetValueTypeClass()); // Process the base interfaces. ProcessBases(node); // Update the scope. PushScope(node.GetScope()); // Visit his children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); // Pop the generic scope. if (genScope != null) { PopScope(); } return(node); }
public override AstNode Visit(StructDefinition node) { // Fix the vtable. try { node.GetStructure().FixInheritance(); } catch (ModuleException error) { Error(node, error.Message); } // Create default constructor. CreateDefaultConstructor(node); // Update the scope. PushScope(node.GetScope()); // Visit his children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); return(node); }
private void CreateDefaultConstructor(StructDefinition node) { // Get the structure. Structure building = node.GetStructure(); // Check for an user defined constructor. if (building.GetConstructor() != null) { return; } // Instance the building. GenericPrototype contGenProto = building.GetGenericPrototype(); int templateArgs = contGenProto.GetPlaceHolderCount(); Structure buildingInstance = building; if (templateArgs != 0) { IChelaType[] thisArgs = new IChelaType[templateArgs]; for (int i = 0; i < templateArgs; ++i) { thisArgs[i] = contGenProto.GetPlaceHolder(i); } buildingInstance = (Structure)building.InstanceGeneric( new GenericInstance(contGenProto, thisArgs), currentModule); } // Create the default constructor function type. List <IChelaType> arguments = new List <IChelaType> (); arguments.Add(ReferenceType.Create(buildingInstance)); FunctionType ctorType = FunctionType.Create(ChelaType.GetVoidType(), arguments); // Create the constructor method. MemberFlags flags = MemberFlags.Public | MemberFlags.Constructor; Method constructor = new Method(building.GetName(), flags, building); constructor.SetFunctionType(ctorType); // Store it. building.AddFunction("<ctor>", constructor); node.SetDefaultConstructor(constructor); }
private void ProcessBases(StructDefinition node) { // Process the bases. int numbases = 0; AstNode baseNode = node.GetBases(); Structure building = node.GetStructure(); for (; baseNode != null; baseNode = baseNode.GetNext()) { // Visit the base. baseNode.Accept(this); // Get the node type. IChelaType baseType = baseNode.GetNodeType(); baseType = ExtractActualType(node, baseType); // Check base security. if (baseType.IsUnsafe()) { UnsafeError(node, "safe class/struct/interface with unsafe base/interface."); } // Check the class/struct/iface matches. if (!baseType.IsInterface() && baseType.IsClass() != building.IsClass()) { Error(baseNode, "incompatible base type."); } // Check for interface inheritance. if (building.IsInterface() && !baseType.IsInterface()) { Error(baseNode, "interfaces only can have interfaces as bases."); } // Only single inheritance, multiple interfaces. if (numbases >= 1 && !baseType.IsInterface()) { Error(baseNode, "only single inheritance and multiples interfaces is supported."); } // Set the base building. if (baseType.IsInterface()) { building.AddInterface((Structure)baseType); } else { Structure oldBase = building.GetBase(); Structure baseBuilding = (Structure)baseType; if (oldBase != null && oldBase != baseBuilding) { Error(node, "incompatible partial class bases."); } building.SetBase(baseBuilding); numbases++; } } // Notify the building. building.CompletedBases(); }