public override AstNode Visit(EventAccessorDefinition node)
        {
            EventVariable eventVariable = node.GetEvent();

            // Build the event flags.
            MemberFlags flags = node.GetFlags();
            if(flags == MemberFlags.ImplicitVis)
            {
                flags = eventVariable.GetFlags();
            }
            else
            {
                // TODO: Check compatibility.
                flags |= eventVariable.GetFlags() & ~MemberFlags.VisibilityMask;
            }

            // Get the instance type.
            MemberFlags instanceFlags = MemberFlags.InstanceMask & flags;

            // Abstract properties cannot have a body.
            if((instanceFlags == MemberFlags.Abstract ||
               instanceFlags == MemberFlags.Contract) && node.GetChildren() != null)
                Error(node, "abstract events cannot have a definition body.");

            // Create the argument list.
            List<IChelaType> arguments = new List<IChelaType> ();

            // Add the this argument.
            IChelaType selfType = null;
            if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface())
            {
                Structure building = (Structure) currentContainer;
                if(instanceFlags != MemberFlags.Static)
                {
                    // Instance the building.
                    building = building.GetSelfInstance();

                    // Create the self argument.
                    selfType = ReferenceType.Create(building);
                    arguments.Add(selfType);
                }
            }

            // Add the value argument.
            arguments.Add(eventVariable.GetVariableType());

            // Create the function type.
            FunctionType functionType = FunctionType.Create(ChelaType.GetVoidType(), arguments, false);

            // Build the function name.
            string functionName = node.GetName() + "_" + eventVariable.GetName();

            // Create the function.
            Function accessor;
            if(selfType != null)
                accessor = new Method(functionName, flags, currentContainer);
            else
                accessor = new Function(functionName, flags, currentContainer);

            // Set the arguments.
            accessor.SetFunctionType(functionType);

            // Set the function position.
            accessor.Position = node.GetPosition();

            // Store the function in the event.
            if(node.GetName() == "add")
                eventVariable.AddModifier = accessor;
            else
                eventVariable.RemoveModifier = accessor;

            // Store the function in his scope.
            if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface())
            {
                Structure building = (Structure)currentContainer;
                building.AddFunction(functionName, accessor);
            }
            else if(currentContainer.IsNamespace())
            {
                Namespace space = (Namespace)currentContainer;
                space.AddMember(accessor);
            }
            else
            {
                Error(node, "an event cannot be declared here.");
            }

            // If there's a body, declare the "argument" variables.
            if(node.GetChildren() != null)
            {
                LexicalScope scope = CreateLexicalScope(node, accessor);

                // Add the "this" local.
                if(selfType != null)
                    new ArgumentVariable(0, "this", scope, selfType);

                // Add the "value" local
                LocalVariable valueVar = new LocalVariable("value", scope, eventVariable.GetVariableType());
                node.SetValueLocal(valueVar);

                // Store the scope
                node.SetScope(scope);
            }

            // Set the node function to the accessor.
            node.SetFunction(accessor);

            return node;
        }
Beispiel #2
0
        public override AstNode Visit(EventAccessorDefinition node)
        {
            // Begin the node.
            builder.BeginNode(node);

            // Get the function.
            Function function = node.GetFunction();

            // Ignore declarations.
            if(node.GetChildren() == null)
                return builder.EndNode();

            // Store the old function.
            Function oldFunction = currentFunction;
            currentFunction = function;

            // Get the function lexical scope.
            LexicalScope topScope = (LexicalScope)node.GetScope();
            PushScope(topScope);

            // Create the top basic block.
            BasicBlock topBlock = CreateBasicBlock();
            topBlock.SetName("top");
            builder.SetBlock(topBlock);

            // Prepare returning, required by exception handling.
            PrepareReturning(node, function, topScope);

            // Store the "value" argument in a local variable.
            int index = function.IsStatic() ? 0 : 1;
            LocalVariable valueLocal = node.GetValueLocal();
            builder.CreateLoadArg((byte)index++);
            builder.CreateStoreLocal(valueLocal);

            // Visit his children.
            VisitList(node.GetChildren());

            // Finish return.
            FinishReturn(node, function);

            // Restore the scope.
            PopScope();

            // Restore the current function.
            currentFunction = oldFunction;

            return builder.EndNode();
        }
Beispiel #3
0
        public override AstNode Visit(EventAccessorDefinition node)
        {
            // Get the function.
            Function function = node.GetFunction();
            if(node.GetChildren() == null)
                return node;

            // Store the old function.
            Function oldFunction = currentFunction;
            currentFunction = function;

            // Update the scope.
            PushScope(node.GetScope());

            // Visit his children.
            VisitList(node.GetChildren());

            // Restore the scope.
            PopScope();

            // Restore the current function.
            currentFunction = oldFunction;

            return node;
        }