Use existing error reporting.
[mono.git] / mcs / mcs / cs-tokenizer.cs
index 802cdc42c68ef56f39634398ddbea8b3aeb98c14..5d1c92c54159e13f22995161cdc23ca7d69ac297 100644 (file)
@@ -14,7 +14,6 @@
 
 using System;
 using System.Text;
-using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 using System.Globalization;
@@ -117,6 +116,17 @@ namespace Mono.CSharp
                                entry.column = column;
                                return entry;
                        }
+
+                       //
+                       // Used for token not required by expression evaluator
+                       //
+                       public static LocatedToken CreateOptional (int row, int col)
+                       {
+#if false
+                               return Create (row, col);
+#endif
+                               return null;
+                       }
                        
                        public static void Initialize ()
                        {
@@ -144,13 +154,14 @@ namespace Mono.CSharp
                int col = 0;
                int previous_col;
                int current_token;
+               int tab_size;
                bool handle_get_set = false;
                bool handle_remove_add = false;
                bool handle_where = false;
                bool handle_typeof = false;
                bool lambda_arguments_parsing;
                Location current_comment_location = Location.Null;
-               ArrayList escaped_identifiers;
+               List<Location> escaped_identifiers;
                int parsing_generic_less_than;
                
                //
@@ -243,6 +254,11 @@ namespace Mono.CSharp
                        get { return handle_typeof; }
                        set { handle_typeof = value; }
                }
+
+               public int TabSize {
+                       get { return tab_size; }
+                       set { tab_size = value; }
+               }
                
                public XmlCommentState doc_state {
                        get { return xml_doc_state; }
@@ -262,7 +278,7 @@ namespace Mono.CSharp
                void AddEscapedIdentifier (Location loc)
                {
                        if (escaped_identifiers == null)
-                               escaped_identifiers = new ArrayList ();
+                               escaped_identifiers = new List<Location> ();
 
                        escaped_identifiers.Add (loc);
                }
@@ -290,7 +306,7 @@ namespace Mono.CSharp
                // Values for the associated token returned
                //
                internal int putback_char;      // Used by repl only
-               Object val;
+               object val;
 
                //
                // Pre-processor
@@ -303,7 +319,7 @@ namespace Mono.CSharp
                //
                // pre-processor if stack state:
                //
-               Stack ifstack;
+               Stack<int> ifstack;
 
                static System.Text.StringBuilder string_builder;
 
@@ -341,7 +357,8 @@ namespace Mono.CSharp
                // on its own to deamiguate a token in behalf of the
                // parser.
                //
-               Stack position_stack = new Stack (2);
+               Stack<Position> position_stack = new Stack<Position> (2);
+
                class Position {
                        public int position;
                        public int line;
@@ -350,9 +367,10 @@ namespace Mono.CSharp
                        public bool hidden;
                        public int putback_char;
                        public int previous_col;
-                       public Stack ifstack;
+                       public Stack<int> ifstack;
                        public int parsing_generic_less_than;
                        public int current_token;
+                       public object val;
 
                        public Position (Tokenizer t)
                        {
@@ -363,10 +381,16 @@ namespace Mono.CSharp
                                hidden = t.hidden;
                                putback_char = t.putback_char;
                                previous_col = t.previous_col;
-                               if (t.ifstack != null && t.ifstack.Count != 0)
-                                       ifstack = (Stack)t.ifstack.Clone ();
+                               if (t.ifstack != null && t.ifstack.Count != 0) {
+                                       // There is no simple way to clone Stack<T> all
+                                       // methods reverse the order
+                                       var clone = t.ifstack.ToArray ();
+                                       Array.Reverse (clone);
+                                       ifstack = new Stack<int> (clone);
+                               }
                                parsing_generic_less_than = t.parsing_generic_less_than;
                                current_token = t.current_token;
+                               val = t.val;
                        }
                }
                
@@ -377,7 +401,7 @@ namespace Mono.CSharp
 
                public void PopPosition ()
                {
-                       Position p = (Position) position_stack.Pop ();
+                       Position p = position_stack.Pop ();
 
                        reader.Position = p.position;
                        ref_line = p.ref_line;
@@ -389,6 +413,7 @@ namespace Mono.CSharp
                        ifstack = p.ifstack;
                        parsing_generic_less_than = p.parsing_generic_less_than;
                        current_token = p.current_token;
+                       val = p.val;
                }
 
                // Do not reset the position, ignore it.
@@ -726,6 +751,11 @@ namespace Mono.CSharp
 
                        xml_comment_buffer = new StringBuilder ();
 
+                       if (Environment.OSVersion.Platform == PlatformID.Win32NT)
+                               tab_size = 4;
+                       else
+                               tab_size = 8;
+
                        //
                        // FIXME: This could be `Location.Push' but we have to
                        // find out why the MS compiler allows this
@@ -762,8 +792,7 @@ namespace Mono.CSharp
 
                //
                // Open parens micro parser. Detects both lambda and cast ambiguity.
-               //
-               
+               //      
                int TokenizeOpenParens ()
                {
                        int ptoken;
@@ -784,12 +813,8 @@ namespace Mono.CSharp
                                        //
                                        // Expression inside parens is lambda, (int i) => 
                                        //
-                                       if (current_token == Token.ARROW) {
-                                               if (RootContext.Version <= LanguageVersion.ISO_2)
-                                                       Report.FeatureIsNotAvailable (Location, "lambda expressions");
-
+                                       if (current_token == Token.ARROW)
                                                return Token.OPEN_PARENS_LAMBDA;
-                                       }
 
                                        //
                                        // Expression inside parens is single type, (int[])
@@ -806,12 +831,7 @@ namespace Mono.CSharp
                                                case Token.BANG:
                                                case Token.TILDE:
                                                case Token.IDENTIFIER:
-                                               case Token.LITERAL_INTEGER:
-                                               case Token.LITERAL_FLOAT:
-                                               case Token.LITERAL_DOUBLE:
-                                               case Token.LITERAL_DECIMAL:
-                                               case Token.LITERAL_CHARACTER:
-                                               case Token.LITERAL_STRING:
+                                               case Token.LITERAL:
                                                case Token.BASE:
                                                case Token.CHECKED:
                                                case Token.DELEGATE:
@@ -1054,8 +1074,7 @@ namespace Mono.CSharp
                        case Token.TRUE:
                        case Token.FALSE:
                        case Token.NULL:
-                       case Token.LITERAL_INTEGER:
-                       case Token.LITERAL_STRING:
+                       case Token.LITERAL:
                                return Token.INTERR;
                        }
 
@@ -1070,12 +1089,7 @@ namespace Mono.CSharp
                        current_token = Token.NONE;
                        int next_token;
                        switch (xtoken ()) {
-                       case Token.LITERAL_INTEGER:
-                       case Token.LITERAL_STRING:
-                       case Token.LITERAL_CHARACTER:
-                       case Token.LITERAL_DECIMAL:
-                       case Token.LITERAL_DOUBLE:
-                       case Token.LITERAL_FLOAT:
+                       case Token.LITERAL:
                        case Token.TRUE:
                        case Token.FALSE:
                        case Token.NULL:
@@ -1177,24 +1191,18 @@ namespace Mono.CSharp
                        return (e >= '0' && e <= '9') || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
                }
 
-               static int real_type_suffix (int c)
+               static TypeCode real_type_suffix (int c)
                {
-                       int t;
-
                        switch (c){
                        case 'F': case 'f':
-                               t =  Token.LITERAL_FLOAT;
-                               break;
+                               return TypeCode.Single;
                        case 'D': case 'd':
-                               t = Token.LITERAL_DOUBLE;
-                               break;
+                               return TypeCode.Double;
                        case 'M': case 'm':
-                                t= Token.LITERAL_DECIMAL;
-                               break;
+                               return TypeCode.Decimal;
                        default:
-                               return Token.NONE;
+                               return TypeCode.Empty;
                        }
-                       return t;
                }
 
                int integer_type_suffix (ulong ul, int c)
@@ -1240,38 +1248,40 @@ namespace Mono.CSharp
                        }
 
                        if (is_long && is_unsigned){
-                               val = ul;
-                               return Token.LITERAL_INTEGER;
-                       } else if (is_unsigned){
+                               val = new ULongLiteral (ul, Location);
+                               return Token.LITERAL;
+                       }
+                       
+                       if (is_unsigned){
                                // uint if possible, or ulong else.
 
                                if ((ul & 0xffffffff00000000) == 0)
-                                       val = (uint) ul;
+                                       val = new UIntLiteral ((uint) ul, Location);
                                else
-                                       val = ul;
+                                       val = new ULongLiteral (ul, Location);
                        } else if (is_long){
                                // long if possible, ulong otherwise
                                if ((ul & 0x8000000000000000) != 0)
-                                       val = ul;
+                                       val = new ULongLiteral (ul, Location);
                                else
-                                       val = (long) ul;
+                                       val = new LongLiteral ((long) ul, Location);
                        } else {
                                // int, uint, long or ulong in that order
                                if ((ul & 0xffffffff00000000) == 0){
                                        uint ui = (uint) ul;
                                        
                                        if ((ui & 0x80000000) != 0)
-                                               val = ui;
+                                               val = new UIntLiteral (ui, Location);
                                        else
-                                               val = (int) ui;
+                                               val = new IntLiteral ((int) ui, Location);
                                } else {
                                        if ((ul & 0x8000000000000000) != 0)
-                                               val = ul;
+                                               val = new ULongLiteral (ul, Location);
                                        else
-                                               val = (long) ul;
+                                               val = new LongLiteral ((long) ul, Location);
                                }
                        }
-                       return Token.LITERAL_INTEGER;
+                       return Token.LITERAL;
                }
                                
                //
@@ -1300,51 +1310,49 @@ namespace Mono.CSharp
                        } catch (OverflowException) {
                                error_details = "Integral constant is too large";
                                Report.Error (1021, Location, error_details);
-                               val = 0ul;
-                               return Token.LITERAL_INTEGER;
+                               val = new IntLiteral (0, Location);
+                               return Token.LITERAL;
                        }
                        catch (FormatException) {
                                Report.Error (1013, Location, "Invalid number");
-                               val = 0ul;
-                               return Token.LITERAL_INTEGER;
+                               val = new IntLiteral (0, Location);
+                               return Token.LITERAL;
                        }
                }
                
-               int adjust_real (int t)
+               int adjust_real (TypeCode t)
                {
                        string s = new String (number_builder, 0, number_pos);
                        const string error_details = "Floating-point constant is outside the range of type `{0}'";
 
                        switch (t){
-                       case Token.LITERAL_DECIMAL:
+                       case TypeCode.Decimal:
                                try {
-                                       val = System.Decimal.Parse (s, styles, csharp_format_info);
+                                       val = new DecimalLiteral (decimal.Parse (s, styles, csharp_format_info), Location);
                                } catch (OverflowException) {
-                                       val = 0m;     
+                                       val = new DecimalLiteral (0, Location);
                                        Report.Error (594, Location, error_details, "decimal");
                                }
                                break;
-                       case Token.LITERAL_FLOAT:
+                       case TypeCode.Single:
                                try {
-                                       val = float.Parse (s, styles, csharp_format_info);
+                                       val = new FloatLiteral (float.Parse (s, styles, csharp_format_info), Location);
                                } catch (OverflowException) {
-                                       val = 0.0f;     
+                                       val = new FloatLiteral (0, Location);
                                        Report.Error (594, Location, error_details, "float");
                                }
                                break;
-                               
-                       case Token.LITERAL_DOUBLE:
-                       case Token.NONE:
-                               t = Token.LITERAL_DOUBLE;
+                       default:
                                try {
-                                       val = System.Double.Parse (s, styles, csharp_format_info);
+                                       val = new DoubleLiteral (double.Parse (s, styles, csharp_format_info), Location);
                                } catch (OverflowException) {
-                                       val = 0.0;     
+                                       val = new DoubleLiteral (0, Location);
                                        Report.Error (594, Location, error_details, "double");
                                }
                                break;
                        }
-                       return t;
+
+                       return Token.LITERAL;
                }
 
                int handle_hex ()
@@ -1370,13 +1378,13 @@ namespace Mono.CSharp
                        } catch (OverflowException){
                                error_details = "Integral constant is too large";
                                Report.Error (1021, Location, error_details);
-                               val = 0ul;
-                               return Token.LITERAL_INTEGER;
+                               val = new IntLiteral (0, Location);
+                               return Token.LITERAL;
                        }
                        catch (FormatException) {
                                Report.Error (1013, Location, "Invalid number");
-                               val = 0ul;
-                               return Token.LITERAL_INTEGER;
+                               val = new IntLiteral (0, Location);
+                               return Token.LITERAL;
                        }
                        
                        return integer_type_suffix (ul, peek_char ());
@@ -1388,7 +1396,6 @@ namespace Mono.CSharp
                int is_number (int c)
                {
                        bool is_real = false;
-                       int type;
 
                        number_pos = 0;
 
@@ -1445,21 +1452,21 @@ namespace Mono.CSharp
                                c = get_char ();
                        }
 
-                       type = real_type_suffix (c);
-                       if (type == Token.NONE && !is_real){
+                       var type = real_type_suffix (c);
+                       if (type == TypeCode.Empty && !is_real){
                                putback (c);
                                return adjust_int (c);
-                       } else 
-                               is_real = true;
+                       }
+
+                       is_real = true;
 
-                       if (type == Token.NONE){
+                       if (type == TypeCode.Empty){
                                putback (c);
                        }
                        
                        if (is_real)
                                return adjust_real (type);
 
-                       Console.WriteLine ("This should not be reached");
                        throw new Exception ("Is Number should never reach this point");
                }
 
@@ -1969,9 +1976,9 @@ namespace Mono.CSharp
 
                        if (arg.StartsWith (w_restore)) {
                                int[] codes = ParseNumbers (arg.Substring (w_restore.Length));
-                               Hashtable w_table = Report.warning_ignore_table;
+                               var w_table = Report.warning_ignore_table;
                                foreach (int code in codes) {
-                                       if (w_table != null && w_table.Contains (code))
+                                       if (w_table != null && w_table.ContainsKey (code))
                                                Report.Warning (1635, 1, Location, "Cannot restore warning `CS{0:0000}' because it was disabled globally", code);
                                        Report.RegisterWarningRegion (Location).WarningEnable (Location, code, Report);
                                }
@@ -2241,7 +2248,7 @@ namespace Mono.CSharp
                                        Error_UnexpectedDirective ("no #region for this #endregion");
                                        return true;
                                }
-                               int pop = (int) ifstack.Pop ();
+                               int pop = ifstack.Pop ();
                                        
                                if ((pop & REGION) == 0)
                                        Report.Error (1027, Location, "Expected `#endif' directive");
@@ -2250,13 +2257,13 @@ namespace Mono.CSharp
                                
                        case "if":
                                if (ifstack == null)
-                                       ifstack = new Stack (2);
+                                       ifstack = new Stack<int> (2);
 
                                int flags = region_directive ? REGION : 0;
                                if (ifstack.Count == 0){
                                        flags |= PARENT_TAKING;
                                } else {
-                                       int state = (int) ifstack.Peek ();
+                                       int state = ifstack.Peek ();
                                        if ((state & TAKING) != 0) {
                                                flags |= PARENT_TAKING;
                                        }
@@ -2274,7 +2281,7 @@ namespace Mono.CSharp
                                        Error_UnexpectedDirective ("no #if for this #endif");
                                        return true;
                                } else {
-                                       pop = (int) ifstack.Pop ();
+                                       pop = ifstack.Pop ();
                                        
                                        if ((pop & REGION) != 0)
                                                Report.Error (1038, Location, "#endregion directive expected");
@@ -2286,7 +2293,7 @@ namespace Mono.CSharp
                                        if (ifstack.Count == 0)
                                                return true;
 
-                                       int state = (int) ifstack.Peek ();
+                                       int state = ifstack.Peek ();
                                        return (state & TAKING) != 0;
                                }
 
@@ -2295,7 +2302,7 @@ namespace Mono.CSharp
                                        Error_UnexpectedDirective ("no #if for this #elif");
                                        return true;
                                } else {
-                                       int state = (int) ifstack.Pop ();
+                                       int state = ifstack.Pop ();
 
                                        if ((state & REGION) != 0) {
                                                Report.Error (1038, Location, "#endregion directive expected");
@@ -2326,7 +2333,7 @@ namespace Mono.CSharp
                                        Error_UnexpectedDirective ("no #if for this #else");
                                        return true;
                                } else {
-                                       int state = (int) ifstack.Peek ();
+                                       int state = ifstack.Peek ();
 
                                        if ((state & REGION) != 0) {
                                                Report.Error (1038, Location, "#endregion directive expected");
@@ -2425,8 +2432,8 @@ namespace Mono.CSharp
                                                get_char ();
                                                continue;
                                        } else {
-                                               val = string_builder.ToString ();
-                                               return Token.LITERAL_STRING;
+                                               val = new StringLiteral (string_builder.ToString (), Location);
+                                               return Token.LITERAL;
                                        }
                                }
 
@@ -2575,7 +2582,7 @@ namespace Mono.CSharp
                        while ((c = get_char ()) != -1) {
                                switch (c) {
                                case '\t':
-                                       col = ((col + 8) / 8) * 8;
+                                       col = ((col + tab_size) / tab_size) * tab_size;
                                        continue;
 
                                case ' ':
@@ -2622,8 +2629,10 @@ namespace Mono.CSharp
                                        // To block doccomment inside attribute declaration.
                                        if (doc_state == XmlCommentState.Allowed)
                                                doc_state = XmlCommentState.NotAllowed;
+                                       val = LocatedToken.CreateOptional (ref_line, col);
                                        return Token.OPEN_BRACKET;
                                case ']':
+                                       val = LocatedToken.CreateOptional (ref_line, col);
                                        return Token.CLOSE_BRACKET;
                                case '(':
                                        val = LocatedToken.Create (ref_line, col);
@@ -2671,22 +2680,29 @@ namespace Mono.CSharp
 
                                        return Token.OPEN_PARENS;
                                case ')':
+                                       val = LocatedToken.CreateOptional (ref_line, col);
                                        return Token.CLOSE_PARENS;
                                case ',':
+                                       val = LocatedToken.CreateOptional (ref_line, col);
                                        return Token.COMMA;
                                case ';':
+                                       val = LocatedToken.CreateOptional (ref_line, col);
                                        return Token.SEMICOLON;
                                case '~':
+                                       val = LocatedToken.Create (ref_line, col);
                                        return Token.TILDE;
                                case '?':
+                                       val = LocatedToken.Create (ref_line, col);
                                        return TokenizePossibleNullableType ();
                                case '<':
+                                       val = LocatedToken.Create (ref_line, col);
                                        if (parsing_generic_less_than++ > 0)
                                                return Token.OP_GENERICS_LT;
 
                                        return TokenizeLessThan ();
 
                                case '>':
+                                       val = LocatedToken.Create (ref_line, col);
                                        d = peek_char ();
 
                                        if (d == '='){
@@ -2713,6 +2729,7 @@ namespace Mono.CSharp
                                        return Token.OP_GT;
 
                                case '+':
+                                       val = LocatedToken.Create (ref_line, col);
                                        d = peek_char ();
                                        if (d == '+') {
                                                d = Token.OP_INC;
@@ -2725,6 +2742,7 @@ namespace Mono.CSharp
                                        return d;
 
                                case '-':
+                                       val = LocatedToken.Create (ref_line, col);
                                        d = peek_char ();
                                        if (d == '-') {
                                                d = Token.OP_DEC;
@@ -2739,6 +2757,7 @@ namespace Mono.CSharp
                                        return d;
 
                                case '!':
+                                       val = LocatedToken.Create (ref_line, col);
                                        if (peek_char () == '='){
                                                get_char ();
                                                return Token.OP_NE;
@@ -2746,6 +2765,7 @@ namespace Mono.CSharp
                                        return Token.BANG;
 
                                case '=':
+                                       val = LocatedToken.Create (ref_line, col);
                                        d = peek_char ();
                                        if (d == '='){
                                                get_char ();
@@ -2759,6 +2779,7 @@ namespace Mono.CSharp
                                        return Token.ASSIGN;
 
                                case '&':
+                                       val = LocatedToken.Create (ref_line, col);
                                        d = peek_char ();
                                        if (d == '&'){
                                                get_char ();
@@ -2771,6 +2792,7 @@ namespace Mono.CSharp
                                        return Token.BITWISE_AND;
 
                                case '|':
+                                       val = LocatedToken.Create (ref_line, col);
                                        d = peek_char ();
                                        if (d == '|'){
                                                get_char ();
@@ -2783,16 +2805,17 @@ namespace Mono.CSharp
                                        return Token.BITWISE_OR;
 
                                case '*':
+                                       val = LocatedToken.Create (ref_line, col);
                                        if (peek_char () == '='){
                                                get_char ();
                                                return Token.OP_MULT_ASSIGN;
                                        }
-                                       val = LocatedToken.Create (ref_line, col);
                                        return Token.STAR;
 
                                case '/':
                                        d = peek_char ();
                                        if (d == '='){
+                                               val = LocatedToken.Create (ref_line, col);
                                                get_char ();
                                                return Token.OP_DIV_ASSIGN;
                                        }
@@ -2869,6 +2892,7 @@ namespace Mono.CSharp
                                        return Token.DIV;
 
                                case '%':
+                                       val = LocatedToken.Create (ref_line, col);
                                        if (peek_char () == '='){
                                                get_char ();
                                                return Token.OP_MOD_ASSIGN;
@@ -2876,6 +2900,7 @@ namespace Mono.CSharp
                                        return Token.PERCENT;
 
                                case '^':
+                                       val = LocatedToken.Create (ref_line, col);
                                        if (peek_char () == '='){
                                                get_char ();
                                                return Token.OP_XOR_ASSIGN;
@@ -2883,6 +2908,7 @@ namespace Mono.CSharp
                                        return Token.CARRET;
 
                                case ':':
+                                       val = LocatedToken.Create (ref_line, col);
                                        if (peek_char () == ':') {
                                                get_char ();
                                                return Token.DOUBLE_COLON;
@@ -3016,7 +3042,7 @@ namespace Mono.CSharp
                        if (d != 0)
                                throw new NotImplementedException ();
 
-                       val = (char) c;
+                       val = new CharLiteral ((char) c, Location);
                        c = get_char ();
 
                        if (c != '\'') {
@@ -3030,7 +3056,7 @@ namespace Mono.CSharp
                                return Token.ERROR;
                        }
 
-                       return Token.LITERAL_CHARACTER;
+                       return Token.LITERAL;
                }
 
                int TokenizeLessThan ()
@@ -3190,7 +3216,7 @@ namespace Mono.CSharp
                public void cleanup ()
                {
                        if (ifstack != null && ifstack.Count >= 1) {
-                               int state = (int) ifstack.Pop ();
+                               int state = ifstack.Pop ();
                                if ((state & REGION) != 0)
                                        Report.Error (1038, Location, "#endregion directive expected");
                                else