Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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;
        }
Ejemplo n.º 3
0
        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();
        }
Ejemplo n.º 4
0
        private void CreateDefaultStaticConstructor(StructDefinition node)
        {
            // Get the structure.
            Structure building = node.GetStructure();

            // Check for an user defined constructor.
            if(building.GetStaticConstructor() != null)
                return;

            // Get the static initialization fields.
            List<FieldDeclaration> staticInitedField = new List<FieldDeclaration> ();
            bool isUnsafe = false;
            foreach(FieldDeclaration decl in building.GetFieldInitializations())
            {
                Variable variable = decl.GetVariable();
                if(variable.IsStatic())
                {
                    staticInitedField.Add(decl);
                    if(variable.IsUnsafe())
                        isUnsafe = true;
                }
            }

            // If there aren't field to initialize, don't create the static constructor.
            if(staticInitedField.Count == 0)
                return;

            // Begin the node.
            builder.BeginNode(node);

            // Create the static constructor function type.
            FunctionType ctorType = FunctionType.Create(ChelaType.GetVoidType());

            // Create the constructor method.
            MemberFlags flags = MemberFlags.StaticConstructor;
            if(isUnsafe)
                flags |= MemberFlags.Unsafe;
            Method constructor = new Method("<sctor>", flags, building);
            constructor.SetFunctionType(ctorType);

            // Store it.
            building.AddFunction("<sctor>", constructor);

            // Create the constructor scope.
            LexicalScope ctorScope = CreateLexicalScope(node, constructor);
            PushScope(ctorScope);

            // Create the top basic block.
            BasicBlock topBlock = new BasicBlock(constructor);
            builder.SetBlock(topBlock);

            // Initialize the static fields.
            GenerateStaticFieldInitializations(node, staticInitedField);

            // Restore the scope.
            PopScope();

            // Return void.
            builder.CreateRetVoid();

            // End the node.
            builder.EndNode();
        }
Ejemplo n.º 5
0
        private void CreateDefaultConstructor(StructDefinition node)
        {
            // Get the structure, and the default constructor.
            Structure building = node.GetStructure();
            Method constructor = node.GetDefaultConstructor();

            // Ignore structures without a default constructor.
            if(constructor == null)
                return;

            // Crete the self scope.
            LexicalScope selfScope = CreateLexicalScope(node, constructor);
            new ArgumentVariable(0, "this", selfScope, ReferenceType.Create(building));
            PushScope(selfScope);

            // Create the top basic block.
            BasicBlock topBlock = new BasicBlock(constructor);
            builder.SetBlock(topBlock);

            // Add implicit construction expressions.
            CreateImplicitBaseConstructor(node, constructor);

            // Initialize some field.
            GenerateFieldInitializations(node, building);

            // Restore the scope.
            PopScope();

            // Return void.
            builder.CreateRetVoid();
        }
Ejemplo n.º 6
0
        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);
        }