Example #1
0
        public override AstNode Visit(AddressOfOperation node)
        {
            // Begin the node.
            builder.BeginNode(node);

            // Functions are statically handler.
            if(node.IsFunction())
            {
                builder.CreateLoadFunctionAddr((Function)node.GetNodeValue());
                return builder.EndNode();
            }

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

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

            // Get the reference variable.
            Variable variable = (Variable) reference.GetNodeValue();
            if(variable.IsLocal())
            {
                LocalVariable local = (LocalVariable) variable;
                if(local.IsPseudoLocal)
                {
                    builder.CreateLoadArg(0);
                    builder.CreateLoadFieldAddr((FieldVariable)local.ActualVariable);
                }
                else
                {
                    builder.CreateLoadLocalAddr(local);
                }
            }
            else if(variable.IsField())
            {
                FieldVariable field = (FieldVariable) variable;
                if(field.IsStatic())
                    builder.CreateLoadGlobalAddr(field);
                else
                    builder.CreateLoadFieldAddr(field);
            }
            else if(variable.IsArraySlot())
            {
                ArraySlot slot = (ArraySlot)variable;
                builder.CreateLoadArraySlotAddr(slot.GetArrayType());
            }
            else if(variable.IsPointedSlot())
            {
                // Do nothing.
            }
            else if(variable.IsReferencedSlot())
            {
                builder.CreateBitCast(node.GetNodeType());
            }
            else if(variable.IsProperty())
            {
                Error(node, "cannot use address-of operator for properties.");
            }

            return builder.EndNode();
        }
Example #2
0
        public override AstNode Visit(AddressOfOperation node)
        {
            UnsafeError(node, "cannot use address-of operator under safe contexts.");

            // Evaluate the base reference.
            Expression reference = node.GetReference();
            reference.Accept(this);

            // Get the reference type.
            IChelaType refType = reference.GetNodeType();
            if(!refType.IsReference() && !refType.IsFunctionGroup())
                Error(node, "expected a reference/function.");

            // Handle function groups.
            if(refType.IsFunctionGroup())
            {
                // Only accept groups with only one function.
                FunctionGroupSelector selector = (FunctionGroupSelector)reference.GetNodeValue();
                FunctionGroup fgroup = selector.GetFunctionGroup();
                if(fgroup.GetFunctionCount() != 1)
                    Error(node, "cannot get the address of a function grop.");

                // Extract the single function in the group.
                Function function = null;
                foreach(FunctionGroupName name in fgroup.GetFunctions())
                    function = name.GetFunction();

                // Make sure its static.
                if(!function.IsStatic())
                    Error(node, "cannot get the addres of a no-static function.");

                // Store it in the node.
                node.SetNodeValue(function);
                node.SetIsFunction(true);

                // Set the node type.
                node.SetNodeType(PointerType.Create(function.GetFunctionType()));

                return node;
            }

            node.SetCoercionType(refType);

            // De-Reference.
            refType = DeReferenceType(refType);
            if(refType.IsReference() || refType.IsPassedByReference())
                Error(node, "cannot use address of operator for managed objects.");

            // Create the pointer type.
            IChelaType pointerType = PointerType.Create(refType);
            node.SetNodeType(pointerType);

            return node;
        }