コード例 #1
0
        public static void Bind(BindingContext context, Function function)
        {
            if (function.Type.Return == null) throw new InvalidOperationException("Can only bind functions whose type is already bound.");

            var scope = new Scope();

            // create a local slot for the arg if there is one
            if (function.Type.Parameter.Unbound != Decl.Unit)
            {
                scope.Define(context.NameGenerator.Generate(), Decl.Unit /* ignored */, false);
            }

            var binder = new FunctionBinder(function, context, scope);

            // bind the function
            function.Bind(context, binder);

            // make sure declared return type matches actual return type
            if (!DeclComparer.TypesMatch(function.Type.Return.Bound, function.Body.Bound.Type))
            {
                if (function.Body.Bound.Type == Decl.EarlyReturn)
                {
                    //### bob: should find the return expr
                    throw new CompileException(function.Position, "Unneeded explicit \"return\".");
                }
                else
                {
                    throw new CompileException(function.Position, String.Format("{0} is declared to return {1} but is returning {2}.",
                        function.Name, function.Type.Return.Bound, function.Body.Bound.Type));
                }
            }
        }
コード例 #2
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);
        }
コード例 #3
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);
            }
        }
コード例 #4
0
ファイル: Function.cs プロジェクト: stjordanis/magpie-csharp
 public void Bind(BindingContext context, FunctionBinder binder)
 {
     Body.Bind(context, binder);
     NumLocals = binder.Scope.NumVariables;
 }