2001-08-11 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / driver.cs
1 //\r
2 // driver.cs: The compiler command line driver.\r
3 //\r
4 // Author: Miguel de Icaza (miguel@gnu.org)\r
5 //\r
6 // Licensed under the terms of the GNU GPL\r
7 //\r
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)\r
9 //\r
10 \r
11 namespace CIR\r
12 {\r
13         using System;\r
14         using System.Reflection;\r
15         using System.Reflection.Emit;\r
16         using System.Collections;\r
17         using System.IO;\r
18         using CIR;\r
19         using Generator;\r
20 \r
21         /// <summary>\r
22         ///    The compiler driver.\r
23         /// </summary>\r
24         public class Driver\r
25         {\r
26                 //\r
27                 // Assemblies references to be linked.   Initialized with\r
28                 // mscorlib.dll here.\r
29                 ArrayList references;\r
30 \r
31                 // Lookup paths\r
32                 ArrayList link_paths;\r
33 \r
34                 RootContext context; \r
35 \r
36                 bool yacc_verbose = false;\r
37 \r
38                 int error_count = 0;\r
39 \r
40                 public int parse (Tree context, string input_file)\r
41                 {\r
42                         CSharpParser parser;\r
43                         System.IO.Stream input;\r
44                         int errors;\r
45                         \r
46                         try {\r
47                                 input = System.IO.File.OpenRead (input_file);\r
48                         } catch {\r
49                                 return 1;\r
50                         }\r
51 \r
52                         parser = new CSharpParser (context, input_file, input);\r
53                         parser.yacc_verbose = yacc_verbose;\r
54                         try {\r
55                                 errors = parser.parse ();\r
56                         } catch (Exception ex) {\r
57                                 Console.WriteLine (ex);\r
58                                 Console.WriteLine ("Compilation aborted");\r
59                                 return 1;\r
60                         }\r
61                         \r
62                         return errors;\r
63                 }\r
64                 \r
65                 public void Usage ()\r
66                 {\r
67                         Console.WriteLine (\r
68                                 "compiler [options] source-files\n\n" +\r
69                                 "-v         Verbose parsing\n"+\r
70                                 "-o         Specifies output file\n" +\r
71                                 "-L         Specifies path for loading assemblies\n" +\r
72                                 "--nostdlib Does not load core libraries\n" +\r
73                                 "-r         References an assembly\n");\r
74                         \r
75                 }\r
76 \r
77                 public ITreeDump lookup_dumper (string name)\r
78                 {\r
79                         if (name == "tree")\r
80                                 return new Generator.TreeDump ();\r
81                         \r
82                         //                      if (name == "il")\r
83                         // return new MSIL.Generator ();\r
84                         \r
85                         return null;\r
86                 }\r
87 \r
88                 public static void error (string msg)\r
89                 {\r
90                         Console.WriteLine ("Error: " + msg);\r
91                 }\r
92 \r
93                 public static void notice (string msg)\r
94                 {\r
95                         Console.WriteLine (msg);\r
96                 }\r
97                 \r
98                 public static int Main(string[] args)\r
99                 {\r
100                         Driver driver = new Driver (args);\r
101 \r
102                         return driver.error_count;\r
103                 }\r
104 \r
105                 public int LoadAssembly (string assembly)\r
106                 {\r
107                         Assembly a;\r
108 \r
109                         foreach (string dir in link_paths){\r
110                                 string full_path = dir + "/" + assembly;\r
111 \r
112                                 try {\r
113                                         Console.WriteLine ("Loading: " + assembly);\r
114                                         a = Assembly.Load (assembly);\r
115                                 } catch (FileNotFoundException f) {\r
116                                         error ("// File not found: " + full_path);\r
117                                         error ("Log: " + f.FusionLog);\r
118                                         return 1;\r
119                                 } catch (BadImageFormatException) {\r
120                                         error ("// Bad file format: " + full_path);\r
121                                         return 1;\r
122                                 } catch (FileLoadException f){\r
123                                         error ("// File Load Exception: " + full_path);\r
124                                         error ("Log: " + f.FusionLog);\r
125                                         return 1;\r
126                                 } catch (ArgumentNullException){\r
127                                         error ("// Argument Null exception " + full_path);\r
128                                         return 1;\r
129                                 }\r
130 \r
131                                 context.TypeManager.AddAssembly (a);\r
132                         }\r
133                         return 0;\r
134                 }\r
135 \r
136                 // <summary>\r
137                 //   Loads all assemblies referenced on the command line\r
138                 // </summary>\r
139                 public int LoadReferences ()\r
140                 {\r
141                         int errors = 0;\r
142                         \r
143                         foreach (string r in references){\r
144                                 errors += LoadAssembly (r);\r
145                         }\r
146 \r
147                         return errors;\r
148                 }\r
149 \r
150                 // <summary>\r
151                 //    Parses the arguments, and drives the compilation\r
152                 //    process.\r
153                 //\r
154                 //    TODO: Mostly structured to debug the compiler\r
155                 //    now, needs to be turned into a real driver soon.\r
156                 // </summary>\r
157                 public Driver (string [] args)\r
158                 {\r
159                         ITreeDump generator = null;\r
160                         int errors = 0, i;\r
161                         string output_file = null;\r
162 \r
163                         context = new RootContext ();\r
164                         references = new ArrayList ();\r
165                         link_paths = new ArrayList ();\r
166 \r
167                         //\r
168                         // Setup defaults\r
169                         //\r
170                         link_paths.Add ("file:///C:/WINNT/Microsoft.NET/Framework/v1.0.2914");\r
171                         \r
172                         for (i = 0; i < args.Length; i++){\r
173                                 string arg = args [i];\r
174                                 \r
175                                 if (arg.StartsWith ("-")){\r
176                                         if (arg.StartsWith ("-v")){\r
177                                                 yacc_verbose = true;\r
178                                                 continue;\r
179                                         }\r
180 \r
181                                         if (arg.StartsWith ("-t")){\r
182                                                 generator = lookup_dumper (args [++i]);\r
183                                                 continue;\r
184                                         }\r
185 \r
186                                         if (arg.StartsWith ("-z")){\r
187                                                 generator.ParseOptions (args [++i]);\r
188                                                 continue;\r
189                                         }\r
190                                         \r
191                                         if (arg.StartsWith ("-o")){\r
192                                                 try {\r
193                                                         output_file = args [++i];\r
194                                                 } catch (Exception){\r
195                                                         error ("Could not write to `"+args [i]);\r
196                                                         error_count++;\r
197                                                         return;\r
198                                                 }\r
199                                                 continue;\r
200                                         }\r
201 \r
202                                         if (arg.StartsWith ("-r")){\r
203                                                 references.Add (args [++i]);\r
204                                                 continue;\r
205                                         }\r
206 \r
207                                         if (arg.StartsWith ("-L")){\r
208                                                 link_paths.Add (args [++i]);\r
209                                                 continue;\r
210                                         }\r
211 \r
212                                         if (arg == "--nostdlib"){\r
213                                                 context.StdLib = false;\r
214                                         }\r
215 \r
216                                         Usage ();\r
217                                         error_count++;\r
218                                         return;\r
219                                 }\r
220                                 \r
221                                 if (!arg.EndsWith (".cs")){\r
222                                         error ("Do not know how to compile " + arg);\r
223                                         errors++;\r
224                                         continue;\r
225                                 }\r
226 \r
227                                 errors += parse (context.Tree, arg);\r
228                         }\r
229 \r
230                         //\r
231                         // Load Core Library for default compilation\r
232                         //\r
233                         if (context.StdLib)\r
234                                 references.Insert (0, "mscorlib");\r
235 \r
236                         if (errors > 0){\r
237                                 error ("Parsing failed");\r
238                                 return;\r
239                         } else\r
240                                 notice ("Parsing successful");\r
241 \r
242                         //\r
243                         // Load assemblies required\r
244                         //\r
245                         errors += LoadReferences ();\r
246 \r
247                         if (errors > 0){\r
248                                 error ("Could not load one or more assemblies");\r
249                                 return;\r
250                         }\r
251 \r
252 \r
253                         //\r
254                         // Dumping the parsed tree.\r
255                         //\r
256                         // This code generation interface is only here\r
257                         // for debugging the parser. \r
258                         //\r
259                         if (generator != null){\r
260                                 if (output_file == null){\r
261                                         error ("Error: no output file specified");\r
262                                         return;\r
263                                 }\r
264 \r
265                                 Stream output_stream = File.Create (output_file);\r
266                                 StreamWriter output = new StreamWriter (output_stream);\r
267                                 \r
268                                 errors += generator.Dump (context.Tree, output);\r
269 \r
270                                 if (errors > 0){\r
271                                         error ("Compilation failed");\r
272                                         return;\r
273                                 } else\r
274                                         notice ("Compilation successful");\r
275 \r
276                                 output.Flush ();\r
277                                 output.Close ();\r
278                         } \r
279 \r
280                         \r
281                         error_count = errors;\r
282 \r
283                         //\r
284                         // Quick hack\r
285                         //\r
286                         if (output_file == null)\r
287                                 output_file = "a.exe";\r
288 \r
289                         context.CodeGen = new CilCodeGen (output_file, output_file);\r
290 \r
291                         //\r
292                         // The second pass of the compiler\r
293                         //\r
294                         context.ResolveTree ();\r
295                         context.PopulateTypes ();\r
296                         \r
297                         if (context.Report.Errors > 0){\r
298                                 error ("Compilation failed");\r
299                                 return;\r
300                         }\r
301                         \r
302                         context.CloseTypes ();\r
303                         \r
304                         context.CodeGen.Save (output_file);\r
305 \r
306                         notice ("Success");\r
307                 }\r
308 \r
309         }\r
310 }\r
311 \r
312 \r
313 \r