Beispiel #1
0
 public PseudoScope(Scope parent, GenericPrototype genProto)
     : this(parent)
 {
     for(int i = 0; i < genProto.GetPlaceHolderCount(); ++i)
     {
         PlaceHolderType placeHolder = genProto.GetPlaceHolder(i);
         AddAlias(placeHolder.GetName(), placeHolder);
     }
 }
Beispiel #2
0
 protected Function(ChelaModule module)
     : base(module)
 {
     this.name = string.Empty;
     this.flags = MemberFlags.Default;
     this.parentScope = null;
     this.basicBlocks = new List<BasicBlock> ();
     this.lexicalScopes = new List<LexicalScope>();
     this.locals = new List<LocalVariable> ();
     this.position = null;
     this.exceptionContext = null;
     this.returnBlock = null;
     this.returningVar = null;
     this.returnValueVar = null;
     this.genericPrototype = GenericPrototype.Empty;
     this.arguments  = null;
 }
Beispiel #3
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);
        }
Beispiel #4
0
        public virtual Structure FindType(string name, GenericPrototype prototype)
        {
            // Find the member.
            ScopeMember member = FindMember(name);
            if(member == null)
                return null;

            // Use the matching type in the type group.
            if(member.IsTypeGroup())
            {
                TypeGroup group = (TypeGroup)member;
                return group.Find(prototype);
            }
            else if(!member.IsClass() && !member.IsInterface() && !member.IsStructure())
                throw new ModuleException("found no structural type " + member.GetFullName());

            // Cast the member.
            return (Structure) member;
        }
Beispiel #5
0
 private IChelaType GenericCoercion(AstNode where, IChelaType argType, IChelaType argExpType,
                                    GenericPrototype genProto, IChelaType[] genericArgumentsSoFar,
                                    out int argCoercions)
 {
     argCoercions = 0;
     return null;
 }
Beispiel #6
0
 public void SetPrototype(GenericPrototype prototype)
 {
     this.prototype = prototype;
 }
Beispiel #7
0
        protected bool CheckGenericArguments(AstNode where, GenericPrototype prototype, IChelaType[] arguments)
        {
            // The argument count must match.
            if(prototype.GetPlaceHolderCount() != arguments.Length)
                return TryError(where, "not matching generic argument count.");

            // Check each argument.
            for(int i = 0; i < arguments.Length; ++i)
            {
                // Get the placeholder and the type.
                PlaceHolderType placeHolder = prototype.GetPlaceHolder(i);
                IChelaType argument = arguments[i];

                // Check for value types.
                if(placeHolder.IsValueType() && !argument.IsFirstClass() && !argument.IsStructure() && !argument.IsPlaceHolderType())
                    return TryError(where, "the generic argument number {0} must be a value type.", i+1);

                // Get the argument structure.
                Structure argumentBuilding = null;
                if(argument.IsClass() || argument.IsStructure() || argument.IsInterface())
                    argumentBuilding = (Structure)argument;
                else if(argument.IsFirstClass())
                    argumentBuilding = currentModule.GetAssociatedClass(argument);
                else if(argument.IsPointer())
                {
                    // TODO: Support pointers.
                    argumentBuilding = currentModule.GetAssociatedClass(ChelaType.GetSizeType());
                }
                else if(argument.IsPlaceHolderType())
                {
                    // Check the place holder.
                    if(CheckGenericPlaceArgument(where, placeHolder, (PlaceHolderType)argument))
                        continue;
                    else
                        return false;
                }
                else
                    return TryError(where, "cannot get class for type {0}", argument.GetDisplayName());

                // Check for constraints.
                for(int j = 0; j < placeHolder.GetBaseCount(); ++j)
                {
                    // Get the base building.
                    Structure baseBuilding = placeHolder.GetBase(j);

                    // If the argument is the base pass.
                    if(argumentBuilding == baseBuilding)
                        continue;

                    // If the base is a class, check for inheritance.
                    if(baseBuilding.IsClass() && argumentBuilding.IsDerivedFrom(baseBuilding))
                        continue;

                    // If the base is a interface, check for implementation.
                    if(baseBuilding.IsInterface() && argumentBuilding.Implements(baseBuilding))
                        continue;

                    // The constraint couldn't be satisfied.
                    return TryError(where, "generic argument {0} of type {1} doesn't support constraint {2}",
                                    i+1, argumentBuilding.GetDisplayName(), baseBuilding.GetDisplayName());
                }
            }

            return true;
        }
Beispiel #8
0
        public override AstNode Visit(GenericSignature node)
        {
            // Visit the constraints first.
            AstNode child = node.GetConstraints();
            while(child != null)
            {
                GenericConstraint constraint = (GenericConstraint)child;
                constraint.SetSignature(node);
                constraint.Accept(this);

                // Visit the next constraint.
                child = child.GetNext();
            }

            // Visit the generic parameters.
            child = node.GetParameters();
            List<PlaceHolderType> placeholders = new List<PlaceHolderType> ();
            while(child !=  null)
            {
                // Visit the child.
                child.Accept(this);

                // Store the child type.
                placeholders.Add((PlaceHolderType)child.GetNodeType());

                // Visit the next parameter.
                child = child.GetNext();
            }

            // Create the generic prototype.
            GenericPrototype prototype = new GenericPrototype(placeholders);
            node.SetPrototype(prototype);

            return node;
        }
Beispiel #9
0
        internal override void Read(ModuleReader reader, MemberHeader header)
        {
            // Read the function header.
            FunctionHeader fheader = new FunctionHeader();
            fheader.Read(reader);

            // Read the function type.
            type = (FunctionType)GetModule().GetType(fheader.functionType);

            // Read the generic prototype.
            genericPrototype = GenericPrototype.Read(reader, GetModule());

            // Read the vslot.
            if(IsMethod())
            {
                Method method = (Method)this;
                method.vslot = fheader.vslot;
            }

            // Skip the elements.
            reader.Skip(header.memberSize - FunctionHeader.HeaderSize - genericPrototype.GetSize());
        }
Beispiel #10
0
 public void SetPrototype(GenericPrototype prototype)
 {
     this.prototype = prototype;
 }
Beispiel #11
0
 public void SetGenericPrototype(GenericPrototype genericPrototype)
 {
     this.genericPrototype = genericPrototype;
 }
Beispiel #12
0
 public Structure Find(GenericPrototype prototype)
 {
     TypeGroupName gname = new TypeGroupName(null, prototype);
     TypeGroupName res = types.Find(gname);
     if(res != null)
         return res.GetBuilding();
     return null;
 }
Beispiel #13
0
        public GenericPrototype GetFullGenericPrototype()
        {
            // Return the cached generic prototype.
            if(fullGenericPrototype != null)
                return fullGenericPrototype;

            // Get the parent full generic prototype.
            GenericPrototype parentFull = null;
            Scope parent = GetParentScope();
            if(parent != null)
                parentFull = parent.GetFullGenericPrototype();

            // Get my generic prototype.
            GenericPrototype myPrototype = GetGenericPrototype();
            if(myPrototype == null || myPrototype.GetPlaceHolderCount() == 0)
            {
                fullGenericPrototype = parentFull;
            }
            else if(parentFull == null || parentFull.GetPlaceHolderCount() == 0)
            {
                fullGenericPrototype = myPrototype;
            }
            else
            {
                // Merge both prototypes
                int parentSize = parentFull.GetPlaceHolderCount();
                int mySize = myPrototype.GetPlaceHolderCount();
                PlaceHolderType[] newProto = new PlaceHolderType[parentSize + mySize];

                // Add the parent prototype components.
                for(int i = 0; i < parentSize; ++i)
                    newProto[i] = parentFull.GetPlaceHolder(i);

                // Add my prototype components.
                for(int i = 0; i < mySize; ++i)
                    newProto[i + parentSize] = myPrototype.GetPlaceHolder(i);

                // Store the new complete generic prototype.
                fullGenericPrototype = new GenericPrototype(newProto);
            }

            return fullGenericPrototype;
        }
Beispiel #14
0
        public override AstNode Visit(DelegateDefinition node)
        {
            // Parse the generic signature.
            GenericSignature genericSign = node.GetGenericSignature();
            GenericPrototype genProto    = GenericPrototype.Empty;
            PseudoScope      protoScope  = null;

            if (genericSign != null)
            {
                // Visit the generic signature.
                genericSign.Accept(this);

                // Connect the generic prototype.
                genProto = genericSign.GetPrototype();

                // Create the placeholders scope.
                protoScope = new PseudoScope(currentScope, genProto);
                node.SetGenericScope(protoScope);
            }

            // Prevent redefinition.
            ScopeMember old = currentContainer.FindType(node.GetName(), GenericPrototype.Empty);

            if (old != null)
            {
                Error(node, "trying to redefine a delegate.");
            }

            // Create the structure
            MemberFlags flags = node.GetFlags();
            // TODO: Check the flags.
            Class building = new Class(node.GetName(), flags, currentContainer);

            building.SetGenericPrototype(genProto);
            building.Position = node.GetPosition();
            node.SetStructure(building);

            // Add into the current scope.
            if (currentContainer.IsNamespace())
            {
                Namespace space = (Namespace)currentContainer;
                space.AddType(building);
            }
            else if (currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass())
            {
                Structure parent = (Structure)currentContainer;
                parent.AddType(building);
            }
            else
            {
                Error(node, "unexpected place for a delegate.");
            }

            // Register the compute binding delegate.
            if (building.GetFullName() == "Chela.Compute.ComputeBinding")
            {
                currentModule.RegisterComputeBindingDelegate(building);
            }

            return(node);
        }
Beispiel #15
0
        public override AstNode Visit(InterfaceDefinition node)
        {
            // Parse the generic signature.
            GenericSignature genericSign = node.GetGenericSignature();
            GenericPrototype genProto    = GenericPrototype.Empty;
            PseudoScope      protoScope  = null;

            if (genericSign != null)
            {
                // Visit the generic signature.
                genericSign.Accept(this);

                // Connect the generic prototype.
                genProto = genericSign.GetPrototype();

                // Create the placeholders scope.
                protoScope = new PseudoScope(currentScope, genProto);
                node.SetGenericScope(protoScope);
            }

            // Prevent redefinition.
            ScopeMember old = currentContainer.FindType(node.GetName(), genProto);

            if (old != null)
            {
                Error(node, "trying to redefine a class.");
            }

            // Create the structure
            Interface iface = new Interface(node.GetName(), node.GetFlags(), currentContainer);

            iface.SetGenericPrototype(genProto);
            node.SetStructure(iface);
            iface.Position = node.GetPosition();

            // Register type maps.
            string     fullName = iface.GetFullName();
            IChelaType alias;

            if (typeMaps.TryGetValue(fullName, out alias))
            {
                currentModule.RegisterTypeMap(alias, ReferenceType.Create(iface));
            }

            // Register some important interfaces.
            if (fullName == "Chela.Lang.NumberConstraint")
            {
                currentModule.RegisterNumberConstraint(iface);
            }
            else if (fullName == "Chela.Lang.IntegerConstraint")
            {
                currentModule.RegisterIntegerConstraint(iface);
            }
            else if (fullName == "Chela.Lang.FloatingPointConstraint")
            {
                currentModule.RegisterFloatingPointConstraint(iface);
            }
            else if (fullName == "Chela.Collections.IEnumerable")
            {
                currentModule.RegisterEnumerableIface(iface);
            }
            else if (fullName == "Chela.Collections.IEnumerator")
            {
                currentModule.RegisterEnumeratorIface(iface);
            }
            else if (fullName.StartsWith("Chela.Collections.Generic.IEnumerable<"))
            {
                currentModule.RegisterEnumerableGIface(iface);
            }
            else if (fullName.StartsWith("Chela.Collections.Generic.IEnumerator<"))
            {
                currentModule.RegisterEnumeratorGIface(iface);
            }

            // Use the prototype scope.
            if (protoScope != null)
            {
                PushScope(protoScope);
            }

            // Add into the current scope.
            if (currentContainer.IsNamespace())
            {
                Namespace space = (Namespace)currentContainer;
                space.AddType(iface);
            }
            else if (currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass())
            {
                Structure parent = (Structure)currentContainer;
                parent.AddType(iface);
            }
            else
            {
                Error(node, "unexpected place for a class.");
            }

            // Push the interface unsafe.
            if (iface.IsUnsafe())
            {
                PushUnsafe();
            }

            // Update the scope.
            PushScope(iface);

            // Visit the building children.
            VisitList(node.GetChildren());

            // Restore the scope.
            PopScope();

            // Restore the generic scope.
            if (protoScope != null)
            {
                PopScope();
            }

            // Pop the interface unsafe.
            if (iface.IsUnsafe())
            {
                PopUnsafe();
            }

            return(node);
        }
Beispiel #16
0
        public override AstNode Visit(ClassDefinition node)
        {
            // Check the partial flag.
            bool isPartial = (node.GetFlags() & MemberFlags.ImplFlagMask) == MemberFlags.Partial;

            // Add the parent static flag.
            if (currentContainer.IsStatic())
            {
                MemberFlags oldInstance = node.GetFlags() & MemberFlags.InstanceMask;
                if (oldInstance == MemberFlags.Static || oldInstance == MemberFlags.Instanced)
                {
                    MemberFlags flags = node.GetFlags() & ~MemberFlags.InstanceMask;
                    node.SetFlags(flags | MemberFlags.Static);
                }
                else
                {
                    Error(node, "static class member cannot be {0}.", oldInstance.ToString().ToLower());
                }
            }

            // Static classes are automatically sealed.
            if ((node.GetFlags() & MemberFlags.InstanceMask) == MemberFlags.Static)
            {
                MemberFlags flags = node.GetFlags() & ~MemberFlags.InheritanceMask;
                node.SetFlags(flags | MemberFlags.Sealed);
            }

            // Parse the generic signature.
            GenericSignature genericSign = node.GetGenericSignature();
            GenericPrototype genProto    = GenericPrototype.Empty;
            PseudoScope      protoScope  = null;

            if (genericSign != null)
            {
                // Visit the generic signature.
                genericSign.Accept(this);

                // Connect the generic prototype.
                genProto = genericSign.GetPrototype();

                // Create the placeholders scope.
                protoScope = new PseudoScope(currentScope, genProto);
                node.SetGenericScope(protoScope);
            }

            // Prevent redefinition.
            ScopeMember old = currentContainer.FindType(node.GetName(), genProto);

            if (old != null && (!isPartial || !old.IsClass()))
            {
                Error(node, "trying to redefine a class.");
            }

            // Create the structure
            Class clazz = (Class)old;

            if (clazz != null)
            {
                if (!clazz.IsPartial())
                {
                    Error(node, "incompatible partial class definitions.");
                }
            }
            else
            {
                clazz          = new Class(node.GetName(), node.GetFlags(), currentContainer);
                clazz.Position = node.GetPosition();
                clazz.SetGenericPrototype(genProto);
            }
            node.SetStructure(clazz);

            // Use the prototype scope.
            if (protoScope != null)
            {
                PushScope(protoScope);
            }

            // Register type maps.
            string     fullName = clazz.GetFullName();
            IChelaType alias;

            if (typeMaps.TryGetValue(fullName, out alias))
            {
                currentModule.RegisterTypeMap(alias, clazz);
            }

            // Register type association.
            IChelaType assoc;

            if (assocClasses.TryGetValue(fullName, out assoc))
            {
                currentModule.RegisterAssociatedClass(assoc, clazz);
            }

            // Array base class is special.
            if (fullName == "Chela.Lang.Array")
            {
                currentModule.RegisterArrayClass(clazz);
            }
            else if (fullName == "Chela.Lang.Attribute")
            {
                currentModule.RegisterAttributeClass(clazz);
            }
            else if (fullName == "Chela.Lang.ValueType")
            {
                currentModule.RegisterValueTypeClass(clazz);
            }
            else if (fullName == "Chela.Lang.Enum")
            {
                currentModule.RegisterEnumClass(clazz);
            }
            else if (fullName == "Chela.Lang.Type")
            {
                currentModule.RegisterTypeClass(clazz);
            }
            else if (fullName == "Chela.Lang.Delegate")
            {
                currentModule.RegisterDelegateClass(clazz);
            }
            else if (fullName == "Chela.Compute.StreamHolder")
            {
                currentModule.RegisterStreamHolderClass(clazz);
            }
            else if (fullName == "Chela.Compute.StreamHolder1D")
            {
                currentModule.RegisterStreamHolder1DClass(clazz);
            }
            else if (fullName == "Chela.Compute.StreamHolder2D")
            {
                currentModule.RegisterStreamHolder2DClass(clazz);
            }
            else if (fullName == "Chela.Compute.StreamHolder3D")
            {
                currentModule.RegisterStreamHolder3DClass(clazz);
            }
            else if (fullName == "Chela.Compute.UniformHolder")
            {
                currentModule.RegisterUniformHolderClass(clazz);
            }

            // Add into the current scope.
            if (currentContainer.IsNamespace())
            {
                Namespace space = (Namespace)currentContainer;
                if (old == null)
                {
                    space.AddType(clazz);
                }
            }
            else if (currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass())
            {
                Structure parent = (Structure)currentContainer;
                if (old == null)
                {
                    parent.AddType(clazz);
                }
            }
            else
            {
                Error(node, "unexpected place for a class.");
            }

            // Push the class unsafe.
            if (clazz.IsUnsafe())
            {
                PushUnsafe();
            }

            // Update the scope.
            PushScope(clazz);

            // Visit the building children.
            VisitList(node.GetChildren());

            // Restore the scope.
            PopScope();

            // Restore the scope.
            if (protoScope != null)
            {
                PopScope();
            }

            // Pop the class unsafe.
            if (clazz.IsUnsafe())
            {
                PopUnsafe();
            }

            return(node);
        }
Beispiel #17
0
        public override AstNode Visit(StructDefinition node)
        {
            // Parse the generic signature.
            GenericSignature genericSign = node.GetGenericSignature();
            GenericPrototype genProto    = GenericPrototype.Empty;
            PseudoScope      protoScope  = null;

            if (genericSign != null)
            {
                // Visit the generic signature.
                genericSign.Accept(this);

                // Connect the generic prototype.
                genProto = genericSign.GetPrototype();

                // Create the placeholders scope.
                protoScope = new PseudoScope(currentScope, genProto);
                node.SetGenericScope(protoScope);
            }

            // Prevent redefinition.
            ScopeMember old = currentContainer.FindType(node.GetName(), genProto);

            if (old != null)
            {
                Error(node, "trying to redefine a struct.");
            }

            // Create the structure
            Structure building = new Structure(node.GetName(), node.GetFlags(), currentContainer);

            building.SetGenericPrototype(genProto);
            node.SetStructure(building);
            building.Position = node.GetPosition();

            // Use the prototype scope.
            if (protoScope != null)
            {
                PushScope(protoScope);
            }

            // Register type association.
            string     fullName = building.GetFullName();
            IChelaType assoc;

            if (assocClasses.TryGetValue(fullName, out assoc))
            {
                currentModule.RegisterAssociatedClass(assoc, building);
            }

            // Add into the current scope.
            if (currentContainer.IsNamespace())
            {
                Namespace space = (Namespace)currentContainer;
                space.AddType(building);
            }
            else if (currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass())
            {
                Structure parent = (Structure)currentContainer;
                parent.AddType(building);
            }
            else
            {
                Error(node, "unexpected place for a structure.");
            }

            // Push the building unsafe.
            if (building.IsUnsafe())
            {
                PushUnsafe();
            }

            // Update the scope.
            PushScope(building);

            // Visit the building children.
            VisitList(node.GetChildren());

            // Restore the scope.
            PopScope();

            // Pop the building unsafe.
            if (building.IsUnsafe())
            {
                PopUnsafe();
            }

            // Restore the prototype scope.
            if (protoScope != null)
            {
                PopScope();
            }

            return(node);
        }