Ejemplo n.º 1
0
        public override AstNode Visit(MemberAccess node)
        {
            // Begin the node
            builder.BeginNode(node);

            // Get the reference expression.
            Expression baseRef = node.GetReference();

            // Visit it.
            baseRef.Accept(this);

            // Get the reference and coercion type.
            IChelaType refType = baseRef.GetNodeType();
            IChelaType coercionType = node.GetCoercionType();
            if(refType != coercionType)
                Cast(node, baseRef.GetNodeValue(), refType, coercionType);

            // Cast generic place holders into something more appropiate.
            Scope memberParent = GetMemberParent(node);
            if(coercionType.IsPlaceHolderType() && memberParent.IsType())
            {
                IChelaType targetType = (IChelaType)memberParent;
                if(targetType.IsPassedByReference())
                    targetType = ReferenceType.Create(targetType);

                // Cast the generic placeholder.
                builder.CreateGCast(targetType);
            }

            // Pop redundant reference.
            ScopeMember member = (ScopeMember)node.GetNodeValue();
            if((coercionType.IsReference() || coercionType.IsStructure())
                && member.IsStatic())
                builder.CreatePop();

            // Load the implicit this.
            if(node.ImplicitSelf)
                LoadCurrentSelf();

            // Next checks are only for functions.
            IChelaType nodeType = node.GetNodeType();
            if(!nodeType.IsFunctionGroup() && !nodeType.IsFunction())
                return builder.EndNode();

            // Handle virtual suppression.
            if(nodeType.IsFunctionGroup() && refType.IsMetaType())
            {
                FunctionGroupSelector selector = (FunctionGroupSelector)node.GetNodeValue();
                Function selected = selector.GetSelected();

                // Load implicit this.
                if(!selected.IsStatic() && selector.ImplicitThis)
                    LoadCurrentSelf();
            }

            // Only primitives and structure can be boxed.
            IChelaType referencedType = DeReferenceType(coercionType);
            bool firstClass = referencedType.IsFirstClass();
            bool structure = referencedType.IsStructure();
            if(!firstClass && !structure)
                return builder.EndNode();

            // Box structures when calling virtual methods.
            Method method = null;
            if(nodeType.IsFunctionGroup())
            {
                // Set the must box flag.
                FunctionGroupSelector selector = (FunctionGroupSelector)node.GetNodeValue();
                Function selected = selector.GetSelected();
                if(selected == null)
                    Error(node, "Trying to get unselected function.");
                if(selected.IsMethod())
                    method = (Method)selected;
            }
            else //if(nodeType.IsFunction())
            {
                Function function = (Function)node.GetNodeValue();
                if(function.IsMethod())
                    method = (Method)function;
            }

            // Only methods may require boxing.
            if(method != null)
            {
                if(!method.GetParentScope().IsStructure())
                {
                    // Must box.
                    IChelaType boxType;
                    if(firstClass)
                        boxType = currentModule.GetAssociatedClass(referencedType);
                    else
                        boxType = referencedType;
                    builder.CreateBox(boxType);
                }
                else if(firstClass) // Light primitive boxing.
                {
                    builder.CreatePrimBox(currentModule.GetAssociatedClass(referencedType));
                }
            }

            return builder.EndNode();
        }
Ejemplo n.º 2
0
        public override AstNode Visit(MemberAccess node)
        {
            // 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 can be a constant
            if(variableType.IsConstant())
            {
                // Perform constant expansion.
                FieldVariable field = (FieldVariable)node.GetNodeValue();
                if(!field.IsExternal())
                    return field.GetInitializer().ToAstNode(node.GetPosition());
            }

            return node;
        }
Ejemplo n.º 3
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;
        }