2007-03-15 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / mcs / driver.cs
index f26d5ab081ec20cf986f138991f9c305c39a450d..eba18fdaad35a12c2dca7f3b0ce8ecc45be5b081 100644 (file)
@@ -199,7 +199,9 @@ namespace Mono.CSharp
                        try {
                                parser.parse ();
                        } catch (Exception ex) {
-                               Report.Error(666, "Compilation aborted: " + ex);
+                               Report.Error(
+                                       666, String.Format ("Compilation aborted in file {0}, parser at {1}: {2}",
+                                                           file.Name, parser.Lexer.Location, ex));
                        } finally {
                                input.Close ();
                        }
@@ -211,6 +213,7 @@ namespace Mono.CSharp
                                "Other flags in the compiler\n" +
                                "   --fatal            Makes errors fatal\n" +
                                "   --parse            Only parses the source file\n" +
+                               "   --typetest         Tests the tokenizer's built-in type parser\n" +
                                "   --stacktrace       Shows stack trace at error location\n" +
                                "   --timestamp        Displays time stamps of various compiler events\n" +
                                "   --expect-error X   Expect that error X will be encountered\n" +
@@ -284,9 +287,7 @@ namespace Mono.CSharp
                
                public static int Main (string[] args)
                {
-#if GMCS_SOURCE
                        RootContext.Version = LanguageVersion.Default;
-#endif
                        Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
 
                        bool ok = MainDriver (args);
@@ -388,6 +389,8 @@ namespace Mono.CSharp
                                                        err = false;
                                                        break;
                                                } catch (FileNotFoundException ff) {
+                                                       if (soft)
+                                                               return;
                                                        total_log += ff.FusionLog;
                                                }
                                        }
@@ -455,12 +458,18 @@ namespace Mono.CSharp
                /// </summary>
                static public void LoadReferences ()
                {
-                       foreach (string r in references)
-                               LoadAssembly (r, false);
+                       //
+                       // Load Core Library for default compilation
+                       //
+                       if (RootContext.StdLib)
+                               LoadAssembly ("mscorlib", false);
 
                        foreach (string r in soft_references)
                                LoadAssembly (r, true);
 
+                       foreach (string r in references)
+                               LoadAssembly (r, false);
+
                        foreach (DictionaryEntry entry in external_aliases)
                                LoadAssembly ((string) entry.Value, (string) entry.Key, false);
                        
@@ -633,7 +642,7 @@ namespace Mono.CSharp
                        //
                        string [] default_config = {
                                "System",
-                               "System.Xml",
+                               "System.Xml"
 #if false
                                //
                                // Is it worth pre-loading all this stuff?
@@ -659,9 +668,10 @@ namespace Mono.CSharp
 #endif
                        };
                        
-                       int p = 0;
-                       foreach (string def in default_config)
-                               soft_references.Insert (p++, def);
+                       if (RootContext.Version == LanguageVersion.LINQ)
+                               soft_references.Add ("System.Core");
+
+                       soft_references.AddRange (default_config);
                }
 
                public static string OutputFile
@@ -701,6 +711,39 @@ namespace Mono.CSharp
                        Console.WriteLine ("Mono C# compiler version {0}", version);
                        Environment.Exit (0);
                }
+
+               //
+               // This is to test the tokenizer internal parser that is used to deambiguate
+               // '(' type identifier from '(' type others so that we are able to parse
+               // without introducing reduce/reduce conflicts in the grammar.
+               // 
+               static void LambdaTypeParseTest (string fname)
+               {
+                       bool fail = false;
+
+                       using (FileStream fs = File.OpenRead (fname)){
+                               StreamReader r = new StreamReader (fs, encoding);
+                               string line;
+                               
+                               while ((line = r.ReadLine ())!= null){
+                                       if (line [0] == '!')
+                                               continue;
+                                       bool must_pass = line [0] == '+';
+                                       StringReader test = new StringReader (line.Substring (1));
+                                       SeekableStreamReader reader = new SeekableStreamReader (test);
+                                       SourceFile file = new SourceFile (fname, fname, 0);
+                                       
+                                       Tokenizer lexer = new Tokenizer (reader, file, defines);
+                                       bool res = lexer.parse_lambda_parameters ();
+                                       
+                                       Console.WriteLine ("{3} ({1}=={2}): {0}", line.Substring (1), res, must_pass, res == must_pass);
+                                       if (res != must_pass)
+                                               fail = true;
+                               }
+                       }
+                       Console.WriteLine ("fail={0}", fail);
+                       Environment.Exit (fail ? 1 : 0);
+               }
                
                //
                // Currently handles the Unix-like command line options, but will be
@@ -967,6 +1010,14 @@ namespace Mono.CSharp
                                Report.Warning (-29, 1, "Compatibility: Use -noconfig option instead of --noconfig");
                                load_default_config = false;
                                return true;
+
+                       case "--typetest":
+                               if ((i + 1) >= args.Length){
+                                       Report.Error (5, "--typetest requires a filename argument");
+                                       Environment.Exit (1);
+                               }
+                               LambdaTypeParseTest (args [++i]);
+                               return true;
                        }
 
                        return false;
@@ -1029,11 +1080,14 @@ namespace Mono.CSharp
                                OutputFile = value;
                                return true;
 
+                       case "/o":
+                       case "/o+":
                        case "/optimize":
                        case "/optimize+":
                                RootContext.Optimize = true;
                                return true;
 
+                       case "/o-":
                        case "/optimize-":
                                RootContext.Optimize = false;
                                return true;
@@ -1046,15 +1100,16 @@ namespace Mono.CSharp
 
                        case "/d":
                        case "/define": {
-                               string [] defs;
-
                                if (value.Length == 0){
                                        Usage ();
                                        Environment.Exit (1);
                                }
 
-                               defs = value.Split (new Char [] {';', ','});
-                               foreach (string d in defs){
+                               foreach (string d in value.Split (';', ',')){
+                                       if (!Tokenizer.IsValidIdentifier (d)) {
+                                               Report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", d);
+                                               continue;
+                                       }
                                        defines.Add (d);
                                }
                                return true;
@@ -1160,7 +1215,7 @@ namespace Mono.CSharp
                                string [] refs = value.Split (new char [] { ';', ',' });
                                foreach (string r in refs){
                                        string val = r;
-                                       int index = val.IndexOf ("=");
+                                       int index = val.IndexOf ('=');
                                        if (index > -1) {
                                                string alias = r.Substring (0, index);
                                                string assembly = r.Substring (index + 1);
@@ -1365,13 +1420,18 @@ namespace Mono.CSharp
                                
                        case "/langversion":
                                switch (value.ToLower (CultureInfo.InvariantCulture)) {
-                                       case "iso-1":
-                                               RootContext.Version = LanguageVersion.ISO_1;
-                                               return true;
-
-                                       case "default":
-                                               SetupV2 ();
-                                               return true;
+                               case "iso-1":
+                                       RootContext.Version = LanguageVersion.ISO_1;
+                                       return true;
+                                       
+                               case "default":
+                                       SetupV2 ();
+                                       return true;
+                                       
+                               case "linq":
+                                       RootContext.Version = LanguageVersion.LINQ;
+                                       Tokenizer.LinqEnabled = true;
+                                       return true;
                                }
                                Report.Error (1617, "Invalid option `{0}' for /langversion. It must be either `ISO-1' or `Default'", value);
                                return true;
@@ -1599,12 +1659,6 @@ namespace Mono.CSharp
                        if (parse_only)
                                return true;
 
-                       //
-                       // Load Core Library for default compilation
-                       //
-                       if (RootContext.StdLib)
-                               references.Insert (0, "mscorlib");
-
                        if (load_default_config)
                                DefineDefaultConfig ();
 
@@ -1992,6 +2046,7 @@ namespace Mono.CSharp
                static void Reset ()
                {
                        Driver.Reset ();
+                       Tokenizer.Reset ();
                        Location.Reset ();
                        RootContext.Reset ();
                        Report.Reset ();