2001-09-12 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / driver.cs
index c796d8b552e63cfeead0a352c9894d04fae1d4be..56ab9f3a7e78893cddf7e32c43d3c68631745c76 100755 (executable)
@@ -8,7 +8,7 @@
 // (C) 2001 Ximian, Inc (http://www.ximian.com)\r
 //\r
 \r
-namespace CSC\r
+namespace CIR\r
 {\r
        using System;\r
        using System.Reflection;\r
@@ -17,13 +17,17 @@ namespace CSC
        using System.IO;\r
        using CIR;\r
        using Generator;\r
-       using CSC;\r
 \r
        /// <summary>\r
-       ///    Summary description for Class1.\r
+       ///    The compiler driver.\r
        /// </summary>\r
        public class Driver\r
        {\r
+\r
+               enum Target {\r
+                       Library, Exe, Module, WinExe\r
+               };\r
+               \r
                //\r
                // Assemblies references to be linked.   Initialized with\r
                // mscorlib.dll here.\r
@@ -32,14 +36,17 @@ namespace CSC
                // Lookup paths\r
                ArrayList link_paths;\r
 \r
-               // Our parser context.\r
-               Tree context;\r
-               \r
+               RootContext context; \r
+\r
                bool yacc_verbose = false;\r
 \r
                int error_count = 0;\r
 \r
-               public int parse (Tree context, string input_file)\r
+               string first_source;\r
+\r
+               Target target = Target.Exe;\r
+               \r
+               public int parse (string input_file)\r
                {\r
                        CSharpParser parser;\r
                        System.IO.Stream input;\r
@@ -67,20 +74,24 @@ namespace CSC
                public void Usage ()\r
                {\r
                        Console.WriteLine (\r
-                               "compiler [-v] [-t tree] [-o output] [-L path] [-r reference] sources.cs\n" +\r
-                               "-v  Verbose parsing\n"+\r
-                               "-o  Specifies output file\n" +\r
-                               "-L  Specifies path for loading assemblies\n" +\r
-                               "-r  References an assembly\n");\r
+                               "compiler [options] source-files\n\n" +\r
+                               "-v         Verbose parsing\n"+\r
+                               "-o         Specifies output file\n" +\r
+                               "-L         Specifies path for loading assemblies\n" +\r
+                               "--nostdlib Does not load core libraries\n" +\r
+                               "--target   Specifies the target (exe, winexe, library, module)\n" +\r
+                               "--dumper   Specifies a tree dumper\n" +\r
+                               "-r         References an assembly\n");\r
                        \r
                }\r
 \r
-               public IGenerator lookup_output (string name)\r
+               public ITreeDump lookup_dumper (string name)\r
                {\r
                        if (name == "tree")\r
                                return new Generator.TreeDump ();\r
-                       if (name == "il")\r
-                               return new MSIL.Generator ();\r
+                       \r
+                       //                      if (name == "il")\r
+                       // return new MSIL.Generator ();\r
                        \r
                        return null;\r
                }\r
@@ -110,6 +121,7 @@ namespace CSC
                                string full_path = dir + "/" + assembly;\r
 \r
                                try {\r
+                                       Console.WriteLine ("Loading: " + assembly);\r
                                        a = Assembly.Load (assembly);\r
                                } catch (FileNotFoundException f) {\r
                                        error ("// File not found: " + full_path);\r
@@ -127,11 +139,14 @@ namespace CSC
                                        return 1;\r
                                }\r
 \r
-                               context.AddAssembly (a);\r
+                               context.TypeManager.AddAssembly (a);\r
                        }\r
                        return 0;\r
                }\r
-               \r
+\r
+               // <summary>\r
+               //   Loads all assemblies referenced on the command line\r
+               // </summary>\r
                public int LoadReferences ()\r
                {\r
                        int errors = 0;\r
@@ -143,21 +158,26 @@ namespace CSC
                        return errors;\r
                }\r
 \r
-               \r
+               // <summary>\r
+               //    Parses the arguments, and drives the compilation\r
+               //    process.\r
+               //\r
+               //    TODO: Mostly structured to debug the compiler\r
+               //    now, needs to be turned into a real driver soon.\r
+               // </summary>\r
                public Driver (string [] args)\r
                {\r
-                       Stream output_stream = Console.OpenStandardOutput ();\r
-                       IGenerator generator = null;\r
+                       ITreeDump generator = null;\r
                        int errors = 0, i;\r
+                       string output_file = null;\r
 \r
-                       context = new Tree ();\r
+                       context = new RootContext ();\r
                        references = new ArrayList ();\r
                        link_paths = new ArrayList ();\r
 \r
                        //\r
                        // Setup defaults\r
                        //\r
-                       references.Add ("mscorlib");\r
                        link_paths.Add ("file:///C:/WINNT/Microsoft.NET/Framework/v1.0.2914");\r
                        \r
                        for (i = 0; i < args.Length; i++){\r
@@ -169,8 +189,8 @@ namespace CSC
                                                continue;\r
                                        }\r
 \r
-                                       if (arg.StartsWith ("-t")){\r
-                                               generator = lookup_output (args [++i]);\r
+                                       if (arg.StartsWith ("--dumper")){\r
+                                               generator = lookup_dumper (args [++i]);\r
                                                continue;\r
                                        }\r
 \r
@@ -181,7 +201,7 @@ namespace CSC
                                        \r
                                        if (arg.StartsWith ("-o")){\r
                                                try {\r
-                                                       output_stream = File.Create (args [++i]);\r
+                                                       output_file = args [++i];\r
                                                } catch (Exception){\r
                                                        error ("Could not write to `"+args [i]);\r
                                                        error_count++;\r
@@ -190,6 +210,28 @@ namespace CSC
                                                continue;\r
                                        }\r
 \r
+                                       if (arg.StartsWith ("--target")){\r
+                                               string type = args [++i];\r
+\r
+                                               switch (type){\r
+                                               case "library":\r
+                                                       target = Target.Library;\r
+                                                       break;\r
+                                                       \r
+                                               case "exe":\r
+                                                       target = Target.Exe;\r
+                                                       break;\r
+\r
+                                               case "winexe":\r
+                                                       target = Target.WinExe;\r
+                                                       break;\r
+                                                       \r
+                                               case "module":\r
+                                                       target = Target.Module;\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       \r
                                        if (arg.StartsWith ("-r")){\r
                                                references.Add (args [++i]);\r
                                                continue;\r
@@ -200,62 +242,152 @@ namespace CSC
                                                continue;\r
                                        }\r
 \r
+                                       if (arg == "--nostdlib"){\r
+                                               context.StdLib = false;\r
+                                       }\r
+\r
                                        Usage ();\r
                                        error_count++;\r
                                        return;\r
                                }\r
                                \r
                                if (!arg.EndsWith (".cs")){\r
+                                               \r
                                        error ("Do not know how to compile " + arg);\r
                                        errors++;\r
                                        continue;\r
                                }\r
 \r
-                               errors += parse (context, arg);\r
+                               if (first_source == null)\r
+                                       first_source = arg;\r
+                               \r
+                               errors += parse (arg);\r
+                       }\r
+\r
+                       if (first_source == null){\r
+                               context.Report.Error (2008, "No files to compile were specified");\r
+                               return;\r
                        }\r
-                       if (errors > 0)\r
-                               error ("// Parsing failed");\r
-                       else\r
-                               notice ("// Parsing successful");                               \r
+                       \r
+                       //\r
+                       // Load Core Library for default compilation\r
+                       //\r
+                       if (context.StdLib)\r
+                               references.Insert (0, "mscorlib");\r
+\r
+                       if (errors > 0){\r
+                               error ("Parsing failed");\r
+                               return;\r
+                       } else\r
+                               notice ("Parsing successful");\r
 \r
                        //\r
                        // Load assemblies required\r
                        //\r
                        errors += LoadReferences ();\r
 \r
-                       if (errors > 0)\r
-                               error ("// Could not load one or more assemblies");\r
-                       else\r
-                               notice ("// Assemblies loaded");\r
-\r
+                       if (errors > 0){\r
+                               error ("Could not load one or more assemblies");\r
+                               return;\r
+                       }\r
 \r
-                       errors += context.BuilderInit ("Module", "Module.exe");\r
 \r
                        //\r
-                       // Name resolution on the tree.\r
-                       //\r
-                       errors += context.Resolve ();\r
-                                                  \r
+                       // Dumping the parsed tree.\r
                        //\r
-                       // Code generation from the tree\r
+                       // This code generation interface is only here\r
+                       // for debugging the parser. \r
                        //\r
                        if (generator != null){\r
+                               if (output_file == null){\r
+                                       error ("Error: no output file specified");\r
+                                       return;\r
+                               }\r
+\r
+                               Stream output_stream = File.Create (output_file);\r
                                StreamWriter output = new StreamWriter (output_stream);\r
                                \r
-                               errors += generator.GenerateFromTree (context, output);\r
+                               errors += generator.Dump (context.Tree, output);\r
 \r
-                               if (errors > 0)\r
-                                       error ("// Compilation failed");\r
-                               else\r
-                                       notice ("// Compilation successful");\r
+                               if (errors > 0){\r
+                                       error ("Compilation failed");\r
+                                       return;\r
+                               } else\r
+                                       notice ("Compilation successful");\r
 \r
                                output.Flush ();\r
                                output.Close ();\r
-                       }\r
+                       } \r
 \r
+                       \r
                        error_count = errors;\r
+\r
+                       //\r
+                       // Quick hack\r
+                       //\r
+                       if (output_file == null){\r
+                               int pos = first_source.LastIndexOf (".");\r
+\r
+                               output_file = first_source.Substring (0, pos) + ".exe";\r
+                       }\r
+\r
+                       context.CodeGen = new CodeGen (output_file, output_file);\r
+\r
+                       //\r
+                       // The second pass of the compiler\r
+                       //\r
+                       context.ResolveTree ();\r
+                       context.PopulateTypes ();\r
+\r
+                       //\r
+                       // Before emitting, we need to get the core\r
+                       // types emitted from the user defined types\r
+                       // or from the system ones.\r
+                       //\r
+                       context.TypeManager.InitCoreTypes ();\r
+\r
+                       //\r
+                       // The code generator\r
+                       //\r
+                       context.EmitCode ();\r
+                       \r
+                       if (context.Report.Errors > 0){\r
+                               error ("Compilation failed");\r
+                               return;\r
+                       }\r
+                       \r
+                       context.CloseTypes ();\r
+\r
+                       PEFileKinds k = PEFileKinds.ConsoleApplication;\r
+                               \r
+                       if (target == Target.Library || target == Target.Module)\r
+                               k = PEFileKinds.Dll;\r
+                       else if (target == Target.Exe)\r
+                               k = PEFileKinds.ConsoleApplication;\r
+                       else if (target == Target.WinExe)\r
+                               k = PEFileKinds.WindowApplication;\r
+\r
+                       if (target == Target.Exe || target == Target.WinExe){\r
+                               MethodInfo ep = context.EntryPoint;\r
+\r
+                               if (ep == null){\r
+                                       context.Report.Error (5001, "Program " + output_file +\r
+                                                             " does not have an entry point defined");\r
+                                       return;\r
+                               }\r
+                               \r
+                               context.CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);\r
+                       }\r
+                       \r
+                       context.CodeGen.Save (context.Report, output_file);\r
+\r
+                       if (context.Report.Errors > 0){\r
+                               error ("Compilation failed");\r
+                               return;\r
+                       }\r
+\r
+                       notice ("Success");\r
                }\r
 \r
        }\r
 }\r
-\r