This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / mbas / driver.cs
1 //
2 // driver.cs: The compiler command line driver.
3 //
4 // Author: Rafael Teixeira (rafaelteixeirabr@hotmail.com)
5 // Based on mcs by : Miguel de Icaza (miguel@gnu.org)
6 //
7 // Licensed under the terms of the GNU GPL
8 //
9 // (C) 2002 Rafael Teixeira
10 //
11
12 namespace Mono.Languages
13 {
14         using System;
15         using System.Reflection;
16         using System.Reflection.Emit;
17         using System.Collections;
18         using System.IO;
19         using System.Globalization;
20         using Mono.MonoBASIC;
21         using Mono.GetOptions;
22
23         enum Target 
24         {
25                 Library, Exe, Module, WinExe
26         };
27         
28         enum OptionCompare
29         {
30                 Binary, Text
31         };
32         
33         /// <summary>
34         ///    The compiler driver.
35         /// </summary>
36         public class Driver : Options
37         {
38                 // Temporary options
39                 //------------------------------------------------------------------
40                 [Option("[Mono] Only parses the source file (for debugging the tokenizer)", "parse")]
41                 public bool parse_only = false;
42
43                 [Option("[Mono] Only tokenizes source files")]
44                 public bool tokenize = false;
45
46                 [Option("[Mono] Shows stack trace at Error location")]
47                 public bool stacktrace { set { Report.Stacktrace = value; } }
48
49                 [Option("[Mono] Displays time stamps of various compiler events")]
50                 public bool timestamp
51                 {
52                         set
53                         {
54                                 timestamps = true;
55                                 last_time = DateTime.Now;
56                                 debug_arglist.Add("timestamp");
57                         }
58                 }
59
60                 // Mono-specific options
61                 //------------------------------------------------------------------
62                 [Option("About the MonoBASIC compiler", "about")]
63                 public override WhatToDoNext DoAbout()
64                 {
65                         return base.DoAbout();
66                 }
67
68                 [Option("[Mono] Don\'t assume the standard library", "nostdlib")]
69                 public bool NoStandardLibraries { set { RootContext.StdLib = !value; } }
70
71                 [Option("[Mono] Disables implicit references to assemblies", "noconfig")]
72                 public bool NoConfig { set { load_default_config = !value; } }
73
74                 [Option("[Mono] Allows unsafe code", "unsafe")]
75                 public bool AllowUnsafeCode { set { RootContext.Unsafe = value; } }
76
77                 [Option("[Mono] Set default context to checked", "checked")]
78                 public bool Checked { set { RootContext.Checked = value; } }
79
80                 [Option("[Mono] Debugger {arguments}", "debug-args")]
81                 public WhatToDoNext SetDebugArgs(string args)
82                 {
83                         char[] sep = { ',' };
84                         debug_arglist.AddRange (args.Split (sep));
85                         return WhatToDoNext.GoAhead;
86                 }
87
88                 [Option("[Mono] Ignores warning number {XXXX}", "ignorewarn")]
89                 public WhatToDoNext SetIgnoreWarning(int warn)
90                 {
91                         Report.SetIgnoreWarning(warn);
92                         return WhatToDoNext.GoAhead;
93                 }       
94
95                 [Option("[Mono] Sets warning {level} (the highest is 4, the default)", "wlevel")]
96                 public int WarningLevel { set { RootContext.WarningLevel = value; } }
97
98                 [Option("[Mono] Makes errors fatal", "fatal")]
99                 public bool Fatal { set { Report.Fatal = value; } }
100
101                 // Output file options
102                 //------------------------------------------------------------------
103                 [Option("Specifies the output {file} name", 'o', "out")]
104                 public string OutputFileName = null;
105
106                 [Option("Specifies the target {type} for the output file (exe [default], winexe, library, module)", "target")]
107                 public WhatToDoNext SetTarget(string type)
108                 {
109                         switch (type.ToLower())
110                         {
111                                 case "library":
112                                         target = Target.Library;
113                                         target_ext = ".dll";
114                                         break;
115                                                         
116                                 case "exe":
117                                         target = Target.Exe;
118                                         break;
119                                                         
120                                 case "winexe":
121                                         target = Target.WinExe;
122                                         break;
123                                                         
124                                 case "module":
125                                         target = Target.Module;
126                                         target_ext = ".dll";
127                                         break;
128                         }
129                         return WhatToDoNext.GoAhead;
130                 }
131
132                 // input file options
133                 //------------------------------------------------------------------
134                 public ArrayList AddedModules = new ArrayList();
135
136                 [Option("[NOT IMPLEMENTED YET]References metadata from specified {module}", "addmodule")]
137                 public string AddedModule { set { AddedModules.Add(value); } }
138
139                 [Option("[NOT IMPLEMENTED YET]Include all files in the current directory and subdirectories according to the {wildcard}", "recurse")]
140                 public WhatToDoNext Recurse(string wildcard)
141                 {
142                         //AddFiles (DirName, true); // TODO wrong semantics
143                         return WhatToDoNext.GoAhead;
144                 }
145
146                 [Option(-1, "References metadata from the specified {assembly}", 'r', "reference")]
147                 public string AddedReference { set { references.Add(value); } }
148                 
149                 // support for the Compact Framework
150                 //------------------------------------------------------------------
151                 [Option("[NOT IMPLEMENTED YET]Sets the compiler to target the Compact Framework","netcf")]
152                 public bool CompileForCompactFramework = false;
153                 
154                 [Option("[NOT IMPLEMENTED YET]Specifies the {path} to the location of mscorlib.dll and microsoft.visualbasic.dll", "sdkpath")]
155                 public string SDKPath = null;
156
157                 // resource options
158                 //------------------------------------------------------------------
159                 public ArrayList EmbeddedResources = new ArrayList();
160                 
161                 [Option(-1, "Adds the specified {file} as an embedded assembly resource", "resource", "res")]
162                 public string AddedResource { set { EmbeddedResources.Add(value); } }
163
164                 public ArrayList LinkedResources = new ArrayList();
165                 
166                 [Option(-1, "[NOT IMPLEMENTED YET]Adds the specified {file} as a linked assembly resource", "linkresource", "linkres")]
167                 public string AddedLinkresource { set { LinkedResources.Add(value); } }
168
169                 public ArrayList Win32Resources = new ArrayList();
170                 
171                 [Option(-1, "[NOT IMPLEMENTED YET]Specifies a Win32 resource {file} (.res)", "win32resource")]
172                 public string AddedWin32resource { set { Win32Resources.Add(value); } }
173
174                 public ArrayList Win32Icons = new ArrayList();
175                 
176                 [Option(-1, "[NOT IMPLEMENTED YET]Specifies a Win32 icon {file} (.ico) for the default Win32 resources", "win32icon")]
177                 public string AddedWin32icon { set { Win32Icons.Add(value); } }
178
179                 // code generation options
180                 //------------------------------------------------------------------
181                 [Option("[NOT IMPLEMENTED YET]Enable optimizations", "optimize")]
182                 public bool optimize = false;
183
184                 [Option("[NOT IMPLEMENTED YET]Remove integer checks. Default off.")]
185                 public bool removeintchecks = false;
186
187                 // TODO: handle VB.NET [+|-] boolean syntax
188                 [Option("Emit debugging information", 'g', "debug")]
189                 public bool want_debugging_support = false;
190
191                 [Option("Emit full debugging information (default)", "debug:full")]
192                 public bool fullDebugging = false;
193
194                 [Option("[IGNORED]Emit PDB file only", "debug:pdbonly")]
195                 public bool pdbOnly = false;
196
197                 // errors and warnings options
198                 //------------------------------------------------------------------
199                 [Option("Treat warnings as errors", "warnaserror")]
200                 public bool WarningsAreErrors { set { Report.WarningsAreErrors = value; } }
201
202                 [Option("Disable warnings", "nowarn")]
203                 public bool NoWarnings { set { if (value) RootContext.WarningLevel = 0; } }
204
205
206                 // language options
207                 //------------------------------------------------------------------
208                 public Hashtable Defines = new Hashtable();
209                 
210                 [Option(-1, "Declares global conditional compilation symbol(s). {symbol-list}:name=value,...", 'd', "define")]
211                 public string define { 
212                         set 
213                         {
214                                 foreach(string item in value.Split(',')) 
215                                 {       
216                                         string[] dados = item.Split('=');
217                                         try
218                                         {
219                                                 if (dados.Length > 1)
220                                                         Defines.Add(dados[0], dados[1]); 
221                                                 else
222                                                         Defines.Add(dados[0], string.Empty);
223                                         }
224                                         catch 
225                                         {
226                                                 Error ("Could not define symbol" + dados[0]);
227                                         }
228                                 }
229                         } 
230                 }
231                 
232                 [Option("Declare global Imports for namespaces in referenced metadata files. {import-list}:namespace,...", "imports")]
233                 public WhatToDoNext imports(string importslist)
234                 {
235                         Mono.MonoBASIC.Parser.ImportsList.AddRange(importslist.Split(','));
236                         return WhatToDoNext.GoAhead;
237                 }
238
239                 // TODO: handle VB.NET [+|-] boolean syntax
240                 [Option("[NOT IMPLEMENTED YET]Require explicit declaration of variables")]
241                 public bool optionexplicit { set { Mono.MonoBASIC.Parser.InitialOptionExplicit = value; } }
242
243                 // TODO: handle VB.NET [+|-] boolean syntax
244                 [Option("[NOT IMPLEMENTED YET]Enforce strict language semantics")]
245                 public bool optionstrict { set { Mono.MonoBASIC.Parser.InitialOptionStrict = value; } }
246                 
247                 [Option("[NOT IMPLEMENTED YET]Specifies binary-style string comparisons. This is the default", "optioncompare:binary")]
248                 public bool optioncomparebinary { set { Mono.MonoBASIC.Parser.InitialOptionCompareBinary = true; } }
249
250                 [Option("[NOT IMPLEMENTED YET]Specifies text-style string comparisons.", "optioncompare:text")]
251                 public bool optioncomparetext { set { Mono.MonoBASIC.Parser.InitialOptionCompareBinary = false; } }
252
253                 [Option("Specifies de root {namespace} for all type declarations")]
254                 public string rootnamespace { set { RootContext.RootNamespace = value; } }
255                 
256                 // Miscellaneous options        
257                 //------------------------------------------------------------------
258                 
259                 [Option("[IGNORED]Do not display compiler copyright banner")]
260                 public bool nologo = false;
261                 
262                 [Option("[NOT IMPLEMENTED YET]Quiet output mode")]
263                 public bool quiet = false;
264                 
265                 // TODO: semantics are different and should be adjusted
266                 [Option("Display verbose messages", 'v')] 
267                 public bool verbose     { set { GenericParser.yacc_verbose_flag = value; } }
268
269                 // Advanced options     
270                 //------------------------------------------------------------------
271                 // TODO: force option to accept number in hex format
272                 [Option("[NOT IMPLEMENTED YET]The base {address} for a library or module (hex)")]
273                 public int baseaddress;
274                 
275                 [Option("[NOT IMPLEMENTED YET]Create bug report {file}")]
276                 public string bugreport;
277                 
278                 // TODO: handle VB.NET [+|-] boolean syntax
279                 [Option("[NOT IMPLEMENTED YET]Delay-sign the assembly using only the public portion of the strong name key")]
280                 public bool delaysign;
281                 
282                 [Option("[NOT IMPLEMENTED YET]Specifies a strong name key {container}")]
283                 public string keycontainer;
284                 
285                 [Option("[NOT IMPLEMENTED YET]Specifies a strong name key {file}")]
286                 public string keyfile;
287
288                 public string[] libpath = null;
289                 
290                 [Option("List of directories to search for metadata references {path-list}:path;...", "libpath")]
291                 public WhatToDoNext setlibpath(string pathlist)
292                 {
293                         libpath = pathlist.Split(';');
294                         return WhatToDoNext.GoAhead;
295                 }
296
297                 [Option(@"Specifies the Class or Module that contains Sub Main.
298                         It can also be a {class} that inherits from System.Windows.Forms.Form.",
299                         'm', "main")]
300                 public string main { set { RootContext.MainClass = value; } }
301
302                 // TODO: handle VB.NET [+|-] boolean syntax
303                 [Option("[IGNORED]Emit compiler output in UTF8 character encoding")]
304                 public bool utf8output;
305
306                 // TODO : response file support
307                 
308                 ArrayList defines = new ArrayList();
309                 ArrayList references = new ArrayList();
310                 ArrayList soft_references = new ArrayList();
311                 
312                 string first_source = null;
313                 Target target = Target.Exe;
314                 string target_ext = ".exe";
315                 ArrayList debug_arglist = new ArrayList ();
316                 bool timestamps = false;
317                 Hashtable source_files = new Hashtable ();
318                 bool load_default_config = true;
319
320                 //
321                 // Last time we took the time
322                 //
323                 DateTime last_time;
324                 void ShowTime (string msg)
325                 {
326                         DateTime now = DateTime.Now;
327                         TimeSpan span = now - last_time;
328                         last_time = now;
329
330                         Console.WriteLine (
331                                 "[{0:00}:{1:000}] {2}",
332                                 (int) span.TotalSeconds, span.Milliseconds, msg);
333                 }
334                         
335                 public int LoadAssembly (string assembly, bool soft)
336                 {
337                         Assembly a;
338                         string total_log = "";
339
340                         try 
341                         {
342                                 char[] path_chars = { '/', '\\' };
343
344                                 if (assembly.IndexOfAny (path_chars) != -1)
345                                         a = Assembly.LoadFrom(assembly);
346                                 else {
347                                         string ass = assembly;
348                                         if (ass.EndsWith (".dll"))
349                                                 ass = assembly.Substring (0, assembly.Length - 4);
350                                         a = Assembly.Load (ass);
351                                 }
352                                 TypeManager.AddAssembly (a);
353                                 return 0;
354                         }
355                         catch (FileNotFoundException)
356                         {
357                                 if (libpath != null)
358                                 {
359                                         foreach (string dir in libpath)
360                                         {
361                                                 string full_path = dir + "/" + assembly + ".dll";
362
363                                                 try 
364                                                 {
365                                                         a = Assembly.LoadFrom (full_path);
366                                                         TypeManager.AddAssembly (a);
367                                                         return 0;
368                                                 } 
369                                                 catch (FileNotFoundException ff) 
370                                                 {
371                                                         total_log += ff.FusionLog;
372                                                         continue;
373                                                 }
374                                         }
375                                 }
376                                 if (soft)
377                                         return 0;
378                         }
379                         catch (BadImageFormatException f) 
380                         {
381                                 Error ("// Bad file format while loading assembly");
382                                 Error ("Log: " + f.FusionLog);
383                                 return 1;
384                         } catch (FileLoadException f){
385                                 Error ("File Load Exception: " + assembly);
386                                 Error ("Log: " + f.FusionLog);
387                                 return 1;
388                         } catch (ArgumentNullException){
389                                 Error ("// Argument Null exception ");
390                                 return 1;
391                         }
392                         
393                         Report.Error (6, "Can not find assembly `" + assembly + "'" );
394                         Console.WriteLine ("Log: \n" + total_log);
395
396                         return 0;
397                 }
398
399                 void Error(string message)
400                 {
401                         Console.WriteLine(message);
402                 }
403
404                 /// <summary>
405                 ///   Loads all assemblies referenced on the command line
406                 /// </summary>
407                 public int LoadReferences ()
408                 {
409                         int errors = 0;
410
411                         foreach (string r in references)
412                                 errors += LoadAssembly (r, false);
413
414                         foreach (string r in soft_references)
415                                 errors += LoadAssembly (r, true);
416                         
417                         return errors;
418                 }
419
420                 void SetupDefaultDefines ()
421                 {
422                         defines = new ArrayList ();
423                         defines.Add ("__MonoBASIC__");
424                 }
425                 
426                 void SetupDefaultImports()
427                 {
428                         Mono.MonoBASIC.Parser.ImportsList = new ArrayList();
429                         Mono.MonoBASIC.Parser.ImportsList.Add("Microsoft.VisualBasic");
430                 }
431
432
433                 //
434                 // Returns the directory where the system assemblies are installed
435                 //
436                 string GetSystemDir ()
437                 {
438                         Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
439
440                         foreach (Assembly a in assemblies){
441                                 string codebase = a.CodeBase;
442                                 if (codebase.EndsWith ("corlib.dll")){
443                                         return codebase.Substring (0, codebase.LastIndexOf ("/"));
444                                 }
445                         }
446
447                         Report.Error (-15, "Can not compute my system path");
448                         return "";
449                 }
450
451                 //
452                 // Given a path specification, splits the path from the file/pattern
453                 //
454                 void SplitPathAndPattern (string spec, out string path, out string pattern)
455                 {
456                         int p = spec.LastIndexOf ("/");
457                         if (p != -1){
458                                 //
459                                 // Windows does not like /file.cs, switch that to:
460                                 // "\", "file.cs"
461                                 //
462                                 if (p == 0){
463                                         path = "\\";
464                                         pattern = spec.Substring (1);
465                                 } else {
466                                         path = spec.Substring (0, p);
467                                         pattern = spec.Substring (p + 1);
468                                 }
469                                 return;
470                         }
471
472                         p = spec.LastIndexOf ("\\");
473                         if (p != -1){
474                                 path = spec.Substring (0, p);
475                                 pattern = spec.Substring (p + 1);
476                                 return;
477                         }
478
479                         path = ".";
480                         pattern = spec;
481                 }
482
483                 bool AddFiles (string spec, bool recurse)
484                 {
485                         string path, pattern;
486
487                         SplitPathAndPattern(spec, out path, out pattern);
488                         if (pattern.IndexOf("*") == -1)
489                         {
490                                 AddFile(spec);
491                                 return true;
492                         }
493
494                         string [] files = null;
495                         try {
496                                 files = Directory.GetFiles(path, pattern);
497                         } catch (System.IO.DirectoryNotFoundException) {
498                                 Report.Error (2001, "Source file `" + spec + "' could not be found");
499                                 return false;
500                         } catch (System.IO.IOException){
501                                 Report.Error (2001, "Source file `" + spec + "' could not be found");
502                                 return false;
503                         }
504                         foreach (string f in files)
505                                 AddFile (f);
506
507                         if (!recurse)
508                                 return true;
509                         
510                         string [] dirs = null;
511
512                         try {
513                                 dirs = Directory.GetDirectories(path);
514                         } catch {
515                         }
516                         
517                         foreach (string d in dirs) {
518                                         
519                                 // Don't include path in this string, as each
520                                 // directory entry already does
521                                 AddFiles (d + "/" + pattern, true);
522                         }
523
524                         return true;
525                 }
526
527                 void DefineDefaultConfig ()
528                 {
529                         //
530                         // For now the "default config" is harcoded into the compiler
531                         // we can move this outside later
532                         //
533                         string [] default_config = 
534                         {
535                                 "System",
536                                 "System.Data",
537                                 "System.Xml",
538                                 "Microsoft.VisualBasic" , 
539 #if EXTRA_DEFAULT_REFS
540                                 //
541                                 // Is it worth pre-loading all this stuff?
542                                 //
543                                 "Accessibility",
544                                 "System.Configuration.Install",
545                                 "System.Design",
546                                 "System.DirectoryServices",
547                                 "System.Drawing.Design",
548                                 "System.Drawing",
549                                 "System.EnterpriseServices",
550                                 "System.Management",
551                                 "System.Messaging",
552                                 "System.Runtime.Remoting",
553                                 "System.Runtime.Serialization.Formatters.Soap",
554                                 "System.Security",
555                                 "System.ServiceProcess",
556                                 "System.Web",
557                                 "System.Web.RegularExpressions",
558                                 "System.Web.Services" ,
559                                 "System.Windows.Forms"
560 #endif
561                         };
562                         
563                         foreach (string def in default_config)
564                                 soft_references.Add(def);
565                 }
566
567                 [ArgumentProcessor]
568                 public void AddFile(string fileName)
569                 {
570                         string f = fileName;
571                         if (first_source == null)
572                                 first_source = f;
573
574                         if (source_files.Contains(f))
575                                 Report.Error(1516, "Source file '" + f + "' specified multiple times");
576                         else
577                                 source_files.Add(f, f);
578                 }
579
580                 void ProcessSourceFile(string filename)
581                 {
582                         if (tokenize)
583                                 GenericParser.Tokenize(filename);
584                         else
585                                 GenericParser.Parse(filename);
586                 }
587
588                 string outputFile_Name = null;
589
590                 string outputFileName
591                 {
592                         get 
593                         {
594                                 if (outputFile_Name == null)
595                                 {
596                                         if (OutputFileName == null)
597                                         {
598                                                 int pos = first_source.LastIndexOf(".");
599
600                                                 if (pos > 0)
601                                                         OutputFileName = first_source.Substring(0, pos);
602                                                 else
603                                                         OutputFileName = first_source;
604                                         }
605                                         string bname = CodeGen.Basename(OutputFileName);
606                                         if (bname.IndexOf(".") == -1)
607                                                 OutputFileName +=  target_ext;
608                                         outputFile_Name = OutputFileName;
609                                 }
610                                 return outputFile_Name;
611                         }
612                 }
613
614                 bool ParseAll() // Phase 1
615                 {
616                         if (first_source == null)
617                         {
618                                 Report.Error(2008, "No files to compile were specified");
619                                 return false;
620                         }
621
622                         foreach(string filename in source_files.Values)
623                                 ProcessSourceFile(filename);
624
625                         if (tokenize || parse_only || (Report.Errors > 0))
626                                 return false;           
627
628                         return true; // everything went well go ahead
629                 }
630
631                 void InitializeDebuggingSupport()
632                 {
633                         string[] debug_args = new string [debug_arglist.Count];
634                         debug_arglist.CopyTo(debug_args);
635                         CodeGen.Init(outputFileName, outputFileName, want_debugging_support, debug_args);
636                         TypeManager.AddModule(CodeGen.ModuleBuilder);
637                 }
638
639                 public bool ResolveAllTypes() // Phase 2
640                 {
641                         // Load Core Library for default compilation
642                         if (RootContext.StdLib)
643                                 references.Insert(0, "mscorlib");
644
645                         if (load_default_config)
646                                 DefineDefaultConfig();
647
648                         if (timestamps)
649                                 ShowTime("Loading references");
650
651                         // Load assemblies required
652                         if (LoadReferences() > 0)
653                         {
654                                 Error ("Could not load one or more assemblies");
655                                 return false;
656                         }
657
658                         if (timestamps)
659                                 ShowTime("References loaded");
660
661                         InitializeDebuggingSupport();
662
663                         //
664                         // Before emitting, we need to get the core
665                         // types emitted from the user defined types
666                         // or from the system ones.
667                         //
668                         if (timestamps)
669                                 ShowTime ("Initializing Core Types");
670
671                         if (!RootContext.StdLib)
672                                 RootContext.ResolveCore ();
673                         if (Report.Errors > 0)
674                                 return false;
675                         
676                         TypeManager.InitCoreTypes();
677                         if (Report.Errors > 0)
678                                 return false;
679
680                         if (timestamps)
681                                 ShowTime ("   Core Types done");
682
683                         if (timestamps)
684                                 ShowTime ("Resolving tree");
685
686                         // The second pass of the compiler
687                         RootContext.ResolveTree ();
688                         if (Report.Errors > 0)
689                                 return false;
690                         
691                         if (timestamps)
692                                 ShowTime ("Populate tree");
693
694                         if (!RootContext.StdLib)
695                                 RootContext.BootCorlib_PopulateCoreTypes();
696                         if (Report.Errors > 0)
697                                 return false;
698
699                         RootContext.PopulateTypes();
700                         if (Report.Errors > 0)
701                                 return false;
702                         
703                         TypeManager.InitCodeHelpers();
704                         if (Report.Errors > 0)
705                                 return false;
706
707                         return true;
708                 }
709                 
710                 bool IsSWFApp()
711                 {
712                         string mainclass = GetFQMainClass();
713                         
714                         if (mainclass != null) {
715                                 foreach (string r in references) {
716                                         if (r.IndexOf ("System.Windows.Forms") >= 0) {
717                                                 Type t = TypeManager.LookupType(mainclass);
718                                                 if (t != null) 
719                                                         return t.IsSubclassOf (TypeManager.LookupType("System.Windows.Forms.Form"));
720                                                 break;  
721                                         }       
722                                 }
723                         }
724                         return false;
725                 }
726                 
727                 string GetFQMainClass()
728                 {       
729                         if (RootContext.RootNamespace != "")
730                                 return RootContext.RootNamespace + "." + RootContext.MainClass;
731                         else
732                                 return RootContext.MainClass;                   
733                 }
734                 
735                 void FixEntryPoint()
736                 {
737                         if (target == Target.Exe || target == Target.WinExe)
738                         {
739                                 MethodInfo ep = RootContext.EntryPoint;
740                         
741                                 if (ep == null)
742                                 {
743                                         // If we don't have a valid entry point yet
744                                         // AND if System.Windows.Forms is included
745                                         // among the dependencies, we have to build
746                                         // a new entry point on-the-fly. Otherwise we
747                                         // won't be able to compile SWF code out of the box.
748
749                                         if (IsSWFApp()) 
750                                         {                                                                                               
751                                                 Type t = TypeManager.LookupType(GetFQMainClass());
752                                                 if (t != null) 
753                                                 {                                                       
754                                                         TypeBuilder tb = t as TypeBuilder;
755                                                         MethodBuilder mb = tb.DefineMethod ("Main", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, 
756                                                                 typeof(void), new Type[0]);
757
758                                                         Type SWFA = TypeManager.LookupType("System.Windows.Forms.Application");
759                                                         Type SWFF = TypeManager.LookupType("System.Windows.Forms.Form");
760                                                         Type[] args = new Type[1];
761                                                         args[0] = SWFF;
762                                                         MethodInfo mi = SWFA.GetMethod("Run", args);
763                                                         ILGenerator ig = mb.GetILGenerator();
764                                                         ConstructorInfo ci = TypeManager.GetConstructor (TypeManager.LookupType(t.FullName), new Type[0]);
765                                                         
766                                                         ig.Emit (OpCodes.Newobj, ci);
767                                                         ig.Emit (OpCodes.Call, mi);
768                                                         ig.Emit (OpCodes.Ret);
769
770                                                         RootContext.EntryPoint = mb as MethodInfo;
771                                                 }
772                                         }
773                                 }
774                         }
775                 }
776
777                 bool GenerateAssembly()
778                 {
779                         //
780                         // The code generator
781                         //
782                         if (timestamps)
783                                 ShowTime ("Emitting code");
784                         
785                         
786
787                         RootContext.EmitCode();
788                         FixEntryPoint();
789                         if (Report.Errors > 0)
790                                 return false;
791
792                         if (timestamps)
793                                 ShowTime ("   done");
794
795
796                         if (timestamps)
797                                 ShowTime ("Closing types");
798
799                         RootContext.CloseTypes ();
800                         if (Report.Errors > 0)
801                                 return false;
802
803                         if (timestamps)
804                                 ShowTime ("   done");
805
806                         PEFileKinds k = PEFileKinds.ConsoleApplication;
807                                                         
808                         if (target == Target.Library || target == Target.Module)
809                                 k = PEFileKinds.Dll;
810                         else if (target == Target.Exe)
811                                 k = PEFileKinds.ConsoleApplication;
812                         else if (target == Target.WinExe)
813                                 k = PEFileKinds.WindowApplication;
814                         
815                         if (target == Target.Exe || target == Target.WinExe)
816                         {
817                                 MethodInfo ep = RootContext.EntryPoint;
818                         
819                                 if (ep == null)
820                                 {
821                                         Report.Error (30737, "Program " + outputFileName +
822                                                 " does not have an entry point defined");
823                                         return false;
824                                 }
825                                                         
826                                 CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
827                         }
828
829                         // Add the resources
830                         if (EmbeddedResources != null)
831                                 foreach (string file in EmbeddedResources)
832                                         CodeGen.AssemblyBuilder.AddResourceFile (file, file);
833                         
834                         CodeGen.Save(outputFileName);
835
836                         if (timestamps)
837                                 ShowTime ("Saved output");
838
839                         
840                         if (want_debugging_support) 
841                         {
842                                 CodeGen.SaveSymbols ();
843                                 if (timestamps)
844                                         ShowTime ("Saved symbols");
845                         }
846
847                         return true;
848                 }
849
850                 public void CompileAll()
851                 {
852 /* 
853                     VB.NET expects the default namespace to be "" (empty string)                
854                     
855                     if (RootContext.RootNamespace == "")
856                     {
857                       RootContext.RootNamespace = System.IO.Path.GetFileNameWithoutExtension(outputFileName);
858                     }
859 */
860                         if (!ParseAll()) // Phase 1
861                                 return;
862
863                         if (!ResolveAllTypes()) // Phase 2
864                                 return;
865
866                         GenerateAssembly(); // Phase 3 
867                 }
868
869                 /// <summary>
870                 ///    Parses the arguments, and calls the compilation process.
871                 /// </summary>
872                 int MainDriver(string [] args)
873                 {
874                         Console.WriteLine ("--------");
875                         Console.WriteLine ("MonoBASIC: THIS IS STILL ALPHA AND UNSUPPORTED SOFTWARE, USE AT YOUR OWN RISK.");
876                         Console.WriteLine ("--------");
877                         SetupDefaultDefines();  
878                         
879                         SetupDefaultImports();
880
881                         ProcessArgs(args);
882                         
883                         if (first_source == null)
884                         {
885                                 if (!quiet) 
886                                         DoHelp();
887                                 return 2;
888                         }
889
890                         CompileAll();
891
892                         return Report.ProcessResults(quiet);
893                 }
894
895                 public static int Main (string[] args)
896                 {
897                         Driver Exec = new Driver();
898                         
899                         Report.Stacktrace = false;
900
901                         return Exec.MainDriver(args);
902                 }
903
904         }
905 }