Exemplo n.º 1
0
        public ICallable Instantiate(BindingContext context, IEnumerable <IBoundDecl> typeArgs,
                                     IBoundDecl argType)
        {
            bool canInfer;
            var  genericContext = BuildContext(context,
                                               BaseType.Type.Parameter.Unbound,
                                               argType, ref typeArgs, out canInfer);

            // bail if we couldn't get the right number of type arguments
            if ((typeArgs == null) || (TypeParameters.Count != typeArgs.Count()))
            {
                return(null);
            }

            // create a new bound function type with the type arguments applied
            FuncType funcType = BaseType.Type.CloneFunc();

            TypeBinder.Bind(genericContext, funcType);

            // make sure the concrete argument types of this instance match what we're actually given
            if (!DeclComparer.TypesMatch(funcType.Parameter.Bound, argType))
            {
                return(null);
            }

            // create a new unbound function with the proper type
            Function instance = new Function(BaseType.Position, BaseType.BaseName,
                                             funcType, BaseType.ParamNames, BaseType.Body.Unbound, typeArgs, canInfer);

            instance.BindSearchSpace(BaseType.SearchSpace);

            // don't instantiate it multiple times
            // note that this must happen *before* the function is bound, in case the
            // newly instantiated generic function is recursive.
            context.Compiler.Functions.Add(instance);

            // bind it with the type arguments in context
            FunctionBinder.Bind(genericContext, instance);

            return(instance);
        }
Exemplo n.º 2
0
        public void BindAll()
        {
            // bind the types of the user functions and add them to the main table
            foreach (var unbound in mUnbound)
            {
                Bind(unbound);
            }

            // copy the functions to a queue because binding a function may cause generics
            // to be instantiated, adding to the collection.
            // (we don't need to worry about binding the newly added generics, because they
            // are bound as part of the instantiation process. binding is how the compiler
            // determines if a generic's type arguments are valid.)
            mToBind = new Queue <Function>(Functions);

            // bind the bodies of all of the functions
            while (mToBind.Count > 0)
            {
                var function = mToBind.Dequeue();
                var context  = new BindingContext(mCompiler, function.SearchSpace);
                FunctionBinder.Bind(context, function);
            }
        }