public CilDocumentSyntax Build(ILogging logging, CilDocumentSyntax context)
        {
            if (data == null)
            {
                logging.Write(
                    new LogEntry
                {
                    Severity = Severity.Error,
                    Message  = string.Format(
                        "Failed to compile '{0}' language definition.",
                        languageName.FullLanguageName),
                    Origin = languageName.Origin
                });

                return(null);
            }

            this.logging = logging;

            this.declaringTypeRef = context.Types.Class_(
                ClassName.Parse(languageName.LanguageTypeName));

            logging.Write(
                new LogEntry
            {
                Severity = Severity.Verbose,
                Message  = string.Format("Started Compiling Derived assembly for {0}", languageName.FullLanguageName)
            });

            var result = context
                         .Class_()
                         .Public
                         .Named(languageName.LanguageTypeName)
                         .Extends(context.Types.Import(typeof(LanguageBase)))
                         .Do(BuildMethod_CreateGrammar)
                         .Do(BuildMethod_GetParserAction)
                         .Do(BuildMethod_CreateTokenIdentities)
                         .Do(BuildMethod_Scan1)
                         .Do(BuildMethod_TermFactory)
                         .Do(BuildMethod_GrammarAction)
                         .Do(BuildMethod_MergeAction)
                         .Do(BuildMethod_CreateStateToSymbol)
                         .Do(BuildMethod_CreateParserActionConflicts)
                         .Do(BuildMethod_CreateTokenComplexityTable)
                         .Do(BuildMethod_CreateDefaultContext)
                         .Do(Build_Ctor)
                         .EndClass()
            ;

            logging.Write(
                new LogEntry
            {
                Severity = Severity.Verbose,
                Message  = string.Format("Done Compiling Derived assembly for {0}", languageName.FullLanguageName)
            });

            implementationGenerator.Generate(context);
            return(result);
        }
예제 #2
0
        private EmitSyntax EmitFactoryCode(
            EmitSyntax emit,
            PlannedClass contextPlannedClass,
            Type type,
            bool nullAllowed)
        {
            if (type == typeof(void))
            {
            }
            else if (type == typeof(int))
            {
                emit = emit.Ldc_I4_0();
            }
            else if (type.IsValueType)
            {
                var resultType = emit.Types.Import(type);
                var resultLoc  = emit.Locals.Generate("result");

                emit = emit
                       .Local(resultLoc, resultType)
                       .Ldloca(resultLoc.GetRef())
                       .Initobj(resultType)
                       .Ldloc(resultLoc.GetRef())
                ;
            }
            else if (nullAllowed)
            {
                emit.Ldnull();
            }
            else if (!type.IsAbstract && !type.IsInterface)
            {
                emit = emit.Newobj(
                    emit.Types.Import(type));
            }
            else if (contextPlannedClass != null && contextPlannedClass.Implements(type))
            {
                emit = emit.Ldarg(0);
            }
            else if (plan.Exists(e => e.Implements(type)))
            {
                var otherEntry = plan.Find(e => e.Implements(type));
                emit = emit.Newobj(
                    emit.Types.Class_(
                        ClassName.Parse(
                            otherEntry.ClassName)));
            }
            else
            {
                throw new InvalidOperationException(
                          "Internal error: non-planned abstract result type");
            }

            return(emit);
        }