コード例 #1
0
ファイル: AttributeConstant.cs プロジェクト: ronsaldo/chela
 public AttributeConstant(Class attributeClass, Method attributeCtor)
 {
     this.attributeClass = attributeClass;
     this.attributeCtor = attributeCtor;
     this.ctorArguments = new List<ConstantValue> ();
     this.propertyValues = new List<PropertyValue> ();
 }
コード例 #2
0
ファイル: NewExpression.cs プロジェクト: ronsaldo/chela
 public NewExpression(Expression typeExpression, Expression arguments, TokenPosition position)
     : base(position)
 {
     this.typeExpression = typeExpression;
     this.arguments = arguments;
     this.constructor = null;
     this.objectType = null;
 }
コード例 #3
0
ファイル: StructDefinition.cs プロジェクト: ronsaldo/chela
        public StructDefinition(MemberFlags flags, string name,
                                GenericSignature genericSignature,
		                        AstNode bases, AstNode children,
                                TokenPosition position)
            : base(children, position)
        {
            SetName(name);
            this.flags = flags;
            this.bases = bases;
            this.genericSignature = genericSignature;
            this.defaultConstructor = null;
            this.genericScope = null;
        }
コード例 #4
0
ファイル: FunctionGenerator.cs プロジェクト: ronsaldo/chela
        private Method CreateTrivialConstructor(Structure building, Structure buildingInstance)
        {
            // Create the constructor function type.
            FunctionType type = FunctionType.Create(ChelaType.GetVoidType(),
                new IChelaType[]{ReferenceType.Create(buildingInstance)}, false);

            // Create the constructor.
            Method ctor = new Method(".ctor", MemberFlags.Public | MemberFlags.Constructor, building);
            ctor.SetFunctionType(type);
            building.AddFunction(".ctor", ctor);

            // Create the constructor block.
            BasicBlock top = new BasicBlock(ctor);
            top.SetName("top");
            top.Append(new Instruction(OpCode.RetVoid, null));

            return ctor;
        }
コード例 #5
0
ファイル: FunctionGenerator.cs プロジェクト: ronsaldo/chela
        private void CreateDefaultStaticConstructor(StructDefinition node)
        {
            // Get the structure.
            Structure building = node.GetStructure();

            // Check for an user defined constructor.
            if(building.GetStaticConstructor() != null)
                return;

            // Get the static initialization fields.
            List<FieldDeclaration> staticInitedField = new List<FieldDeclaration> ();
            bool isUnsafe = false;
            foreach(FieldDeclaration decl in building.GetFieldInitializations())
            {
                Variable variable = decl.GetVariable();
                if(variable.IsStatic())
                {
                    staticInitedField.Add(decl);
                    if(variable.IsUnsafe())
                        isUnsafe = true;
                }
            }

            // If there aren't field to initialize, don't create the static constructor.
            if(staticInitedField.Count == 0)
                return;

            // Begin the node.
            builder.BeginNode(node);

            // Create the static constructor function type.
            FunctionType ctorType = FunctionType.Create(ChelaType.GetVoidType());

            // Create the constructor method.
            MemberFlags flags = MemberFlags.StaticConstructor;
            if(isUnsafe)
                flags |= MemberFlags.Unsafe;
            Method constructor = new Method("<sctor>", flags, building);
            constructor.SetFunctionType(ctorType);

            // Store it.
            building.AddFunction("<sctor>", constructor);

            // Create the constructor scope.
            LexicalScope ctorScope = CreateLexicalScope(node, constructor);
            PushScope(ctorScope);

            // Create the top basic block.
            BasicBlock topBlock = new BasicBlock(constructor);
            builder.SetBlock(topBlock);

            // Initialize the static fields.
            GenerateStaticFieldInitializations(node, staticInitedField);

            // Restore the scope.
            PopScope();

            // Return void.
            builder.CreateRetVoid();

            // End the node.
            builder.EndNode();
        }
コード例 #6
0
ファイル: FunctionGenerator.cs プロジェクト: ronsaldo/chela
        private void CreateGenerator_Reset(FunctionDefinition node)
        {
            // Get the generator class.
            Class genClass = node.GeneratorClass;

            // Create the function type.
            FunctionType functionType =
                FunctionType.Create(ChelaType.GetVoidType(),
                    new IChelaType[]{ReferenceType.Create(node.GeneratorClassInstance)}, false);

            // Create the method.
            Method method = new Method("Reset", MemberFlags.Public, genClass);
            method.SetFunctionType(functionType);
            genClass.AddFunction("Reset", method);

            // Create the top block.
            BasicBlock top = new BasicBlock(method);
            builder.SetBlock(top);

            // Throw an exception.
            Class excpt = (Class)ExtractClass(node, currentModule.GetLangMember("InvalidOperationException"));
            builder.CreateLoadString("IEnumerator.Reset cannot be called in generators.");
            builder.CreateNewObject(excpt, GetExceptionCtor(node, excpt), 1);
            builder.CreateThrow();
        }
コード例 #7
0
ファイル: FunctionGenerator.cs プロジェクト: ronsaldo/chela
 private void CreateImplicitBaseConstructor(AstNode node, Method function)
 {
     Function parentConstructor = function.GetCtorParent();
     if(parentConstructor != null &&
        function.GetParentScope().IsStructure() == parentConstructor.GetParentScope().IsStructure())
     {
         builder.CreateLoadArg(0);
         builder.CreateCall(parentConstructor, 1);
     }
 }
コード例 #8
0
ファイル: FunctionGenerator.cs プロジェクト: ronsaldo/chela
        private void CreateGenerator_GetEnumerator(FunctionDefinition node, Structure enumeratorType, bool generic)
        {
            // Get the generator class.
            Class genClass = node.GeneratorClass;

            // Use the GetEnumerator name for the most specific version.
            string name = "GetEnumerator";
            Function contract = null;
            if(!generic && node.IsGenericIterator)
            {
                name = GenSym();
                contract = FindFirstConstract(currentModule.GetEnumerableIface(), "GetEnumerator");
            }

            // Create the function type.
            FunctionType functionType =
                FunctionType.Create(ReferenceType.Create(enumeratorType),
                    new IChelaType[]{ReferenceType.Create(node.GeneratorClassInstance)}, false);

            // Create the method.
            Method method = new Method(name, MemberFlags.Public, genClass);
            method.SetFunctionType(functionType);
            genClass.AddFunction(name, method);

            // Set the explicit contract.
            if(contract != null)
                method.SetExplicitContract(contract);

            // Create the method block.
            BasicBlock block = new BasicBlock(method);
            block.SetName("top");

            // Return this.
            builder.SetBlock(block);
            builder.CreateLoadArg(0);
            builder.CreateRet();
        }
コード例 #9
0
ファイル: FunctionGenerator.cs プロジェクト: ronsaldo/chela
        private Function CreateGenerator_MoveNext(FunctionDefinition node)
        {
            // Get the generator class.
            Class genClass = node.GeneratorClass;

            // Create the function type.
            FunctionType functionType =
                FunctionType.Create(ChelaType.GetBoolType(),
                    new IChelaType[]{ReferenceType.Create(node.GeneratorClassInstance)}, false);

            // Create the method.
            Method method = new Method("MoveNext", MemberFlags.Public, genClass);
            method.SetFunctionType(functionType);
            method.DefinitionNode = node;
            genClass.AddFunction("MoveNext", method);

            // Swap the exception contexts.
            method.SwapExceptionContexts(currentFunction);

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

            // Create the jump table block.
            BasicBlock jmpBlock = CreateBasicBlock();
            jmpBlock.SetName("jmp");

            // Generate the main code.
            BasicBlock topBlock = CreateBasicBlock();
            topBlock.SetName("top");
            builder.SetBlock(topBlock);

            // Prepare returning.
            LexicalScope topScope = (LexicalScope) node.GetScope();
            PrepareReturning(node, currentFunction, topScope);

            // Create the function body.
            VisitList(node.GetChildren());

            // Finish returning.
            FinishReturn(node, currentFunction);

            // Create the state jump table.
            builder.SetBlock(jmpBlock);

            // Load the current state.
            builder.CreateLoadArg(0);
            builder.CreateLoadField(node.GeneratorState);

            // Build the jump table.
            int numstates = node.Yields.Count*2+3;
            int[] stateConstants = new int[numstates];
            BasicBlock[] stateEntries = new BasicBlock[numstates];

            // The default case is return.
            stateConstants[0] = -1;
            stateEntries[0] = currentFunction.ReturnBlock;

            // The first state is the top block.
            stateConstants[1] = 0;
            stateEntries[1] = topBlock;

            // The second state is the return block.
            stateConstants[2] = 1;
            stateEntries[2] = currentFunction.ReturnBlock;

            // The next states are the yield merges followed by yield disposes.
            for(int i = 0; i < node.Yields.Count; ++i)
            {
                ReturnStatement yieldStmnt = node.Yields[i];

                // Emit the merge state.
                int stateId = i*2+2;
                int entryIndex = stateId+1;
                stateConstants[entryIndex] = stateId;
                stateEntries[entryIndex] = yieldStmnt.MergeBlock;

                // Emit the dispose state.
                stateConstants[entryIndex+1] = stateId+1;
                stateEntries[entryIndex+1] = yieldStmnt.DisposeBlock;
            }

            builder.CreateSwitch(stateConstants, stateEntries);

            // Restore the old function.
            currentFunction = oldFunction;

            return method;
        }
コード例 #10
0
ファイル: StructDefinition.cs プロジェクト: ronsaldo/chela
 public void SetDefaultConstructor(Method constructor)
 {
     defaultConstructor = constructor;
 }
コード例 #11
0
ファイル: FunctionSemantic.cs プロジェクト: ronsaldo/chela
        private void CheckDefaultConstructorInit(AstNode node, Method function)
        {
            // Get the base building.
            Structure building = (Structure)function.GetParentScope();
            Structure baseBuilding = building.GetBase();
            if(baseBuilding == null)
                return; // Object class.

            // Find a default construcotor.
            FunctionGroup ctorGroup = baseBuilding.GetConstructor();
            Method ctor = null;
            foreach(FunctionGroupName ctorName in ctorGroup.GetFunctions())
            {
                // Ignore static constructors.
                if(ctorName.IsStatic())
                    continue;

                // Check the constructor type.
                FunctionType ctorType = ctorName.GetFunctionType();
                if(ctorType.GetArgumentCount() == 1)
                {
                    // Found, the first argument must be "this".
                    ctor = (Method)ctorName.GetFunction();
                    break;
                }
            }

            // If not found, raise error.
            if(ctor == null)
                Error(node, baseBuilding.GetFullName() + " doesn't have a default constructor.");

            // Store the default constructor.
            function.SetCtorParent(ctor);
        }
コード例 #12
0
ファイル: ModuleInheritance.cs プロジェクト: ronsaldo/chela
        private void CreateDefaultConstructor(StructDefinition node)
        {
            // Get the structure.
            Structure building = node.GetStructure();

            // Check for an user defined constructor.
            if(building.GetConstructor() != null)
                return;

            // Instance the building.
            GenericPrototype contGenProto = building.GetGenericPrototype();
            int templateArgs = contGenProto.GetPlaceHolderCount();
            Structure buildingInstance = building;
            if(templateArgs != 0)
            {
                IChelaType[] thisArgs = new IChelaType[templateArgs];
                for(int i = 0; i < templateArgs; ++i)
                    thisArgs[i] = contGenProto.GetPlaceHolder(i);
                buildingInstance = (Structure)building.InstanceGeneric(
                    new GenericInstance(contGenProto, thisArgs), currentModule);
            }

            // Create the default constructor function type.
            List<IChelaType> arguments = new List<IChelaType> ();
            arguments.Add(ReferenceType.Create(buildingInstance));
            FunctionType ctorType = FunctionType.Create(ChelaType.GetVoidType(), arguments);

            // Create the constructor method.
            MemberFlags flags = MemberFlags.Public | MemberFlags.Constructor;
            Method constructor = new Method(building.GetName(), flags, building);
            constructor.SetFunctionType(ctorType);

            // Store it.
            building.AddFunction("<ctor>", constructor);
            node.SetDefaultConstructor(constructor);
        }
コード例 #13
0
ファイル: NewExpression.cs プロジェクト: ronsaldo/chela
 public void SetConstructor(Method method)
 {
     this.constructor = method;
 }
コード例 #14
0
        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;
        }
コード例 #15
0
        public override AstNode Visit(SetAccessorDefinition node)
        {
            PropertyVariable property = node.GetProperty();

            if(node.GetChildren() == null && property.SetAccessor != null)
                return node;

            if(node.GetChildren() != null && property.SetAccessor != null)
                Error(node, "multiples definitions of the set accessor.");

            // Build the property flags.
            MemberFlags flags = node.GetFlags();
            if(flags == MemberFlags.ImplicitVis)
            {
                flags = property.GetFlags();
            }
            else
            {
                // TODO: Check compatibility.
                flags |= property.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 properties cannot have a definition body.");

            // Create the set accesor.
            if(property.SetAccessor == null)
            {
                // 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 parameter.
                        selfType = ReferenceType.Create(building);
                        arguments.Add(selfType);
                    }
                }

                // Append the indices.
                foreach(IChelaType indexType in property.Indices)
                    arguments.Add(indexType);

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

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

                // Create the function.
                Function accessor;
                if(selfType != null)
                    accessor = new Method("set_" + property.GetName(), flags, currentContainer);
                else
                    accessor = new Function("set_" + property.GetName(), flags, currentContainer);

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

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

                // Store the function in the property.
                property.SetAccessor = accessor;

                // Store the function in his scope.
                if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface())
                {
                    Structure building = (Structure)currentContainer;
                    building.AddFunction("set_" + property.GetName(), accessor);
                }
                else if(currentContainer.IsNamespace())
                {
                    Namespace space = (Namespace)currentContainer;
                    space.AddMember(accessor);
                }
                else
                {
                    Error(node, "a property 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, property.GetVariableType());
                    node.SetValueLocal(valueVar);

                    // Add the indices variables.
                    AstNode index = node.GetIndices();
                    List<LocalVariable> indexerVars = new List<LocalVariable> ();
                    while(index != null)
                    {
                        // Create the local
                        LocalVariable local = new LocalVariable(index.GetName(), scope, index.GetNodeType());
                        indexerVars.Add(local);

                        // Process the next.
                        index = index.GetNext();
                    }
                    node.SetIndexerVariables(indexerVars);
                    node.SetScope(scope);
                }
            }
            else
            {
                // Check for declaration compatibility.
                if(flags != property.SetAccessor.GetFlags())
                    Error(node, "incompatible set accessor declarations.");
            }

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

            return node;
        }
コード例 #16
0
        public override AstNode Visit(FunctionPrototype node)
        {
            MemberFlags callingConvention = node.GetFlags() & MemberFlags.LanguageMask;
            bool isCdecl = callingConvention == MemberFlags.Cdecl;
            bool isUnsafe = (node.GetFlags() & MemberFlags.SecurityMask) == MemberFlags.Unsafe;

            // Use the unsafe scope.
            if(isUnsafe)
                PushUnsafe();

            // Generate a name for explicit contracts.
            if(node.GetNameExpression() != null)
                node.SetName(GenSym());

            // Find an existing group.
            ScopeMember oldGroup = currentContainer.FindMember(node.GetName());
            if(oldGroup != null && (oldGroup.IsType() || !oldGroup.IsFunctionGroup()))
            {
                if(oldGroup.IsFunction() && isCdecl)
                {
                    // TODO: Add additional checks.
                    Function oldDefinition = (Function)oldGroup;
                    node.SetFunction(oldDefinition);
                    node.SetNodeType(oldDefinition.GetFunctionType());
                    oldGroup = null;
                    return node;
                }
                else
                    Error(node, "cannot override something without a function group.");
            }

            FunctionGroup functionGroup = null;
            if(oldGroup != null) // Cast the group member.
                functionGroup = (FunctionGroup)oldGroup;

            // Make sure the destructor name is correct.
            if(node.GetDestructorName() != null)
            {
                // Get the building scope.
                Scope buildingScope = currentScope;
                while(buildingScope != null && (buildingScope.IsFunction() || buildingScope.IsPseudoScope() || buildingScope.IsLexicalScope()))
                    buildingScope = buildingScope.GetParentScope();

                // Make sure we are in a class.
                if(buildingScope == null || !buildingScope.IsClass())
                    Error(node, "only classes can have finalizers.");

                // Make sure the destructor and class name are the same.
                if(node.GetDestructorName() != buildingScope.GetName())
                    Error(node, "finalizers must have the same name as their class.");
            }

            // Read the instance flag.
            MemberFlags instanceFlags = node.GetFlags() & MemberFlags.InstanceMask;

            // Don't allow overloading with cdecl.
            if(isCdecl && functionGroup != null)
                Error(node, "overloading and cdecl are incompatible.");

            // Make sure static constructor doesn't have modifiers.
            if(instanceFlags == MemberFlags.StaticConstructor &&
               node.GetFlags() != MemberFlags.StaticConstructor)
                Error(node, "static constructors cannot have modifiers.");

            // Static constructors cannot have paraemeters.
            if(instanceFlags == MemberFlags.StaticConstructor &&
               node.GetArguments() != null)
                Error(node, "static constructors cannot have parameters.");

            // Add the this argument.
            if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface())
            {
                // Cast the scope.
                Structure building = (Structure)currentContainer;

                // Add the this argument.
                if(instanceFlags != MemberFlags.Static &&
                   instanceFlags != MemberFlags.StaticConstructor)
                {
                    // Instance the building.
                    building = building.GetSelfInstance();

                    // Use the structure type.
                    TypeNode thisType = new TypeNode(TypeKind.Reference, node.GetPosition());
                    thisType.SetOtherType(building);

                    // Create the this argument.
                    FunctionArgument thisArg = new FunctionArgument(thisType, "this",
                                                                    node.GetPosition());

                    // Add to the begin of the argument list.
                    thisArg.SetNext(node.GetArguments());
                    node.SetArguments(thisArg);
                }
            }

            // Parse the generic signature.
            GenericSignature genericSign = node.GetGenericSignature();
            GenericPrototype genProto = null;
            PseudoScope protoScope = null;
            if(genericSign != null)
            {
                // Visit the generic signature.
                genericSign.Accept(this);

                // Create the placeholders scope.
                genProto = genericSign.GetPrototype();
                protoScope = new PseudoScope(currentScope, genProto);
                node.SetScope(protoScope);
            }

            // Use the prototype scope.
            if(protoScope != null)
                PushScope(protoScope);

            // Visit the arguments.
            VisitList(node.GetArguments());

            // Visit the return type.
            Expression returnTypeExpr = node.GetReturnType();
            IChelaType returnType;
            if(returnTypeExpr != null)
            {
                // Don't allow the same name as the container.
                if((currentContainer.IsStructure() || currentContainer.IsClass() ||
                   currentContainer.IsInterface()) &&
                   node.GetName() == currentContainer.GetName())
                    Error(node, "constructors cannot have a return type.");

                returnTypeExpr.Accept(this);
                returnType = returnTypeExpr.GetNodeType();
                returnType = ExtractActualType(returnTypeExpr, returnType);

                // Use references for class/interface.
                if(returnType.IsPassedByReference())
                    returnType = ReferenceType.Create(returnType);
            }
            else if(node.GetDestructorName() != null)
            {
                returnType = ChelaType.GetVoidType();
            }
            else
            {
                returnType = ChelaType.GetVoidType();
                if(!currentContainer.IsStructure() && !currentContainer.IsClass())
                    Error(node, "only classes and structures can have constructors.");

                if(node.GetName() != currentContainer.GetName())
                    Error(node, "constructors must have the same name as their parent.");
            }

            // Restore the prototype scope.
            if(protoScope != null)
                PopScope();

            // Create his function type.
            List<IChelaType> arguments = new List<IChelaType> ();
            bool variableArgs = false;

            // Add the argument types.
            AstNode argNode = node.GetArguments();
            while(argNode != null)
            {
                // Cast the argument node.
                FunctionArgument funArg = (FunctionArgument)argNode;

                // Store the argument type.
                arguments.Add(funArg.GetNodeType());

                // Set the variable argument flags.
                variableArgs = funArg.IsParams();

                // Check the next argument.
                argNode = argNode.GetNext();
            }

            // Set the function type.
            FunctionType type = FunctionType.Create(returnType, arguments,
                                                    variableArgs, callingConvention);
            node.SetNodeType(type);

            // Check the function safetyness.
            if(type.IsUnsafe())
                UnsafeError(node, "safe function with unsafe type.");

            // Avoid collisions.
            if(functionGroup != null)
            {
                Function ambiguos = functionGroup.Find(type, instanceFlags == MemberFlags.Static);
                if(ambiguos != null)
                    Error(node, "adding ambiguous overload for " + ambiguos.GetFullName());
            }

            // Create and add the method into his scope.
            Function function = null;
            if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface())
            {
                // Cast the scope.
                Structure building = (Structure) currentContainer;

                // Create the function according to his instance type.
                if(instanceFlags == MemberFlags.Static ||
                   instanceFlags == MemberFlags.StaticConstructor)
                {
                    function = new Function(node.GetName(), node.GetFlags(), currentContainer);
                }
                else
                {
                    Method method = new Method(node.GetName(), node.GetFlags(), currentContainer);
                    function = method;

                    // Check the constructor initializer.
                    ConstructorInitializer ctorInit = node.GetConstructorInitializer();
                    if(ctorInit == null || ctorInit.IsBaseCall())
                        method.SetCtorLeaf(true);
                }

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

                // Set the function type.
                function.SetFunctionType(type);

                // Add the function.
                try
                {
                    building.AddFunction(node.GetName(), function);
                }
                catch(ModuleException error)
                {
                    Error(node, error.Message);
                }
            }
            else if(currentContainer.IsNamespace())
            {
                // Create the function.
                function = new Function(node.GetName(), node.GetFlags(), currentContainer);
                function.SetFunctionType(type);

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

                // Add the method into his namespace.
                Namespace space = (Namespace) currentContainer;

                // Create the function group.
                if(functionGroup == null && !isCdecl)
                {
                    functionGroup = new FunctionGroup(node.GetName(), currentContainer);
                    oldGroup = functionGroup;
                    space.AddMember(functionGroup);
                }

                // Add the function into the function group or the namespace.
                if(!isCdecl)
                    functionGroup.Insert(function);
                else
                    space.AddMember(function);
            }
            else
            {
                Error(node, "a function cannot be added here.");
            }

            // Store the generic prototype.
            if(genProto != null)
                function.SetGenericPrototype(genProto);

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

            // Check for main function.
            if(function.IsStatic() && function.GetName() == "Main")
                CheckMainCandidate(node, function);

            // Create kernel entry point.
            if(function.IsKernel())
                CreateKernelEntryPoint(node, function);

            // Restore the safety scope.
            if(isUnsafe)
                PopUnsafe();

            return node;
        }
コード例 #17
0
        public override AstNode Visit(DelegateDefinition node)
        {
            // Check the security.
            bool isUnsafe = (node.GetFlags() & MemberFlags.SecurityMask) == MemberFlags.Unsafe;
            if(isUnsafe)
                PushUnsafe();

            // Get the delegate building.
            Structure building = node.GetStructure();

            // Use the generic prototype.
            // Use the generic scope.
            PseudoScope genScope = node.GetGenericScope();
            if(genScope != null)
                PushScope(genScope);

            // Visit the argument list.
            VisitList(node.GetArguments());

            // Visit the return type.
            Expression returnTypeExpr = node.GetReturnType();
            returnTypeExpr.Accept(this);

            IChelaType returnType = returnTypeExpr.GetNodeType();
            returnType = ExtractActualType(returnTypeExpr, returnType);

            // Use references for class/interface.
            if(returnType.IsPassedByReference())
                returnType = ReferenceType.Create(returnType);

            // Create the invoke function type.
            List<IChelaType> arguments = new List<IChelaType> ();

            // Add the argument types.
            AstNode argNode = node.GetArguments();
            while(argNode != null)
            {
                arguments.Add(argNode.GetNodeType());
                argNode = argNode.GetNext();
            }

            // Create the function type.
            FunctionType functionType = FunctionType.Create(returnType, arguments);

            // Check the type security.
            if(functionType.IsUnsafe())
                UnsafeError(node, "safe delegate with unsafe type.");

            // Create the invoke type.
            List<IChelaType> invokeArguments = new List<IChelaType> ();
            invokeArguments.Add(ReferenceType.Create(building));
            for(int i = 0; i < arguments.Count; ++i)
                invokeArguments.Add(arguments[i]);
            FunctionType invokeType = FunctionType.Create(returnType, invokeArguments);

            // Create the constructor type.
            List<IChelaType> ctorArguments = new List<IChelaType> ();
            ctorArguments.Add(ReferenceType.Create(building));
            ctorArguments.Add(ReferenceType.Create(currentModule.TypeMap(ChelaType.GetObjectType())));
            ctorArguments.Add(ReferenceType.Create(functionType));
            FunctionType ctorType = FunctionType.Create(ChelaType.GetVoidType(), ctorArguments);

            // Create the constructor method.
            Method ctorMethod = new Method("<ctor>", MemberFlags.Public | MemberFlags.Runtime | MemberFlags.Constructor, building);
            ctorMethod.SetFunctionType(ctorType);
            building.AddFunction("<ctor>", ctorMethod);

            // Create the invoke function.
            Method invokeMethod = new Method("Invoke", MemberFlags.Public | MemberFlags.Runtime, building);
            invokeMethod.SetFunctionType(invokeType);
            building.AddFunction("Invoke", invokeMethod);

            // Restore the scope.
            if(genScope != null)
                PopScope();

            // Restore the security level.
            if(isUnsafe)
                PushUnsafe();

            return node;
        }
コード例 #18
0
        private void CreateSimplifiedEventFunction(AstNode node, EventVariable eventVariable, FunctionType functionType, bool isAdd)
        {
            // Create the function name.
            string functionName = (isAdd ? "add_" : "remove_") + eventVariable.GetName();

            // Create the function.
            Function function;
            if(functionType.GetArgumentCount() > 1)
                function = new Method(functionName, eventVariable.GetFlags(), currentContainer);
            else
                function = new Function(functionName, eventVariable.GetFlags(), currentContainer);

            // Set the function type.
            function.SetFunctionType(functionType);

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

            // Store the function in the event.
            if(isAdd)
                eventVariable.AddModifier = function;
            else
                eventVariable.RemoveModifier = function;

            // Store the function in his container.
            if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface())
            {
                Structure building = (Structure)currentContainer;
                building.AddFunction(functionName, function);
            }
            else if(currentContainer.IsNamespace())
            {
                Namespace space = (Namespace)currentContainer;
                space.AddMember(function);
            }
            else
            {
                Error(node, "an event cannot be declared here.");
            }
        }
コード例 #19
0
ファイル: FunctionGenerator.cs プロジェクト: ronsaldo/chela
        private void CreateGenerator_Current(FunctionDefinition node, bool generic)
        {
            // Get the generator class.
            Class genClass = node.GeneratorClass;

            // Use the get_Current name for the most specific version.
            string name = "get_Current";
            Function contract = null;
            if(!generic && node.IsGenericIterator)
            {
                name = GenSym();
                contract = FindFirstConstract(currentModule.GetEnumeratorIface(), "get_Current");
            }

            // Select the current type.
            IChelaType currentType = node.YieldType;
            if(!generic)
                currentType = ReferenceType.Create(currentModule.GetObjectClass());

            // Create the function type.
            FunctionType functionType =
                FunctionType.Create(currentType,
                    new IChelaType[]{ReferenceType.Create(node.GeneratorClassInstance)}, false);

            // Create the method.
            Method method = new Method(name, MemberFlags.Public, genClass);
            method.SetFunctionType(functionType);
            genClass.AddFunction(name, method);

            // Set the explicit contract.
            if(contract != null)
                method.SetExplicitContract(contract);

            // Create the method block.
            BasicBlock block = new BasicBlock(method);
            block.SetName("top");

            // Create the return and error blocks.
            BasicBlock retBlock = new BasicBlock(method);
            retBlock.SetName("ret");

            BasicBlock errorBlock = new BasicBlock(method);
            errorBlock.SetName("error");

            // Make sure reset was called before the first Current.
            builder.SetBlock(block);
            builder.CreateLoadArg(0);
            builder.CreateLoadField(node.GeneratorState);
            builder.CreateLoadInt32(0);
            builder.CreateCmpEQ();
            builder.CreateBr(errorBlock, retBlock);

            // Raise an error if reset wasn't called.
            builder.SetBlock(errorBlock);

            Class excpt = (Class)ExtractClass(node, currentModule.GetLangMember("InvalidOperationException"));
            builder.CreateLoadString("IEnumerator.MoveNext must be called before than IEnumerator.Current.");
            builder.CreateNewObject(excpt, GetExceptionCtor(node, excpt), 1);
            builder.CreateThrow();

            // Load the yielded value.
            builder.SetBlock(retBlock);
            builder.CreateLoadArg(0);
            builder.CreateLoadField(node.YieldedValue);

            // Cast the yielded value.
            Cast(node, null, node.YieldType, currentType);

            // Return.
            builder.CreateRet();
        }
コード例 #20
0
ファイル: FunctionGenerator.cs プロジェクト: ronsaldo/chela
        private void CreateGenerator_Dispose(FunctionDefinition node, Function moveNext)
        {
            // Get the generator class.
            Class genClass = node.GeneratorClass;

            // Create the function type.
            FunctionType functionType =
                FunctionType.Create(ChelaType.GetVoidType(),
                    new IChelaType[]{ReferenceType.Create(node.GeneratorClassInstance)}, false);

            // Create the method.
            Method method = new Method("Dispose", MemberFlags.Public, genClass);
            method.SetFunctionType(functionType);
            genClass.AddFunction("Dispose", method);

            // Create the top block.
            BasicBlock top = new BasicBlock(method);
            builder.SetBlock(top);

            // Create the return and dispose blocks.
            BasicBlock justReturn = new BasicBlock(method);
            BasicBlock disposeAndReturn = new BasicBlock(method);

            // Load the current state.
            builder.CreateLoadArg(0);
            builder.CreateDup1();
            builder.CreateDup1();
            builder.CreateLoadField(node.GeneratorState);
            builder.CreateDup1();
            builder.CreateLoadInt32(1);
            builder.CreateCmpEQ();
            builder.CreateBr(justReturn, disposeAndReturn);

            // Dispose and return implementation.
            builder.SetBlock(disposeAndReturn);

            // Increase the state.
            builder.CreateLoadInt32(1);
            builder.CreateAdd();
            builder.CreateStoreField(node.GeneratorState);

            // Call move next.
            builder.CreateCall(moveNext, 1);
            builder.CreateRetVoid();

            // Just return implementation.
            builder.SetBlock(justReturn);
            builder.CreateRetVoid();
        }
コード例 #21
0
ファイル: AttributeInstance.cs プロジェクト: ronsaldo/chela
 public void SetAttributeConstructor(Method attributeConstructor)
 {
     this.attributeConstructor = attributeConstructor;
 }
コード例 #22
0
ファイル: FunctionSemantic.cs プロジェクト: ronsaldo/chela
        private void CheckConstructorCycles(AstNode node, Method ctor)
        {
            Method current = ctor.GetCtorParent();
            while(current != null)
            {
                // Don't continue checking when hitting a leaf.
                if(current.IsCtorLeaf())
                    return;

                // If the parent is equal to the start point,
                // a cycle has been found.
                if(current == ctor)
                    Error(node, "constructor initializers produces a cycle.");

                // Check the next parent.
                current = current.GetCtorParent();
            }
        }