コード例 #1
0
        public override AstNode Visit(MemberAccess node)
        {
            // This is the same as VariableReference implementation.
            // Get the node type.
            IChelaType variableType = node.GetNodeType();

            // Ignore type references, namespaces and functions.
            if (variableType.IsMetaType() || variableType.IsNamespace() ||
                variableType.IsFunctionGroup() || variableType.IsFunction())
            {
                return(node);
            }

            // The type must be a reference.
            variableType = DeReferenceType(variableType);

            // Now, it must be a constant.
            if (!variableType.IsConstant())
            {
                Error(node, "constant initialization can't reference no constant variables.");
            }

            // The node value, must be the constant variable.
            FieldVariable constantVar = (FieldVariable)node.GetNodeValue();

            // Find the corresponding constant data.
            ConstantData depData;

            if (constants.TryGetValue(constantVar, out depData))
            {
                currentConstant.AddDependency(depData);
            }

            return(node);
        }
コード例 #2
0
        public override AstNode Visit(FieldDeclaration node)
        {
            // Get the field.
            FieldVariable field = (FieldVariable)node.GetVariable();

            // Get the field type.
            IChelaType fieldType = field.GetVariableType();

            if (!fieldType.IsConstant() || field.IsExternal())
            {
                return(node); // Ignore not constant fields.
            }
            // Get the initializer.
            Expression initializer = node.GetDefaultValue();

            if (initializer == null)
            {
                Error(node, "constants must have initializers.");
            }

            // Don't allow multiple definitions.
            if (constants.ContainsKey(field))
            {
                Error(node, "multiples definitions of a constant.");
            }

            // Store the constant.
            ConstantData data = new ConstantData(field, initializer);

            this.constants.Add(field, data);

            // Return the node.
            return(node);
        }
コード例 #3
0
ファイル: ObjectDeclarator.cs プロジェクト: ronsaldo/chela
        public static IChelaType DeConstType(IChelaType type)
        {
            if(type == null || !type.IsConstant())
                return type;

            ConstantType constantType = (ConstantType)type;
            return constantType.GetValueType();
        }
コード例 #4
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);
            }
        }
コード例 #5
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;
        }
コード例 #6
0
ファイル: FunctionSemantic.cs プロジェクト: ronsaldo/chela
        public IChelaType CoerceCounted(AstNode where, IChelaType leftType, IChelaType rightType, object value, out int count)
        {
            // Initialize the output to zero.
            count = 0;

            // Remove constant.
            bool leftConstant = leftType.IsConstant();
            leftType = DeConstType(leftType);

            bool rightConstant = rightType.IsConstant();
            rightType = DeConstType(rightType);

            // Compute the result for constants.
            bool resultConstant = leftConstant && rightConstant;

            // Handle null type.
            if(leftType == ChelaType.GetNullType())
            {
                leftType = rightType;
            }
            else if(rightType == ChelaType.GetNullType())
            {
                rightType = leftType;
            }

            // Remove double references
            leftType = SimplifyReference(leftType);
            rightType = SimplifyReference(rightType);

            // Dereference.
            leftType = CoerceDeReference(leftType, ref leftConstant);
            rightType = CoerceDeReference(rightType, ref rightConstant);
            resultConstant = leftConstant && rightConstant;

            // If the right type is an integer constant, use his actual type.
            ConstantValue rightValue = value as ConstantValue;
            if(rightConstant && rightType.IsInteger() && rightValue != null &&
                rightType != ChelaType.GetBoolType() &&
                rightType != ChelaType.GetCharType())
            {
                bool positive = rightValue.IsPositive();
                if(leftType.IsUnsigned() && positive)
                {
                    ulong cval = rightValue.GetULongValue();
                    if(cval <= 0xFF)
                        rightType = ChelaType.GetByteType();
                    else if(cval <= 0xFFFF)
                        rightType = ChelaType.GetUShortType();
                    else if(cval <= 0xFFFFFFFFu)
                        rightType = ChelaType.GetUIntType();
                    else
                        rightType = ChelaType.GetULongType();
                }
                else if(!positive)
                {
                    long cval = rightValue.GetLongValue();
                    // Test using the absolute value.
                    if(cval < 0)
                        cval = -cval;

                    if(cval <= 0x7F)
                        rightType = ChelaType.GetSByteType();
                    else if(cval <= 0x7FFF)
                        rightType = ChelaType.GetShortType();
                    else if(cval <= 0x7FFFFFFF)
                        rightType = ChelaType.GetIntType();
                    else
                        rightType = ChelaType.GetLongType();
                }
            }

            /*if(currentFunction != null && currentFunction.GetName() == "GetEnumerator")
            {
                IChelaType left = DeReferenceType(leftType);
                IChelaType right = DeReferenceType(rightType);
                Console.WriteLine("{0}", currentFunction.GetFullName());
                Console.WriteLine("left {0} -> {1}", leftType.GetFullName(), left.GetFullName());
                Console.WriteLine("right {0} -> {1}", rightType.GetFullName() ,right.GetFullName());
                Console.WriteLine("left == right: {0}", left == right);
            }*/

            //System.Console.WriteLine("coerce {0} <-> {1}, eq {2}", leftType, rightType, leftType == rightType);
            // Any pointer can be casted implicitly into a void* or const void*.
            if(leftType == ChelaType.GetConstVoidPtrType() && rightType.IsPointer())
            {
                count++;
                return CoerceConstantResult(ChelaType.GetConstVoidPtrType(), resultConstant);
            }
            else if(leftType == ChelaType.GetVoidPtrType() && rightType.IsPointer())
            {
                count++;
                return CoerceConstantResult(ChelaType.GetVoidPtrType(), resultConstant);
            }

            if(rightType == ChelaType.GetConstVoidPtrType() && leftType.IsPointer())
            {
                count++;
                return CoerceConstantResult(ChelaType.GetConstVoidPtrType(), resultConstant);
            }
            else if(rightType == ChelaType.GetVoidPtrType() && leftType.IsPointer())
            {
                count++;
                return CoerceConstantResult(ChelaType.GetVoidPtrType(), resultConstant);
            }

            // Void has special treatment.
            if(leftType == ChelaType.GetVoidType() || rightType == ChelaType.GetVoidType())
                return null; // Invalid coercion.

            IChelaType destType = leftType;
            if(leftType != rightType)
            {
                // Increase the coercion count.
                count++;

                // Vector type checks.
                bool vector = leftType.IsVector() || rightType.IsVector();
                int numcomponents = 1;

                // Vector->Vector coercion rules.
                if(leftType.IsVector() && rightType.IsVector())
                {
                    // Use primitive coercion rules.
                    vector = false;

                    // Check left vector.
                    VectorType leftVector = (VectorType)leftType;
                    leftType = leftVector.GetPrimitiveType();
                    numcomponents = leftVector.GetNumComponents();

                    // Check right vector
                    VectorType rightVector = (VectorType)rightType;
                    rightType = rightVector.GetPrimitiveType();
                    if(numcomponents != rightVector.GetNumComponents())
                        return null;
                }
                else if(vector)
                {
                    // Primitive <-> vector coercion is not allowed.
                    if(leftType.IsPrimitive() || rightType.IsPrimitive())
                        return null; // Not coercion allowed.
                }

                // Coerce the types.
                uint size = Math.Max(leftType.GetSize(), rightType.GetSize());
                bool sameSize = (leftType.GetSize() == size) && (rightType.GetSize() == size);
                bool integer = false;
                bool floating = false;
                bool reference = false;
                bool pointer = false;
                bool structure = false;
                bool functionGroup = false;
                bool firstClass = false;
                bool placeholder = false;

                if(leftType.IsInteger())
                    integer = true;
                else if(leftType.IsFloatingPoint())
                    floating = true;
                else if(leftType.IsReference())
                    reference = true;
                else if(leftType.IsPointer())
                    pointer = true;
                else if(leftType.IsFunctionGroup())
                    functionGroup = true;
                if(leftType.IsPlaceHolderType())
                    placeholder = true;
                if(leftType.IsStructure())
                    structure = true;
                if(leftType.IsFirstClass())
                    firstClass = true;

                if(rightType.IsInteger())
                    integer = true;
                else if(rightType.IsFloatingPoint())
                    floating = true;
                else if(rightType.IsReference())
                    reference = true;
                else if(rightType.IsPointer())
                    pointer = true;
                else if(rightType.IsFunctionGroup())
                    functionGroup = true;
                if(rightType.IsPlaceHolderType())
                    placeholder = true;
                if(rightType.IsStructure())
                    structure = true;
                if(rightType.IsFirstClass())
                    firstClass = true;

                if(reference && !pointer && !firstClass && !placeholder)
                {
                    if(leftType.IsReference() && rightType.IsReference())
                    {
                        // Dereference them.
                        IChelaType left = DeReferenceType(leftType);
                        IChelaType right = DeReferenceType(rightType);
                        IChelaType objectType = currentModule.TypeMap(ChelaType.GetObjectType());
                        destType = null;
                        //System.Console.WriteLine("[{0}]{1} {2} {3}", leftType, left, right, objectType);

                        if(left == right)
                        {
                            destType = leftType;
                        }
                        else if(left == objectType || right == objectType)
                        {
                            destType = ReferenceType.Create(objectType);
                        }
                        else if(left.IsInterface() || right.IsInterface())
                        {
                            destType = null;
                            Structure leftBuilding = (Structure)left;
                            Structure rightBuilding = (Structure)right;
                            // TODO: Check this.
                            if(leftBuilding.IsInterface())
                            {
                                if(rightBuilding.Implements(leftBuilding))
                                    destType = leftType;
                            }
                            if(rightBuilding.IsInterface() && destType == null)
                            {
                                if(leftBuilding.Implements(rightBuilding))
                                    destType = rightType;
                            }
                        }
                        else if(left.IsClass() && right.IsClass())
                        {
                            Structure leftBuilding = (Structure)left;
                            Structure rightBuilding = (Structure)right;

                            // Make sure the generic inheritance relations are loaded.
                            FixGenericBases(leftBuilding);
                            FixGenericBases(rightBuilding);

                            //System.Console.WriteLine("Check base");
                            if(leftBuilding.IsDerivedFrom(rightBuilding))
                                destType = rightType;
                            else if(rightBuilding.IsDerivedFrom(leftBuilding))
                                destType = leftType;
                            else
                                destType = null;
                        }
                        else if(left.IsArray() && right.IsArray())
                        {
                            // Array-array coercion.
                            ArrayType leftArray = (ArrayType)left;
                            ArrayType rightArray = (ArrayType)right;

                            // The dimensions must match.
                            if(leftArray.GetDimensions() != rightArray.GetDimensions())
                            {
                                destType = null;
                            }
                            else
                            {
                                // Get the element types.
                                IChelaType leftElement = leftArray.GetValueType();
                                IChelaType rightElement = rightArray.GetValueType();

                                // Compute the read only flag.
                                bool readOnly = leftArray.IsReadOnly() || rightArray.IsReadOnly();
                                int dimensions = leftArray.GetDimensions();

                                // Coerce the element types.
                                if(leftElement == rightElement)
                                {
                                    destType = ArrayType.Create(leftElement, dimensions, readOnly);
                                }
                                else
                                {
                                    IChelaType coerced = Coerce(where, leftElement, rightElement, null);
                                    if(coerced != null)
                                        destType = ArrayType.Create(coerced, dimensions, readOnly);
                                }

                                // Add the reference layer.
                                if(destType != null)
                                    destType = ReferenceType.Create(destType);
                            }
                        }
                    }
                    else if(functionGroup)
                    {
                        // By default there isn't coercion
                        destType = null;

                        // Function -> Delegate coercion.
                        IChelaType refType = null;
                        FunctionGroupType groupType = null;
                        if(leftType.IsReference())
                        {
                            refType = leftType;
                            groupType = (FunctionGroupType)rightType;
                        }
                        else
                        {
                            refType = rightType;
                            groupType = (FunctionGroupType)leftType;
                        }

                        // One of the types must be a delegate.
                        IChelaType referencedType = DeReferenceType(refType);
                        if(referencedType.IsClass())
                        {
                            // If one of the types is a delegate, coerce to it.
                            Class delegateClass = currentModule.GetDelegateClass();
                            Class delegateType = (Class)referencedType;
                            if(delegateType.IsDerivedFrom(delegateClass))
                            {
                                // Now, select the correct function.
                                FunctionGroup invokeGroup = (FunctionGroup)delegateType.FindMemberRecursive("Invoke");
                                FunctionGroupSelector selector = (FunctionGroupSelector)value;
                                FunctionGroup delegatedGroup = selector.GetFunctionGroup();
                                selector.Select(null);
                                foreach(FunctionGroupName gname in invokeGroup.GetFunctions())
                                {
                                    // Ignore static signatures.
                                    Function invokeFunction = gname.GetFunction();
                                    if(invokeFunction.IsStatic())
                                        continue;

                                    // Only one invoke per delegate is permitted.
                                    List<object> arguments = new List<object> ();
                                    FunctionType invokeType = invokeFunction.GetFunctionType();
                                    for(int i = 1; i < invokeType.GetArgumentCount(); ++i)
                                        arguments.Add(invokeType.GetArgument(i));

                                    // Pick the function. This performs argument covariance.
                                    Function picked = PickFunction(where, delegatedGroup, groupType, null, arguments, true);
                                    if(picked != null)
                                    {
                                        // Make sure the return type is compatible.
                                        FunctionType pickedType = picked.GetFunctionType();
                                        IChelaType delegateReturn = invokeType.GetReturnType();
                                        IChelaType pickedReturn = pickedType.GetReturnType();
                                        if(pickedReturn != delegateReturn &&
                                           Coerce(pickedReturn, delegateReturn) != delegateReturn)
                                            Error(where, "incompatible delegate and invoked function return type.");

                                        selector.Select(picked);
                                        break;
                                    }
                                }

                                if(selector.GetSelected() != null)
                                    destType = refType;
                                else
                                    destType = null;
                            }
                        }
                    }
                    else
                    {
                        // Support structure boxing
                        IChelaType referencedType;
                        IChelaType valueType;
                        if(leftType.IsReference())
                        {
                            referencedType = DeReferenceType(leftType);
                            valueType = rightType;
                        }
                        else
                        {
                            referencedType = DeReferenceType(rightType);
                            valueType = leftType;
                        }

                        if(valueType.IsStructure())
                        {
                            Structure referencedClass = referencedType as Structure;
                            Structure building = (Structure)valueType;
                            if(referencedClass != null && building.IsBasedIn(referencedClass))
                                destType = ReferenceType.Create(referencedType);
                            else
                                destType = null;
                        }
                        else
                        {
                            destType = null;
                        }
                    }
                }
                else if(pointer && !reference && !firstClass && !placeholder)
                {
                    if(leftType.IsPointer() && rightType.IsPointer())
                    {
                        // Depointer them.
                        IChelaType left = DePointerType(leftType);
                        IChelaType right = DePointerType(rightType);

                        // De-const.
                        bool pointerToConstant = false;
                        if(left.IsConstant() || right.IsConstant())
                            pointerToConstant = true;

                        left = DeConstType(left);
                        right = DeConstType(right);
                        if(left == right)
                        {
                            destType = left;
                        }
                        else if(left.IsStructure() && right.IsStructure())
                        {
                            Structure leftBuilding = (Structure)left;
                            Structure rightBuilding = (Structure)right;
                            if(leftBuilding.IsDerivedFrom(rightBuilding))
                                destType = right;
                            else if(rightBuilding.IsDerivedFrom(leftBuilding))
                                destType = left;
                            else
                                destType = null;
                        }
                        else if(left.IsStructure() && right.IsFirstClass() ||
                                right.IsStructure() && left.IsFirstClass())
                        {
                            // They could represent the same type.
                            Structure building;
                            IChelaType primitive;
                            if(left.IsStructure())
                            {
                                building = (Structure)left;
                                primitive = right;
                            }
                            else
                            {
                                building = (Structure)right;
                                primitive = left;
                            }

                            // Get the primitive associated class.
                            Structure associated = currentModule.GetAssociatedClass(primitive);

                            // If the structure is the associated class, they are the same type.
                            if(building == associated)
                                destType = left;
                            else
                                destType = null;

                        }
                        else
                        {
                            destType = null;
                        }

                        // Make the pointer.
                        if(destType != null)
                        {
                            if(pointerToConstant)
                                destType = PointerType.Create(ConstantType.Create(destType));
                            else
                                destType = PointerType.Create(destType);
                        }
                    }
                    else
                    {
                        // Invalid coercion.
                        destType = null;
                    }
                }
                else if(firstClass && reference)
                {
                    // Select the primitive and reference type.
                    IChelaType primType;
                    IChelaType refType;
                    if(leftType.IsFirstClass())
                    {
                        primType = leftType;
                        refType = rightType;
                    }
                    else
                    {
                        primType = rightType;
                        refType = leftType;
                    }

                    // Get the referenced type.
                    Structure assoc = currentModule.GetAssociatedClass(primType);
                    IChelaType referencedType = DeReferenceType(refType);
                    if(assoc == null || (!referencedType.IsClass() && !referencedType.IsStructure() && !referencedType.IsInterface()))
                        return null;
                    Structure building = (Structure)referencedType;

                    // Only cast if there are related.
                    if(assoc.IsBasedIn(building))
                        destType = refType;
                    else
                        destType = null;
                }
                else if(firstClass && structure)
                {
                    IChelaType primType;
                    IChelaType structType;
                    if(leftType.IsFirstClass())
                    {
                        primType = leftType;
                        structType = rightType;
                    }
                    else
                    {
                        primType = rightType;
                        structType = leftType;
                    }

                    // Get the associated type
                    Structure building = (Structure)structType;
                    Structure assoc = currentModule.GetAssociatedClass(primType);
                    if(assoc == null || structType != assoc)
                    {
                        destType = null;

                        // Get the value field.
                        FieldVariable valueField = (FieldVariable)building.FindMember("__value");
                        if(valueField == null)
                            valueField = (FieldVariable)building.FindMember("m_value");

                        // Check enumerations
                        if(valueField != null)
                        {
                            IChelaType valueType = valueField.GetVariableType();
                            Class enumClass = currentModule.GetEnumClass();
                            if(building.IsDerivedFrom(enumClass))
                            {
                                if(primType == valueType)
                                    destType = primType;
                            }
                            else
                            {
                                // Generic structure.
                                IChelaType coerced = Coerce(valueType, primType);
                                if(coerced == valueType)
                                    destType = structType;
                                else
                                    destType = coerced;
                            }
                        }
                    }
                    else
                    {
                        // Don't count coercion
                        count = 0;
                        destType = leftType;
                    }
                }
                else if(placeholder && reference)
                {
                    // Check for placeholder->object or constraint.
                    PlaceHolderType placeholderType = null;
                    IChelaType referenceType = null;
                    if(leftType.IsPlaceHolderType())
                    {
                        placeholderType = (PlaceHolderType)leftType;
                        referenceType = rightType;
                    }
                    else
                    {
                        placeholderType = (PlaceHolderType)rightType;
                        referenceType = leftType;
                    }

                    // Get the referenced type.
                    IChelaType referencedType = DeReferenceType(referenceType);

                    // Default result.
                    destType = null;

                    // Use the constraints.
                    if(referencedType.IsInterface() || referencedType.IsClass())
                    {
                        Structure building = (Structure)referencedType;

                        // Check if one constraint implements building.
                        bool compatible = false;

                        // Object is implicit.
                        if(building == currentModule.GetObjectClass())
                            compatible = true;
                        // Value types are deriverd from the ValueType class.
                        else if(placeholderType.IsValueType() &&
                                building == currentModule.GetValueTypeClass())
                            compatible = true;

                        for(int i = 0; i < placeholderType.GetBaseCount() && !compatible; ++i)
                        {
                            Structure baseBuilding = (Structure)placeholderType.GetBase(i);
                            if(baseBuilding == building) // The constraint is the building.
                                compatible = true;
                            // The constraint implements the target type.
                            else if(baseBuilding.IsClass() && baseBuilding.IsDerivedFrom(building))
                                compatible = true;
                            // The constraint implements the interface
                            else if(baseBuilding.IsInterface() && baseBuilding.Implements(building))
                                compatible = true;

                            // Not implemented by the constraint.
                        }

                        // If the type is compatible, perform coercion.
                        if(compatible)
                            destType = referenceType;
                    }
                }
                else if(integer && floating && !placeholder)
                {
                    // int->(float|double)
                    if(size <= 4)
                        destType = ChelaType.GetFloatType();
                    else
                        destType = ChelaType.GetDoubleType();
                }
                else if(integer && !placeholder)
                {
                    // int->long?

                    // Find the signs.
                    bool signed = !leftType.IsUnsigned() || !rightType.IsUnsigned();
                    bool unsigned = leftType.IsUnsigned() || rightType.IsUnsigned();
                    bool withSign = signed;

                    // If they have the same size and different signs, increase the size
                    if(sameSize && signed && unsigned)
                        ++size;

                    if(size == 1)
                    {
                        if(withSign)
                            destType = ChelaType.GetSByteType();
                        else
                            destType = ChelaType.GetByteType();
                    }
                    else if(size == 2)
                    {
                        if(withSign)
                            destType = ChelaType.GetShortType();
                        else
                            destType = ChelaType.GetUShortType();
                    }
                    else if(size <= 4)
                    {
                        if(withSign)
                            destType = ChelaType.GetIntType();
                        else
                            destType = ChelaType.GetUIntType();
                    }
                    else if(size == 100)
                    {
                        if(withSign)
                            destType = null;
                        else
                            destType = ChelaType.GetSizeType();
                    }
                    else if(size <= 8)
                    {
                        if(withSign)
                            destType = ChelaType.GetLongType();
                        else
                            destType = ChelaType.GetULongType();
                    }
                }
                else if(floating && !placeholder)
                {
                    // float->double
                    if(size <= 4)
                        destType = ChelaType.GetFloatType();
                    else
                        destType = ChelaType.GetDoubleType();
                }
                else
                {
                    // Failed to coerce.
                    destType = null;
                }

                // Vector coercion.
                if(destType != null && numcomponents > 1 && destType.IsPrimitive())
                    destType = VectorType.Create(destType, numcomponents);
            }
            return CoerceConstantResult(destType, resultConstant);
        }