예제 #1
0
        private MidMemberDecl EmitMemberDeclImpl(
            MidModuleDecl midModule,
            IResPipelineDecl resPipeline,
            MidEmitEnv outerEnv)
        {
            var midPipeline = new MidPipelineDecl(
                midModule,
                resPipeline.Name,
                this,
                outerEnv,
                resPipeline.Range);

            midPipeline.IsAbstract = (resPipeline.ConcretenessMode == ResMemberConcretenessMode.Abstract);
            midPipeline.IsPrimary  = (resPipeline.MixinMode == ResMixinMode.Primary);

            MidEmitEnv env = new MidGlobalEmitEnv(outerEnv, outerEnv.Context);

            env.Insert(
                resPipeline.ThisParameter,
                (SourceRange r) =>
                new MidLit <object>(r, null, new MidPipelineRef(midPipeline, null)));
            midPipeline.Env = env;

            midPipeline.AddBuildAction(() =>
            {
                foreach (var resFacet in resPipeline.Facets)
                {
                    var originalPipeline = (MidPipelineRef)EmitMemberTerm(
                        resFacet.OriginalPipeline.MemberTerm,
                        env);
                    var midFacet = midPipeline.AddFacet(
                        originalPipeline);

                    foreach (var resLine in resFacet.MemberLines)
                    {
                        var resDecl = resLine.EffectiveDecl;
                        var midDecl = EmitMemberDecl(midFacet, resDecl, env);
                        midPipeline.InsertMemberDecl(resDecl, midDecl);
                    }
                    midFacet.DoneBuilding();
                }
            });
            midPipeline.DoneBuilding();

            midModule.AddPipeline(midPipeline);
            midModule.InsertMemberDecl(resPipeline, midPipeline);
            return(midPipeline);
        }
예제 #2
0
        public IMidMemberRef SpecializeGenericDecl(
            MidGenericDecl genericDecl,
            IEnumerable <object> args)
        {
            var resGeneric = genericDecl.ResDecl;
            var env        = new MidGlobalEmitEnv(genericDecl.Env, genericDecl.Env.Context);

            foreach (var p in args.Zip(resGeneric.Parameters, Tuple.Create))
            {
                env.Insert(p.Item2, p.Item1);
            }

            var builder = new Builder(null);
            var midDecl = EmitMemberDecl(
                builder,
                resGeneric.InnerDecl,
                env);

            builder.DoneBuilding();
            builder.ForceDeep();

            return(midDecl.CreateRef(null));
        }
예제 #3
0
        private MidMemberDecl EmitMemberDeclImpl(
            IBuilder parent,
            IResMethodDecl resMethod,
            MidEmitEnv env)
        {
            var builtinTags = (from tag in resMethod.Line.Tags
                               let builtinTag = tag as ResBuiltinTag
                                                where builtinTag != null
                                                select builtinTag).ToArray();

            if (resMethod.Body != null)
            {
                // Don't use builtin version if there's an inline impl (probably
                // because its an override...)
                builtinTags = new ResBuiltinTag[] { };
            }


            IMidMethodDecl midMethod = null;

            if (builtinTags.Length != 0)
            {
                midMethod = new MidBuiltinMethodDecl(
                    parent,
                    resMethod.Name,
                    builtinTags);
            }
            else
            {
                midMethod = new MidMethodDecl(
                    parent,
                    resMethod.Name,
                    _exps);
            }

            midMethod.AddBuildAction(() =>
            {
                var resultType = EmitTypeExp(resMethod.ResultType, env);

                midMethod.ResultType = resultType;

                var midParams = (from p in resMethod.Parameters
                                 select new MidVar(p.Name, EmitTypeExp(p.Type, env))).ToArray();

                midMethod.Parameters = midParams;

                if (resMethod.Body != null && !IsCrossFrequencyMethod(resMethod))
                {
                    var paramEnv = new MidGlobalEmitEnv(env, env.Context);
                    foreach (var pair in midParams.Zip(resMethod.Parameters, Tuple.Create))
                    {
                        var midParam = pair.Item1;
                        var resParam = pair.Item2;

                        paramEnv.Insert(resParam, (SourceRange r) => new MidVarRef(r, midParam));
                    }

                    ((MidMethodDecl)midMethod).Body = EmitLocalExp(resMethod.Body, paramEnv);
                }
            });
            midMethod.DoneBuilding();

            if ((parent is MidFacetDecl) && (midMethod is MidMethodDecl))
            {
                ((MidFacetDecl)parent).AddMethod((MidMethodDecl)midMethod);
            }
            return((MidMemberDecl)midMethod);
        }