⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// EntryPoint for Blue Compiler
// See http://blogs.msdn.com/jmstall for issues.
//-----------------------------------------------------------------------------

using System;
using System.Diagnostics;
using IO = System.IO;

using Blue.Public;
using Utilities = Blue.Utilities;
using CodeGen = Blue.CodeGen;
using ErrorLog = Blue.Utilities.ErrorLog;


// This is a dummy class just to serve as a tag for the XML docs
/// <summary>
/// Blue is a C# compiler written in C#.
/// </summary>
/// <remarks>
/// <para>Blue is an entirely managed C# implementation written 
/// in C# using the .NET runtime and Frameworks.</para>
/// <para>See help on <see cref="Blue.Driver"/> for more details on the implementation</para>
/// </remarks>
public class Help
{
public static void About() { }
}

namespace Blue
{  
#region Driver & helpers
    /// <summary>
    /// The <c>Driver</c> class houses the Main() function and 
    /// controls all other components.
    /// </summary>
    /// <remarks>
    /// The Driver class is the primary client for the interfaces in <see cref="Blue.Public"/>.
    /// It creates the components in the compilation pipeline.
    /// <list type="bullet">
    /// <item><see cref="ILexer"/> - convert source to a token stream </item>
    /// <item><see cref="IParser"/> - convert token stream into AST </item>
    /// <item><see cref="ISemanticChecker"/> - do symbol resolution on the AST </item>
    /// <item><see cref="ICodeGenDriver"/> - emit IL for a resolved-AST </item>    
    /// </list>
    /// It also creates the utility components:
    /// <list type="bullet">
    /// <item><see cref="IOptions"/> - register delegates to handle command line options</item>
    /// <item><see cref="IError"/> - unified error-reporting system for user-errors</item>
    /// <item><see cref="Log"/> - logging facility, mostly for debugging </item>
    /// </list>
    /// </remarks>
    public class Driver
    {
//-----------------------------------------------------------------------------
// Entry point for Blue
//-----------------------------------------------------------------------------
        public static int Main(string[] arstArgs)
        {        
            int iErrorValue = 1;
            
            Init(arstArgs);
            
            // Main work done here. This should not throw an exception.
            // It will print all the error information. When we return from here,
            // the binary should have been compiled, all error handling done, etc.
            
            iErrorValue = MainProxy(arstArgs);
            
            if (StdErrorLog.HasErrors())
                iErrorValue = 2;   
                
            Terminate(iErrorValue);
            
            return iErrorValue;
        }

//-----------------------------------------------------------------------------
// Shutdown
//-----------------------------------------------------------------------------
        static void Terminate(int iErrorValue)
        {
            Log.WriteLine(Log.LF.All, "Shutdown compiler, return value={0}",iErrorValue);
            Log.TerminateLogging();            
        }

//-----------------------------------------------------------------------------
// Initialization
//-----------------------------------------------------------------------------
        static void Init(string [] arstArgs)
        {
            PrintLogo();
            
            // Initialize logging
            Log.InitLogging(arstArgs);
            
            // Log startup info
            #if __BLUE__
                Log.WriteLine(Log.LF.All, "DOGFOOD version compiled by Blue.");            
            #else
                Log.WriteLine(Log.LF.All, "Normal version compiled by C#.");
            #endif
            Log.WriteLine(Log.LF.All, "Startup compiler, args={0}", Log.F(arstArgs));
            
            // Create the error logging facility
            m_ErrorLog = new Utilities.ErrorLog();
            
            // Create the option facility
            m_OptionMananager = new Utilities.Options();
            
            // Let each of the differen components register their option handlers
            AddDriverOptions();
            
            m_codegen = new CodeGen.EmitCodeGen(OptionManager);
        }
        
        // Add the options for the Driver.
        static void AddDriverOptions()            
        {
            OptionManager.AddHandler("xml", null, new OptionHandler(Driver.OptionX),
                "Generate XML debug information", 
                "Emit xml files for the parse tree and symbols.\n"+
                "The parse tree of all source files are dumped into a single xml file.\n" +
                "The following files are generated:\n"+
                "'X_parse.xml' - the parse tree before any resolution.\n"+
                "'X_post.xml'  - the parse tree after resolution. This may display most.\n"+
                "                attributes as well as show the changes in the tree during.\n"+
                "                resolution.\n"+
                "'X_sym.xml'   - a dump of the symbol table, including imported symbols.\n"
                );
                    
            OptionManager.AddHandler("dbg_quit", "_Q", new OptionHandler(Driver.OptionDbgQuit),
                "Debugging: Quit after stage (Lexer, Parser, Resolve)", 
                "[For debugging purposes.]\n"+
                "Quits after the specified compilation stage. Useful in conjuction with\n"+
                "the 'xml' option.\n"+
                "usage:\n"+
                "/_Q:Lexer - quit after scanning. Implicitly output the lexemes.\n"+
                "/_Q:Parser - quit after building the AST, before any resolution.\n"+
                "/_Q:Resolve - quit after symbol resolution, but before codegen.\n"
            );
                
            OptionManager.AddHandler("reference", "r", new OptionHandler(Driver.OptionAddReference),
                "Add assembly reference (/r:myassem)", 
                "Imports the meta data from the specified assembly\n" +
                "/r:XXX will first search the local directory for a file XXX; if not found it\n"+
                "will then search the GAC where XXX is the fully-qualified name; if not found it\n"+
                "will then search where XXX is the partial name.\n"+
                "ex: /r:System"
                );
                
            OptionManager.AddHandler("define", "d", new OptionHandler(Driver.OptionDefineSymbol),
                "Define conditional compilation symbols (/d:<symbol>)", 
                "Adds a symbol to control the preprocessor's #if <symbol> behavior.\n"+
                "This is equivalent to using a #define <symbol> in every source file.\n"+
                "The symbol __BLUE__ is always prefedined."+
                "ex:\n"+
                "/define:DEBUG\n"
                //"/d:Skip_First_thing,AnotherDefine,Third" @todo - allow this
                );
        }
        
#region Data
        // Option manager
        static Utilities.Options m_OptionMananager;
        static Public.IOptions OptionManager {
            get { return m_OptionMananager; }
        }
        
        
        // Codegen
        static ICodeGenDriver m_codegen;
        
        // Predefined symbols for preprocessor        
        static string [] m_defines;
        
        // Expose the error log publicly
        static Utilities.ErrorLog m_ErrorLog;
        //static public Utilities.ErrorLog StdErrorLog
        static public Blue.Public.IError StdErrorLog
        {
            get { return m_ErrorLog; }
        }

#endregion

//-----------------------------------------------------------------------------
// Print the startup info
//-----------------------------------------------------------------------------
        static void PrintLogo()
        {
            Console.Write("Blue Sample Compiler v1.0");            
#if __BLUE__
            Console.WriteLine(" [Dogfood]");
#else
            Console.WriteLine(" [normal]");
#endif      
            Console.WriteLine("by Mike Stall (http://blogs.msdn.com/jmstall)");
            Console.WriteLine("\n");
        }

//-----------------------------------------------------------------------------
// Primary Worker. This drives the different stages.
// Returns the error code for all expected end-user errors.
// Unexpected errors (bugs / holes in the compiler) will throw an exception. 
//-----------------------------------------------------------------------------
        static int MainWorker(string[] arstSourceFiles)
        {   
            if (arstSourceFiles == null)
            {
                PrintError_NoSourceFiles();                        
                return 1;
            }
                                                    
                                        
            // Check if debugging the lexer. Just do first file
            // @todo - should we do all files?
            if (ShouldDebugQuit(EStage.cLexer))
            {
                string stDefault = arstSourceFiles[0];
                System.IO.StreamReader reader = new System.IO.StreamReader(stDefault);
                ILexer lex = new ManualParser.Lexer(stDefault, reader);

                return TestLexer(lex);
            }
               
            //                
            // Lex & Parse all source files. 
            // It doesn't matter which order files are parsed in
            //
            AST.ProgramDecl root = ParseAllFiles(arstSourceFiles);
            if (root == null)
                return 1;
                    
            if (ShouldDebugQuit(EStage.cParser))
                return 0;
                    
                            
            //                
            // Symantic checks:                     
            //
            
            // Must startup codegen so that it can assign clr types
            m_codegen.BeginOutput(arstSourceFiles);
            
            System.Reflection.Assembly [] refs = LoadImportedAssemblies();
            if (StdErrorLog.HasErrors())
                return 19;
            
            ICLRtypeProvider provider = m_codegen.GetProvider(refs);
                                    
            ISemanticChecker check = new SymbolEngine.SemanticChecker();
            bool fCheckOk = check.DoCheck(root, provider, refs);
                    
            if (!fCheckOk)
            {
                return 2;
            }
            
            // Dump parse tree after resolution        
            if (s_fGenerateXML)
            {
                string stOutput = IO.Path.GetFileNameWithoutExtension(arstSourceFiles[0]);
                
                
                System.Xml.XmlWriter oSym = new System.Xml.XmlTextWriter(stOutput + "_sym.xml", null);
                check.DumpSymbolTable(oSym);
            
                System.Xml.XmlWriter oPost = new System.Xml.XmlTextWriter(stOutput + "_post.xml", null);
                AST.Node.DumpTree(root, oPost);
            }
                
            if (ShouldDebugQuit(EStage.cSymbolResolution))
                return 0;

            //
            // Codegen
            //     
            
            m_codegen.DoCodeGen(root);
            
            m_codegen.EndOutput();
        
            // If we make it this far, we have no errors.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -