Microsoft.Zing.Splicer.CodeGen C# (CSharp) Method

CodeGen() public method

public CodeGen ( Compilation compilation ) : CompilationUnit
compilation Compilation
return CompilationUnit
        public CompilationUnit CodeGen(Compilation compilation)
        {
            try
            {
                // Debugging message
                /*
                for (int c = 0, nc = compilation.CompilationUnits.Length; c < nc; c++)
                {
                    Namespace ns = (Namespace)compilation.CompilationUnits[c].Nodes[0];
                    Console.WriteLine("X" + ns.Name.ToString() + "X");

                    for (int i = 0, n = ns.Types.Length; i < n; i++)
                    {
                        TypeNode tn = (TypeNode)ns.Types[i];

                        Console.WriteLine("\t" + tn.Name.ToString());
                    }
                }
                 */
                // END

                this.cZing = compilation;
                Templates.module = compilation.TargetModule;
                Templates.InitializeTemplates();

                // Scan the Zing AST for interesting high-level information.
                MemberList globals = CollectGlobals();
                TypeNodeList classes = CollectClasses();

                // Compile the "base" template and get the interesting nodes from it.
                cuBase = Templates.GetApplicationTemplate(compilation.TargetModule, options, globals.Count > 0, HeapUsed());

                Debug.Assert(((Namespace)cuBase.Nodes[0]).Types.Count == 0);
                Debug.Assert(((Namespace)cuBase.Nodes[0]).NestedNamespaces.Count == 1);
                Debug.Assert(((Namespace)cuBase.Nodes[0]).NestedNamespaces[0].Types.Count == 1);

                appClass = (Class)((Namespace)cuBase.Nodes[0]).NestedNamespaces[0].Types[0];

                // Begin transforming the output

                SetSourceStrings(compilation);
                SetExceptionList();

                // for each Zing type definition, call a helper to splice it into the
                // generated compilation unit.

                for (int c = 0, nc = cZing.CompilationUnits.Count; c < nc; c++)
                {
                    for (int i = 0, n = ((Namespace)cZing.CompilationUnits[c].Nodes[0]).Types.Count; i < n; i++)
                    {
                        TypeNode tn = (TypeNode)((Namespace)cZing.CompilationUnits[c].Nodes[0]).Types[i];

                        if (tn is Interface)
                            GenerateInterface((Interface)tn);
                        else if (tn is Class)
                            GenerateClass((Class)tn);
                        else if (tn is EnumNode)
                            GenerateEnum((EnumNode)tn);
                        else if (tn is Range)
                            GenerateRange((Range)tn);
                        else if (tn is Set)
                            GenerateSet((Set)tn);
                        else if (tn is Chan)
                            GenerateChan((Chan)tn);
                        else if (tn is Struct)
                            GenerateStruct((Struct)tn);
                        else if (tn is ZArray)
                            GenerateArray((ZArray)tn);
                        else
                            throw new ApplicationException("Unknown Zing type: " + tn.GetType().ToString());
                    }
                }

                GenerateTypeChoiceHelper();

                // NOTE: this must be done after processing the classes because we turn off
                // the "static" flag on the globals during processing which confuses GenerateClass.
                ProcessGlobals(globals);

                return cuBase;
            }
            finally
            {
                Templates.module = null;
                Templates.ReleaseTemplates();
            }
        }

Usage Example

Example #1
0
        public override void CompileParseTree(Compilation compilation, ErrorNodeList errorNodes)
        {
            TrivialHashtable ambiguousTypes = new TrivialHashtable();
            TrivialHashtable scopeFor = new TrivialHashtable();
            TrivialHashtable referencedLabels = new TrivialHashtable();
            Hashtable exceptionNames = new Hashtable();
            ErrorHandler errorHandler = new ErrorHandler(errorNodes);
            string target = "";
            ZingCompilerOptions zoptions = compilation.CompilerParameters as ZingCompilerOptions;
            if (zoptions != null && zoptions.DumpSource)
            {
                target = compilation.CompilerParameters.OutputAssembly;
                if (string.IsNullOrEmpty(target))
                {
                    target = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar;
                }
                string output = Path.GetDirectoryName(target);
                if (string.IsNullOrEmpty(output)) output = Directory.GetCurrentDirectory();
                target = Path.GetFileNameWithoutExtension(target);
            }

            if (this.Options == null)
                this.Options = compilation.CompilerParameters;

            //Attach scopes to namespaces and types so that forward references to base types can be looked up in the appropriate namespace scope
            Scoper scoper = new Scoper(scopeFor);
            scoper.VisitCompilation(compilation);

            //Walk IR looking up names
            TypeSystem typeSystem = new TypeSystem(errorHandler);
            Looker looker = new Looker(compilation.GlobalScope, errorHandler, scopeFor, typeSystem, // LJW: added typeSystem
                ambiguousTypes, referencedLabels, exceptionNames);
            looker.VisitCompilation(compilation);

            //Walk IR inferring types and resolving overloads
            Resolver resolver = new Resolver(errorHandler, typeSystem);
            resolver.VisitCompilation(compilation);

            Checker checker = new Checker(errorHandler, typeSystem, scopeFor, ambiguousTypes, referencedLabels); // LJW: added scopeFor
            checker.VisitCompilation(compilation);

            // Walk the Zing IR splicing it into our code-gen templates
            Splicer splicer = new Splicer(this.Options, referencedLabels, exceptionNames);
            CompilationUnit cuMerged = splicer.CodeGen(compilation);

            //
            // If the 'dumpSource' option is given, then we decompile the IR to C# and write this
            // to a file.
            //
            if (zoptions != null && zoptions.DumpSource)
            {
                // Once the codegen is done and we have the IR for the generated code, we use the
                // decompiler to get C# back out, and hand this to the standard compiler. Later,
                // we'll replace this with the X# normalizer and avoid going in and out of source
                // code (except for compiler debugging).
                string tempSrc;
                string tempName = compilation.CompilerParameters.OutputAssembly + ".cs";
                Decompiler decompiler = new Decompiler();
                tempSrc = decompiler.Decompile(cuMerged);

                StreamWriter sw = File.CreateText(tempName);
                sw.Write(tempSrc);
                sw.Close();
            }

            if (zoptions != null && zoptions.DumpLabels)
            {
                string tempName = compilation.CompilerParameters.OutputAssembly + ".labels";
                StreamWriter sw = File.CreateText(tempName);
                sw.Write(splicer.LabelString);
                sw.Close();
            }

            for (int i = 0; i < RequiredTypes.Length; i++)
            {
                R.Assembly asm = R.Assembly.GetAssembly(RequiredTypes[i]);
                if (!compilation.CompilerParameters.ReferencedAssemblies.Contains(asm.Location))
                    compilation.CompilerParameters.ReferencedAssemblies.Add(asm.Location);
            }

            // The if-statement added by Jiri Adamek
            // It loads a native ZOM assembly if used
            if (zoptions != null && zoptions.ZomAssemblyName != null)
            {
                compilation.CompilerParameters.ReferencedAssemblies.Add(zoptions.ZomAssemblyName);
            }

            CS.Compiler csCompiler = new CS.Compiler();

            // We have to create a new module to pull in references from the
            // assemblies we just added above.
            compilation.TargetModule = this.targetModule =
                csCompiler.CreateModule(compilation.CompilerParameters, errorNodes);

            // Our one top-level type must be added to the module's type list
            compilation.TargetModule.Types.Add(((Namespace)cuMerged.Nodes[0]).NestedNamespaces[0].Types[0]);

            // The restorer patches the DeclaringModule field of our types
            Restorer restorer = new Restorer(compilation.TargetModule);
            restorer.VisitCompilationUnit(cuMerged);

            // Replace the Zing compilation unit with our generated code before invoking
            // the Spec# back end.
            compilation.CompilationUnits = new CompilationUnitList(cuMerged);

            foreach (CompilationUnit cunit in compilation.CompilationUnits)
                cunit.Compilation = compilation;

            // For retail builds, disable the time-consuming definite-assignment checks
            // in the Spec# compiler.
            if (!this.Options.IncludeDebugInformation)
                compilation.CompilationUnits[0].PreprocessorDefinedSymbols["NODEFASSIGN"] = "true";

            // Let the Spec# back end process the IR from here
            csCompiler.CompileParseTree(compilation, errorNodes);
        }