コード例 #1
0
ファイル: ObjectDeclarator.cs プロジェクト: ronsaldo/chela
        public static IChelaType DeReferenceType(IChelaType type)
        {
            if(!type.IsReference())
                return type;

            ReferenceType refType = (ReferenceType)type;
            return refType.GetReferencedType();
        }
コード例 #2
0
        public override AstNode Visit(UsingStatement node)
        {
            // Visit the using member.
            Expression member = node.GetMember();

            member.Accept(this);

            // Cast the pseudo-scope.
            PseudoScope scope = (PseudoScope)node.GetScope();

            // Get the member type.
            IChelaType memberType = member.GetNodeType();

            if (memberType.IsMetaType())
            {
                // Get the actual type.
                MetaType meta = (MetaType)memberType;
                memberType = meta.GetActualType();

                // Only structure relatives.
                if (memberType.IsStructure() || memberType.IsClass() || memberType.IsInterface())
                {
                    scope.AddAlias(memberType.GetName(), (ScopeMember)memberType);
                }
                else
                {
                    Error(node, "unexpected type.");
                }
            }
            else if (memberType.IsReference())
            {
                // Only static members supported.
                ScopeMember theMember     = (ScopeMember)member.GetNodeValue();
                MemberFlags instanceFlags = MemberFlags.InstanceMask & theMember.GetFlags();
                if (instanceFlags != MemberFlags.Static)
                {
                    Error(node, "unexpected member type.");
                }

                // Store the member.
                scope.AddAlias(theMember.GetName(), theMember);
            }
            else if (memberType.IsNamespace())
            {
                // Set the namespace chain.
                Namespace space = (Namespace)member.GetNodeValue();
                scope.SetChainNamespace(space);
            }
            else
            {
                Error(node, "unsupported object to use.");
            }

            base.Visit(node);

            return(node);
        }
コード例 #3
0
        /// <summary>
        /// Checks for equality with the possibility of ignore some arguments
        /// and maybe the return type.
        /// </summary>
        public bool Equals(FunctionType obj, int ignore, bool noret, bool noflags)
        {
            // Reject comparison with null, make sure the lengths are the same.
            if (obj == null ||
                arguments.Length != obj.arguments.Length ||
                variableArguments != obj.variableArguments)
            {
                return(false);
            }

            // Compare the return type.
            if (!noret && returnType != obj.returnType)
            {
                return(false);
            }

            // Compare the flags.
            if (!noflags && flags != obj.flags)
            {
                return(false);
            }

            // Compare the arguments.
            int size = arguments.Length;

            for (int i = ignore; i < size; ++i)
            {
                IChelaType leftArg  = arguments[i];
                IChelaType rightArg = obj.arguments[i];

                // Handle ref/out equality.
                if (leftArg != rightArg && leftArg != null && rightArg != null &&
                    leftArg.IsReference() && rightArg.IsReference())
                {
                    ReferenceType leftRef  = (ReferenceType)leftArg;
                    ReferenceType rightRef = (ReferenceType)rightArg;
                    leftArg  = leftRef.GetReferencedType();
                    rightArg = rightRef.GetReferencedType();
                }

                // Reject if different.
                if (leftArg != rightArg)
                {
                    return(false);
                }
            }

            // Everything is equal, return true.
            return(true);
        }
コード例 #4
0
        /// <summary>
        /// Create the specified array type.
        /// </summary>
        public static ArrayType Create(IChelaType valueType, int dimensions, bool readOnly)
        {
            // Remove the reference layer.
            if (valueType.IsReference())
            {
                ReferenceType refType = (ReferenceType)valueType;
                valueType = refType.GetReferencedType();
            }

            // Don't allow 0 dimensions.
            if (dimensions == 0)
            {
                dimensions = 1;
            }

            // Create the array type.
            ArrayType array = new ArrayType(valueType, dimensions, readOnly);

            return(arrayTypes.GetOrAdd(array));
        }
コード例 #5
0
        /// <summary>
        /// Gets the hash code, but with the possibility of ignoring
        /// some arguments and the return type..
        /// </summary>
        public int GetHashCode(int ignore, bool noret, bool noflags)
        {
            // Add the function type size and variable arguments flag.
            int hash = arguments.Length ^ variableArguments.GetHashCode();

            // Add the return type hash code.
            if (!noret)
            {
                hash ^= RuntimeHelpers.GetHashCode(returnType);
            }

            // Add the flags hash code.
            if (!noflags)
            {
                hash ^= flags.GetHashCode();
            }

            // Add the arguments.
            int size = arguments.Length;

            for (int i = ignore; i < size; ++i)
            {
                // Get the argument.
                IChelaType arg = arguments[i];

                // Handle ref/out equality.
                if (arg.IsReference())
                {
                    ReferenceType refType = (ReferenceType)arg;
                    arg = refType.GetReferencedType();
                }

                // Add the argument hash.
                hash ^= RuntimeHelpers.GetHashCode(arg);
            }

            return(hash);
        }
コード例 #6
0
ファイル: FunctionGenerator.cs プロジェクト: ronsaldo/chela
        private void Cast(AstNode where, object original, IChelaType originalType, IChelaType destType, bool isChecked)
        {
            // De-const.
            originalType = DeConstType(originalType);
            destType = DeConstType(destType);

            // Don't perform casting if not needed.
            if(originalType == destType)
                return;

            // Dereference.
            if(original != null && originalType.IsReference() && originalType != ChelaType.GetNullType())
            {
                ReferenceType refType = (ReferenceType) originalType;
                IChelaType referencedType = refType.GetReferencedType();

                bool load = false;
                if(destType.IsReference() == referencedType.IsReference())
                {
                    load = true;
                }
                else if(!destType.IsPointer() || referencedType.IsStructure() ||
                        referencedType.IsPointer() || referencedType.IsReference() ||
                        referencedType.IsVector())
                {
                    load = true;
                }

                if(load)
                {
                    ScopeMember member = (ScopeMember) original;
                    if(member.IsVariable())
                    {
                        Variable variable = (Variable) member;
                        LoadVariableValue(where, variable);
                    }
                }
                originalType = DeConstType(referencedType);
            }

            if(originalType == destType)
                return;

            //bool decrease = destType.GetSize() < originalType.GetSize();
            //System.Console.WriteLine("Cast {0} -> {1}", originalType, destType);
            IChelaType intermediateCast = null;
            if((originalType.IsInteger() && destType.IsFloatingPoint()) ||
               (originalType.IsFloatingPoint() && destType.IsInteger()) ||
               (originalType.IsFloatingPoint() && destType.IsFloatingPoint()) ||
               (originalType.IsInteger() && destType.IsInteger()) ||
               (destType.IsPointer() && originalType.IsPointer()) )
            {
                builder.CreateCast(destType);
            }
            else if((destType == ChelaType.GetSizeType() && originalType.IsPointer()) ||
                    (destType.IsPointer() && (originalType == ChelaType.GetSizeType() || originalType == ChelaType.GetPtrDiffType()))
                   )
            {
                Warning(where, "reinterpret_cast is preffered to cast from {0} into {1}", originalType.GetFullName(), destType.GetFullName());
                builder.CreateCast(destType);
            }
            else if(destType.IsReference() && originalType.IsReference())
            {
                IChelaType rsource = DeReferenceType(originalType);
                IChelaType rdest = DeReferenceType(originalType);
                if(rdest != null && rdest.IsStructure())
                {
                    if(rsource == null)
                        Error(where, "trying to unbox a null reference.");

                    if(isChecked)
                        builder.CreateChecked();
                    builder.CreateUnbox(rdest);
                }
                else
                {
                    if(rsource != null && rsource.IsStructure())
                        builder.CreateBox(rsource);
                    if(isChecked)
                        builder.CreateChecked();
                    builder.CreateCast(destType);
                }
            }
            else if(destType.IsReference() && originalType.IsFunctionGroup())
            {
                // Cast the delegate type.
                IChelaType referencedType = DeReferenceType(destType);
                Class delegateType = (Class)referencedType;

                // Get the selected function.
                FunctionGroupSelector selector = (FunctionGroupSelector)original;

                // Create the delegate.
                builder.CreateNewDelegate(delegateType, selector.GetSelected());
            }
            else if(destType.IsReference() && originalType.IsStructure())
            {
                builder.CreateBox(originalType);
                builder.CreateCast(destType);
            }
            else if((destType.IsReference() || destType.IsPointer()) &&
                    originalType == ChelaType.GetNullType())
            {
                builder.CreateCast(destType);
            }
            else if(destType.IsPointer() && originalType.IsStructure())
            {
                // Get the structure type.
                Structure building = (Structure)originalType;

                // Building must be IntPtr or UIntPtr.
                if(building != currentModule.GetAssociatedClass(ChelaType.GetSizeType()) &&
                    building != currentModule.GetAssociatedClass(ChelaType.GetPtrDiffType()))
                    Error(where, "cannot perform structure -> pointer cast.");

                // Unbox the structure.
                FieldVariable field = (FieldVariable)building.FindMember("__value");
                if(field == null)
                    field = (FieldVariable)building.FindMember("m_value");
                if(field == null)
                    Error(where, "cannot unbox {0}", building.GetFullName());
                builder.CreateExtractPrim();

                // Cast into the pointer.
                builder.CreateCast(destType);
            }
            else if(destType.IsStructure() && originalType.IsPointer())
            {
                // Get the structure type.
                Structure building = (Structure)destType;

                // Building must be IntPtr or UIntPtr.
                if(building != currentModule.GetAssociatedClass(ChelaType.GetSizeType()) &&
                    building != currentModule.GetAssociatedClass(ChelaType.GetPtrDiffType()))
                    Error(where, "cannot perform pointer -> structure cast.");

                // Get the structure pointer type.
                FieldVariable field = (FieldVariable)building.FindMember("__value");
                if(field == null)
                    field = (FieldVariable)building.FindMember("m_value");
                if(field == null)
                    Error(where, "cannot unbox {0}", building.GetFullName());

                // Cast the pointer into the pointer used by the structure.
                builder.CreateCast(field.GetVariableType());

                // Box the pointer.
                builder.CreatePrimBox(building);
            }
            else if(destType.IsStructure() && originalType.IsReference())
            {
                // Don't unbox null.
                IChelaType rsource = DeReferenceType(originalType);
                if(rsource == null)
                    Error(where, "trying to unbox a null reference.");

                if(isChecked)
                    builder.CreateChecked();
                builder.CreateUnbox(destType);
            }
            else if(destType.IsFirstClass() && originalType.IsStructure())
            {
                // Check dest/source relation.
                Structure bsource = (Structure)originalType;
                // TODO: Check the source type its a box.
                if(!bsource.IsDerivedFrom(currentModule.GetEnumClass()) &&
                    currentModule.GetAssociatedClassPrimitive(bsource) == null)
                    Error(where, "structure cannot be casted into a primitive value.");

                // Get the value field.
                FieldVariable valueField = (FieldVariable)bsource.FindMember("__value");
                if(valueField == null)
                    valueField = (FieldVariable)bsource.FindMember("m_value");
                if(valueField == null)
                    Error(where, "invalid enum definition, bug in the compiler.");

                // Use the intermediate cast.
                IChelaType boxedType = valueField.GetVariableType();
                if(destType != boxedType)
                   intermediateCast = boxedType;

                // Extract the primitive.
                builder.CreateExtractPrim();
            }
            else if(destType.IsStructure() && originalType.IsFirstClass())
            {
                // Check dest/source relation.
                Structure bdest = (Structure)destType;
                if(!bdest.IsDerivedFrom(currentModule.GetEnumClass()) &&
                    currentModule.GetAssociatedClassPrimitive(bdest) == null)
                    Error(where, "primitive value cannot be casted into structure.");

                // Get the value field.
                FieldVariable valueField = (FieldVariable)bdest.FindMember("__value");
                if(valueField == null)
                    valueField = (FieldVariable)bdest.FindMember("m_value");
                if(valueField == null)
                    Error(where, "invalid enum definition, bug in the compiler.");

                // Perform the intermediate cast.
                IChelaType enumType = valueField.GetVariableType();
                if(originalType != enumType)
                    Cast(where, null, originalType, enumType);

                // Create the structure.
                builder.CreatePrimBox(destType);
            }
            else if(destType.IsFirstClass() && originalType.IsReference())
            {
                // Get the associated class.
                Structure assoc = currentModule.GetAssociatedClass(destType);
                IChelaType rsource = DeReferenceType(originalType);
                if(rsource == null)
                    Error(where, "trying to unbox null.");
                if(!rsource.IsStructure() && !rsource.IsClass() && !rsource.IsInterface())
                    Error(where, "expected class/interface reference.");

                if(!assoc.IsBasedIn((Structure)rsource))
                    Error(where, "cannot perform cast " + originalType + " -> " + destType);
                if(isChecked)
                    builder.CreateChecked();
                builder.CreateUnbox(assoc);

                // Extract the primitive.
                builder.CreateExtractPrim();
            }
            else if(destType.IsReference() && originalType.IsFirstClass())
            {
                // Get the associated class.
                Structure assoc = currentModule.GetAssociatedClass(originalType);
                IChelaType rdest = DeReferenceType(destType);

                // Make sure the cast is valid.
                if(!assoc.IsBasedIn((Structure)rdest))
                    Error(where, "cannot perform cast " + originalType + " -> " + destType);

                builder.CreateBox(assoc);
                if(rdest != assoc)
                    builder.CreateCast(destType);
            }
            else if(destType.IsStructure() && originalType.IsStructure())
            {
                // Cast the structures.
                Structure originalBuilding = (Structure)originalType;
                Structure destBuilding = (Structure)destType;

                // Only boxed types are supported in this cast.
                if(originalBuilding.GetSlotCount() != 1 ||
                    destBuilding.GetSlotCount() != 1)
                    Error(where, "cannot perform cast structure {0} -> {1}.", originalBuilding.GetFullName(), destBuilding.GetFullName());

                // Get the original field.
                FieldVariable originalField = (FieldVariable)originalBuilding.FindMember("__value");
                if(originalField == null)
                    originalField = (FieldVariable)originalBuilding.FindMember("m_value");

                // Get the destination field.
                FieldVariable destField = (FieldVariable)destBuilding.FindMember("__value");
                if(destField == null)
                    destField = (FieldVariable)destBuilding.FindMember("m_value");

                // Make sure they exist.
                if(originalField == null || destField == null)
                    Error(where, "cannot perform cast structure {0} -> {1}.", originalBuilding.GetFullName(), destBuilding.GetFullName());

                // Unbox the source.
                Cast(where, original, originalType, originalField.GetVariableType());

                // Cast the field.
                Cast(where, null, originalField.GetVariableType(), destField.GetVariableType());

                // Box the casted source.
                Cast(where, null, destField.GetVariableType(), destType);
            }
            else if(destType.IsReference() && originalType.IsPlaceHolderType())
            {
                // TODO: Add type checking.
                builder.CreateGCast(destType);
            }
            else if((destType.IsFirstClass() || destType.IsStructure()) &&
                    originalType.IsPlaceHolderType())
            {
                // TODO: Add type checking.
                builder.CreateGCast(destType);
            }
            else if(destType.IsPlaceHolderType() && originalType.IsReference())
            {
                // TODO: Add type checking.
                builder.CreateGCast(destType);
            }
            else if(destType.IsPlaceHolderType() &&
                    (originalType.IsFirstClass() || originalType.IsStructure()))
            {
                // TODO: Add type checking.
                builder.CreateGCast(destType);
            }

            else
                Error(where, "cannot perform cast " + originalType + " -> " + destType);

            // Cast the intermediate type.
            if(intermediateCast != null)
                Cast(where, null, intermediateCast, destType);
        }
コード例 #7
0
ファイル: ChelaModule.cs プロジェクト: ronsaldo/chela
        private void RegisterAnonTypeLeaf(IChelaType type, bool registered)
        {
            // Make sure lower types are registered.
            if(!registered)
                RegisterType(type);

            if(type.IsReference())
            {
                ReferenceType refType = (ReferenceType)type;
                RegisterAnonTypeLeaf(refType.GetReferencedType());
            }
            else if(type.IsPointer())
            {
                PointerType pointerType = (PointerType)type;
                RegisterAnonTypeLeaf(pointerType.GetPointedType());
            }
            else if(type.IsConstant())
            {
                ConstantType constType = (ConstantType)type;
                RegisterAnonTypeLeaf(constType.GetValueType());
            }
            else if(type.IsArray())
            {
                ArrayType arrayType = (ArrayType)type;
                RegisterAnonTypeLeaf(arrayType.GetValueType());
            }
            else if(type.IsVector())
            {
                VectorType vectorType = (VectorType)type;
                RegisterAnonTypeLeaf(vectorType.GetPrimitiveType());
            }
            else if(type.IsMatrix())
            {
                MatrixType matrixType = (MatrixType)type;
                RegisterAnonTypeLeaf(matrixType.GetPrimitiveType());
            }
            else if(type.IsFunction())
            {
                FunctionType functionType = (FunctionType)type;

                // Register the return type.
                RegisterAnonTypeLeaf(functionType.GetReturnType());

                // Register the function arguments.
                for(int i = 0; i < functionType.GetArgumentCount(); ++i)
                    RegisterAnonTypeLeaf(functionType.GetArgument(i));
            }
            else if(type.IsPlaceHolderType())
            {
                // Register the base types.
                PlaceHolderType placeholder = (PlaceHolderType)type;
                for(int i = 0; i < placeholder.GetBaseCount(); ++i)
                    RegisterMember(placeholder.GetBase(i));
            }
            else if(type.IsPrimitive())
            {
                // Do nothing.
            }
            else if(type.IsTypeInstance())
            {
                StructureInstance instance = (StructureInstance)type;
                instance.PrepareSerialization();
                RegisterMember(instance);
            }
            else
            {
                // Found a leaf.
                ScopeMember member = (ScopeMember)type;
                RegisterMember(member);
            }
        }
コード例 #8
0
ファイル: FunctionSemantic.cs プロジェクト: ronsaldo/chela
        public IChelaType RefCoerceCounted(AstNode where, IChelaType leftType, IChelaType rightType, object value, out int count)
        {
            // Initialize the count.
            count = 0;

            // Both types must be references.
            if(!leftType.IsReference())
                return null;
            if(!rightType.IsReference())
                return null;

            // Remove that reference.
            IChelaType left = DeReferenceType(leftType);
            IChelaType right = DeReferenceType(rightType);

            // Check for primitive coercion.
            if(left != right)
            {
                if(left.IsFirstClass() && right == currentModule.GetAssociatedClass(left))
                    return leftType;
                else if(right.IsFirstClass() && left == currentModule.GetAssociatedClass(right))
                    return leftType;
                else
                    return null;
            }

            return leftType;
        }
コード例 #9
0
ファイル: FunctionSemantic.cs プロジェクト: ronsaldo/chela
        /// <summary>
        /// Converts T&& into T&
        /// </summary>
        private IChelaType SimplifyReference(IChelaType type)
        {
            if(type.IsReference())
            {
                ReferenceType refType = (ReferenceType)type;
                IChelaType referenced = refType.GetReferencedType();
                if(referenced.IsReference())
                    type = referenced;
            }

            return type;
        }
コード例 #10
0
ファイル: FunctionSemantic.cs プロジェクト: ronsaldo/chela
        private IChelaType CoerceDeReference(IChelaType type, ref bool isConstant)
        {
            if(type.IsReference())
            {
                ReferenceType refType = (ReferenceType)type;
                IChelaType referencedType = refType.GetReferencedType();
                if(referencedType.IsPrimitive() || referencedType.IsStructure() ||
                   referencedType.IsReference() || referencedType.IsPointer() ||
                   referencedType.IsConstant() || referencedType.IsVector() ||
                   referencedType.IsMatrix() || referencedType.IsPlaceHolderType() ||
                   referencedType.IsFirstClass())
                    type = referencedType;

                // De-const again.
                isConstant = type.IsConstant();
                type = DeConstType(type);
            }

            return type;
        }