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

            // Get the pointer expression.
            Expression basePointer = node.GetBasePointer();

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

            // Get the pointer and coercion type.
            IChelaType pointerType = basePointer.GetNodeType();
            IChelaType coercionType = node.GetCoercionType();
            if(pointerType != coercionType)
                Cast(node, basePointer.GetNodeValue(), pointerType, coercionType);

            return builder.EndNode();
        }
Exemplo n.º 2
0
        public override AstNode Visit(IndirectAccess node)
        {
            // Evaluate the base pointer.
            Expression basePointer = node.GetBasePointer();
            basePointer.Accept(this);

            // Get the base pointer type.
            IChelaType pointerType = basePointer.GetNodeType();
            if(pointerType.IsReference())
            {
                // Dereference the variable.
                ReferenceType refType = (ReferenceType) pointerType;
                pointerType = refType.GetReferencedType();
            }

            if(!pointerType.IsPointer())
                Error(node, "expected pointer indirection.");

            // Set the coercion type.
            node.SetCoercionType(pointerType);

            // Get the pointed type.
            PointerType pointer = (PointerType) pointerType;
            IChelaType pointedType = pointer.GetPointedType();

            // Only structure type are supported.
            if(!pointedType.IsStructure())
                Error(node, "only structure indirection is supported.");

            // Cast the structure type.
            Structure structType = (Structure) pointedType;

            // Check that the structure has the member.
            ScopeMember member = structType.FindMemberRecursive(node.GetName());
            if(member == null)
                Error(node, "couldn't find the member '{0}'.", node.GetName());

            // Check the flags.
            if((member.GetFlags() & MemberFlags.InstanceMask) == MemberFlags.Static)
                Error(node, "cannot use pointer indirectionto access static members.");

            // TODO: Check the access flags.

            // Perform checks depending on the type of the member.
            if(member.IsVariable())
            {
                Variable variable = (Variable) member;
                if(!variable.IsField() && !variable.IsProperty())
                    Error(node, "expected field/property member.");

                IChelaType varType = variable.GetVariableType();
                if(varType.IsStructure())
                    varType = ReferenceType.Create(varType); // Required for nested access.
                node.SetNodeType(ReferenceType.Create(varType));
                node.SetNodeValue(variable);

                if(variable.IsField())
                {
                    FieldVariable field = (FieldVariable) variable;
                    node.SetSlot(field.GetSlot());
                }
            }
            else if(member.IsFunction())
            {
                Function function = (Function) member;
                if(!function.IsMethod())
                    Error(node, "expected a method member.");

                Method method = (Method) function;
                node.SetSlot(method.GetVSlot());
                node.SetNodeType(method.GetFunctionType());
                node.SetNodeValue(method);
            }
            else if(member.IsFunctionGroup())
            {
                FunctionGroup functionGroup = (FunctionGroup)member;
                FunctionGroupSelector selector = new FunctionGroupSelector(functionGroup);
                node.SetNodeType(ChelaType.GetFunctionGroupType());
                node.SetNodeValue(selector);
            }
            else
            {
                Error(node, "expected field or method member.");
            }

            return node;
        }