コード例 #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
ファイル: 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);
        }
コード例 #3
0
        public override AstNode Visit(FunctionPrototype node)
        {
            // Get the name expression.
            Expression nameExpression = node.GetNameExpression();

            if (nameExpression == null)
            {
                return(node);
            }

            // Visit the name expression.
            nameExpression.SetHints(Expression.MemberHint);
            nameExpression.Accept(this);

            // Get the function and his type.
            Function     function     = node.GetFunction();
            FunctionType functionType = function.GetFunctionType();

            if (!function.IsMethod())
            {
                Error(node, "expected a method prototype.");
            }
            Method method = (Method)function;

            // It must be a function selector.
            IChelaType nameType = nameExpression.GetNodeType();

            if (!nameType.IsFunctionGroup())
            {
                Error(nameExpression, "expected a function group.");
            }
            FunctionGroupSelector selector = (FunctionGroupSelector)nameExpression.GetNodeValue();
            FunctionGroup         group    = selector.GetFunctionGroup();

            // Find a matching function in the group.
            Function match = null;

            foreach (FunctionGroupName gname in group.GetFunctions())
            {
                // Ignore static functions.
                if (gname.IsStatic())
                {
                    continue;
                }

                // Check for match.
                FunctionType candidate = gname.GetFunctionType();

                // Found a match?.
                if (MatchFunction(candidate, functionType, 1))
                {
                    match = (Function)gname.GetFunction();
                    break;
                }
            }

            // Raise an error.
            if (match == null)
            {
                Error(nameExpression, "couldn't find matching interface member for {0}", functionType.GetName());
            }

            // TODO: Rename the method.

            // Bind the contract.
            method.SetExplicitContract(match);

            return(node);
        }