X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmbas%2Fmb-tokenizer.cs;h=788a8d0ab3a560a457fcc2cff9d845aadac4b23d;hb=0799426c96b85f3b346de122a02b76fc9a01a966;hp=c7cfaa760a55985cefe64fe5f61de574e6675cc3;hpb=7c36d2ed0003371f775489c81430bddf83faf04c;p=mono.git diff --git a/mcs/mbas/mb-tokenizer.cs b/mcs/mbas/mb-tokenizer.cs index c7cfaa760a5..788a8d0ab3a 100644 --- a/mcs/mbas/mb-tokenizer.cs +++ b/mcs/mbas/mb-tokenizer.cs @@ -2,7 +2,7 @@ // Mono.MonoBASIC.Tokenizer.cs: The Tokenizer for the MonoBASIC compiler // // Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com) -// +// : Manjula GHM (mmanjula@novell.com) // Based on cs-tokenizer.cs by Miguel de Icaza (miguel@gnu.org) // // Licensed under the terms of the GNU GPL @@ -27,13 +27,12 @@ namespace Mono.MonoBASIC public class Tokenizer : yyParser.yyInput { TextReader reader; - // TODO: public SourceFile file_name; - public string file_name; - public string ref_name; - public int ref_line = 1; - public int line = 1; - public int col = 1; - public int current_token = Token.EOL; + string file_name; + string ref_name; + int ref_line = 0; + int line = 0; + int col = 1; + public int current_token = Token.ERROR; bool handle_get_set = false; bool cant_have_a_type_character = false; @@ -71,28 +70,13 @@ namespace Mono.MonoBASIC static NumberStyles styles; static NumberFormatInfo csharp_format_info; - // - // Pre-processor - // - Hashtable defines; - - const int TAKING = 1; - const int TAKEN_BEFORE = 2; - const int ELSE_SEEN = 4; - const int PARENT_TAKING = 8; - const int REGION = 16; - - // - // pre-processor if stack state: - // - Stack ifstack; - // // Values for the associated token returned // StringBuilder number; - int putback_char; + int putback_char = -1; Object val; + long lon = 0; // // Details about the error encoutered by the tokenizer @@ -104,13 +88,45 @@ namespace Mono.MonoBASIC return error_details; } } + + public string Source { + get { + return file_name; + } + + set { + file_name = value; + ref_name = value; + Location.SetCurrentSource(file_name); + } + } + + public string EffectiveSource { + get { + return ref_name; + } + set { + ref_name = value; + Location.SetCurrentSource(ref_name); + } + } + public int Line { get { return line; } } + public int EffectiveLine { + get { + return ref_line; + } + set { + ref_line = value; + } + } + public int Col { get { return col; @@ -130,7 +146,7 @@ namespace Mono.MonoBASIC keywords.Add ("as", Token.AS); keywords.Add ("assembly", Token.ASSEMBLY); keywords.Add ("auto", Token.AUTO); - keywords.Add ("binary", Token.BINARY); + keywords.Add ("binary", Token.BINARY); // Not a VB.NET Keyword keywords.Add ("boolean", Token.BOOLEAN); keywords.Add ("byref", Token.BYREF); keywords.Add ("byte", Token.BYTE); @@ -149,7 +165,7 @@ namespace Mono.MonoBASIC keywords.Add ("class", Token.CLASS); keywords.Add ("clng", Token.CLNG); keywords.Add ("cobj", Token.COBJ); - keywords.Add ("compare", Token.COMPARE); + keywords.Add ("compare", Token.COMPARE); // Not a VB.NET Keyword keywords.Add ("const", Token.CONST); keywords.Add ("cshort", Token.CSHORT); keywords.Add ("csng", Token.CSNG); @@ -161,25 +177,28 @@ namespace Mono.MonoBASIC keywords.Add ("default", Token.DEFAULT); keywords.Add ("delegate", Token.DELEGATE); keywords.Add ("dim", Token.DIM); + keywords.Add ("directcast", Token.DIRECTCAST); keywords.Add ("do", Token.DO); keywords.Add ("double", Token.DOUBLE); keywords.Add ("each", Token.EACH); keywords.Add ("else", Token.ELSE); keywords.Add ("elseif", Token.ELSEIF); keywords.Add ("end", Token.END); + keywords.Add ("endif", Token.ENDIF); // An unused VB.NET keyword keywords.Add ("enum", Token.ENUM); keywords.Add ("erase", Token.ERASE); keywords.Add ("error", Token.ERROR); keywords.Add ("event", Token.EVENT); keywords.Add ("exit", Token.EXIT); - keywords.Add ("explicit", Token.EXPLICIT); + keywords.Add ("explicit", Token.EXPLICIT); // Not a VB.NET keyword keywords.Add ("false", Token.FALSE); keywords.Add ("finally", Token.FINALLY); keywords.Add ("for", Token.FOR); keywords.Add ("friend", Token.FRIEND); keywords.Add ("function", Token.FUNCTION); keywords.Add ("get", Token.GET); - //keywords.Add ("gettype", Token.GETTYPE); + keywords.Add ("gettype", Token.GETTYPE); + keywords.Add ("gosub", Token.GOSUB); // An unused VB.NET keyword keywords.Add ("goto", Token.GOTO); keywords.Add ("handles", Token.HANDLES); keywords.Add ("if", Token.IF); @@ -190,9 +209,9 @@ namespace Mono.MonoBASIC keywords.Add ("integer", Token.INTEGER); keywords.Add ("interface", Token.INTERFACE); keywords.Add ("is", Token.IS); - keywords.Add ("let ", Token.LET ); + keywords.Add ("let ", Token.LET ); // An unused VB.NET keyword keywords.Add ("lib ", Token.LIB ); - keywords.Add ("like ", Token.LIKE ); + keywords.Add ("like", Token.LIKE ); keywords.Add ("long", Token.LONG); keywords.Add ("loop", Token.LOOP); keywords.Add ("me", Token.ME); @@ -210,7 +229,7 @@ namespace Mono.MonoBASIC keywords.Add ("notinheritable", Token.NOTINHERITABLE); keywords.Add ("notoverridable", Token.NOTOVERRIDABLE); keywords.Add ("object", Token.OBJECT); - keywords.Add ("off", Token.OFF); + keywords.Add ("off", Token.OFF); // Not a VB.NET Keyword keywords.Add ("on", Token.ON); keywords.Add ("option", Token.OPTION); keywords.Add ("optional", Token.OPTIONAL); @@ -238,16 +257,16 @@ namespace Mono.MonoBASIC keywords.Add ("shared", Token.SHARED); keywords.Add ("short", Token.SHORT); keywords.Add ("single", Token.SINGLE); - keywords.Add ("sizeof", Token.SIZEOF); + keywords.Add ("sizeof", Token.SIZEOF); // Not a VB.NET Keyword keywords.Add ("static", Token.STATIC); keywords.Add ("step", Token.STEP); keywords.Add ("stop", Token.STOP); - keywords.Add ("strict", Token.STRICT); + keywords.Add ("strict", Token.STRICT); // Not a VB.NET Keyword keywords.Add ("string", Token.STRING); keywords.Add ("structure", Token.STRUCTURE); keywords.Add ("sub", Token.SUB); keywords.Add ("synclock", Token.SYNCLOCK); - keywords.Add ("text", Token.TEXT); + keywords.Add ("text", Token.TEXT); // Not a VB.NET Keyword keywords.Add ("then", Token.THEN); keywords.Add ("throw", Token.THROW); keywords.Add ("to", Token.TO); @@ -256,7 +275,8 @@ namespace Mono.MonoBASIC keywords.Add ("typeof", Token.TYPEOF); keywords.Add ("unicode", Token.UNICODE); keywords.Add ("until", Token.UNTIL); - keywords.Add ("variant", Token.VARIANT); + keywords.Add ("variant", Token.VARIANT); // An unused VB.NET keyword + keywords.Add ("wend", Token.WEND); // An unused VB.NET keyword keywords.Add ("when", Token.WHEN); keywords.Add ("while", Token.WHILE); keywords.Add ("with", Token.WITH); @@ -270,9 +290,6 @@ namespace Mono.MonoBASIC } - // - // Class initializer - // static Tokenizer () { initTokens (); @@ -283,11 +300,13 @@ namespace Mono.MonoBASIC public Tokenizer (System.IO.TextReader input, string fname, ArrayList defines) { - this.ref_name = fname; + this.Source = fname; + reader = input; - putback_char = -1; - - Location.Push (fname); + + // putback an EOL at the beginning of a stream. This is a convenience that + // allows pre-processor directives to be added to the beginning of a vb file. + putback('\n'); } bool is_keyword (string name) @@ -312,16 +331,6 @@ namespace Mono.MonoBASIC } } - void define (string def) - { - if (!RootContext.AllDefines.Contains(def)){ - RootContext.AllDefines [def] = true; - } - if (defines.Contains (def)) - return; - defines [def] = true; - } - public bool PropertyParsing { get { return handle_get_set; @@ -387,24 +396,24 @@ namespace Mono.MonoBASIC return Token.ERROR; return Token.PERCENT; case '#': - if (!tokens_seen) + if(tokens_seen) { - workout_preprocessing_directive(); - return Token.NONE; + if (cant_have_a_type_character) + return ExtractDateTimeLiteral(); + else + return Token.NUMBER_SIGN; + } + else + { + tokens_seen = true; + return Token.HASH; } - if (cant_have_a_type_character) - return ExtractDateTimeLiteral(); - return Token.NUMBER_SIGN; case '&': if (!cant_have_a_type_character) return Token.LONGTYPECHAR; t = handle_integer_literal_in_other_bases(d); if (t == Token.NONE) { - if (d == '=') { - doread = true; - t = Token.OP_CONCAT_ASSIGN; - } else - t = Token.OP_CONCAT; + t = Token.OP_CONCAT; } return t; } @@ -412,20 +421,13 @@ namespace Mono.MonoBASIC if (c == '+'){ if (d == '+') t = Token.OP_INC; - else if (d == '=') - t = Token.OP_ADD_ASSIGN; - else + else return Token.PLUS; doread = true; return t; } if (c == '-'){ - if (d == '=') - t = Token.OP_SUB_ASSIGN; - else - return Token.MINUS; - doread = true; - return t; + return Token.MINUS; } if (c == '='){ @@ -433,34 +435,18 @@ namespace Mono.MonoBASIC } if (c == '*'){ - if (d == '='){ - doread = true; - return Token.OP_MULT_ASSIGN; - } return Token.STAR; } if (c == '/'){ - if (d == '='){ - doread = true; - return Token.OP_DIV_ASSIGN; - } return Token.DIV; } if (c == '\\'){ - if (d == '='){ - doread = true; - return Token.OP_IDIV_ASSIGN; - } return Token.OP_IDIV; } if (c == '^'){ - if (d == '='){ - doread = true; - return Token.OP_EXP_ASSIGN; - } return Token.OP_EXP; } @@ -513,7 +499,6 @@ namespace Mono.MonoBASIC if (c != -1) number.Append ((char) c); - while ((d = peekChar ()) != -1){ if (Char.IsDigit ((char)d)){ number.Append ((char) d); @@ -556,7 +541,16 @@ namespace Mono.MonoBASIC switch (c){ case 'S': case 's': t = Token.LITERAL_INTEGER; // SHORT ? - val = ((IConvertible)val).ToInt16(null); + + // hexadecimal literals - like &H8000S is "-32768" + // and not an overflow exception + // Check for other literals ??? + + if(lon == 32768) { + val = (short) lon; + } + else + val = ((IConvertible)val).ToInt16(null); break; case 'I': case 'i': t = Token.LITERAL_INTEGER; @@ -630,7 +624,8 @@ namespace Mono.MonoBASIC } else break; } - return System.Int64.Parse (hexNumber.ToString(), NumberStyles.HexNumber); + lon = System.Int64.Parse (hexNumber.ToString(), NumberStyles.HexNumber); + return lon; } long octal_digits () @@ -677,12 +672,14 @@ namespace Mono.MonoBASIC bool is_real = false; number = new StringBuilder (); int type; + bool non_prefixdecimal = false; //To capture decimals like .50 number.Length = 0; if (Char.IsDigit ((char)c)){ decimal_digits (c); - c = peekChar (); + c = peekChar (); + non_prefixdecimal = true; } // @@ -690,6 +687,8 @@ namespace Mono.MonoBASIC // "1.1" vs "1.ToString()" (LITERAL_SINGLE vs NUMBER DOT IDENTIFIER) // if (c == '.'){ + if (non_prefixdecimal == false) + putback ('.'); if (decimal_digits (getChar())){ is_real = true; c = peekChar (); @@ -746,6 +745,7 @@ namespace Mono.MonoBASIC return putback_char; return reader.Peek (); } + void putback (int c) { @@ -772,27 +772,37 @@ namespace Mono.MonoBASIC private bool IsEOL(int currentChar) { - if (currentChar == 0x0D) - { + bool retVal; + + if (currentChar == 0x0D) { if (peekChar() == 0x0A) // if it is a CR-LF pair consume LF also getChar(); - return true; + retVal = true; + } + else { + retVal = (currentChar == -1 || currentChar == 0x0A || currentChar == 0x2028 || currentChar == 0x2029); + } + + if(retVal) { + nextLine(); } - return (currentChar == -1 || currentChar == 0x0A || currentChar == 0x2028 || currentChar == 0x2029); + + return retVal; } private int DropComments() { - int d; - while (!IsEOL(d = getChar ())) + //int d; + while (!IsEOL(/*d =*/ getChar ())) col++; - line++; - ref_line++; - col = 0; return Token.EOL; } + + public bool putbacktoken = false; + public bool flag = false; + int next_token; public int token () { @@ -800,6 +810,14 @@ namespace Mono.MonoBASIC do { current_token = xtoken (); + if(current_token == Token.END) { + next_token = xtoken(); + putbacktoken = true; + if (next_token == Token.EOL) + return Token.END_EOL; + else + return Token.END; + } if (current_token == 0) return Token.EOF; if (current_token == Token.REM) @@ -837,7 +855,7 @@ namespace Mono.MonoBASIC cant_have_a_type_character = false; - return id.ToString (); + return id.ToString(); } private bool is_doublequote(int currentChar) @@ -869,6 +887,11 @@ namespace Mono.MonoBASIC bool doread = false; int c; + if (putbacktoken == true) { + putbacktoken = false; + return next_token; + } + val = null; for (;(c = getChar ()) != -1; col++) { @@ -881,7 +904,8 @@ namespace Mono.MonoBASIC c = getChar (); } } - + + // white space if (is_whitespace(c)) { // expand tabs for location @@ -898,7 +922,6 @@ namespace Mono.MonoBASIC // Handle EOL. if (IsEOL(c)) { - nextLine(); if (current_token == Token.EOL) // if last token was also EOL keep skipping continue; return Token.EOL; @@ -935,6 +958,14 @@ namespace Mono.MonoBASIC } // handle numeric literals + + if (Char.IsDigit ((char) c)) + { + cant_have_a_type_character = true; + tokens_seen = true; + return is_number (c); + } + if (c == '.') { cant_have_a_type_character = true; @@ -943,14 +974,6 @@ namespace Mono.MonoBASIC return is_number (c); return Token.DOT; } - - if (Char.IsDigit ((char) c)) - { - cant_have_a_type_character = true; - tokens_seen = true; - return is_number (c); - } - if ((t = is_punct ((char)c, ref doread)) != Token.ERROR) { cant_have_a_type_character = true; @@ -987,7 +1010,6 @@ namespace Mono.MonoBASIC return Token.LITERAL_DATE; } if (IsEOL(c)) { - nextLine(); break; } if (c == '-') @@ -1025,9 +1047,7 @@ namespace Mono.MonoBASIC } } - if (IsEOL(c)) - { - nextLine(); + if (IsEOL(c)) { return Token.ERROR; } @@ -1037,44 +1057,6 @@ namespace Mono.MonoBASIC return Token.ERROR; } - private void workout_preprocessing_directive() - { - int c; - bool cont = true; - - start_again: - - cont = handle_preprocessing_directive (cont); - - if (cont) { - col = 0; - return; - } - col = 1; - - bool skipping = false; - for (;(c = getChar ()) != -1; col++) { - if (is_whitespace(c)) - continue; - if (IsEOL(c)) { - col = 0; - line++; - ref_line++; - skipping = false; - continue; - } - if (c != '#') { - skipping = true; - continue; - } - if (c == '#' && !skipping) - goto start_again; - } - tokens_seen = false; - if (c == -1) - Report.Error (1027, Location, "#endif/#endregion expected"); - } - static IFormatProvider enUSculture = new CultureInfo("en-US", true); private DateTime ParseDateLiteral(StringBuilder value) @@ -1098,542 +1080,19 @@ namespace Mono.MonoBASIC return new DateTime(); } - - public void cleanup () - { -/* borrowed from mcs - have to work it to have preprocessing in mbas - - if (ifstack != null && ifstack.Count >= 1) { - int state = (int) ifstack.Pop (); - if ((state & REGION) != 0) - Report.Error (1038, "#endregion directive expected"); - else - Report.Error (1027, "#endif directive expected"); - } -*/ - } - - static StringBuilder static_cmd_arg = new StringBuilder (); - - void get_cmd_arg (out string cmd, out string arg) - { - int c; - - tokens_seen = false; - cmd = ""; - arg = ""; - - // skip over white space - while ((c = getChar ()) != -1 && (c != '\n') && (c != '\r') && ((c == ' ') || (c == '\t'))) - ; - - if (c == '\n'){ - line++; - ref_line++; - return; - } else if (c == '\r') - col = 0; - - static_cmd_arg.Length = 0; - static_cmd_arg.Append ((char) c); - - - while ((c = getChar ()) != -1 && (c != '\n') && (c != ' ') && (c != '\t') && (c != '\r')){ - static_cmd_arg.Append ((char) c); - } - - cmd = static_cmd_arg.ToString().ToLower(); - - if (c == '\n'){ - line++; - ref_line++; - return; - } else if (c == '\r') - col = 0; - - // skip over white space - while ((c = getChar ()) != -1 && (c != '\n') && (c != '\r') && ((c == ' ') || (c == '\t'))) - ; - - if (c == '\n'){ - line++; - ref_line++; - return; - } else if (c == '\r'){ - col = 0; - return; - } - - static_cmd_arg.Length = 0; - static_cmd_arg.Append ((char) c); - - while ((c = getChar ()) != -1 && (c != '\n') && (c != '\r')){ - static_cmd_arg.Append ((char) c); - } - - if (c == '\n'){ - line++; - ref_line++; - } else if (c == '\r') - col = 0; - arg = static_cmd_arg.ToString ().Trim (); - - if (cmd == "end" && arg.ToLower() == "region") { - cmd = "end region"; - arg = ""; - } - if (cmd == "end" && arg.ToLower() == "if") { - cmd = "end if"; - arg = ""; - } - - } - - // - // Handles the #line directive - // - bool PreProcessLine (string arg) - { - if (arg == "") - return false; - - if (arg == "default"){ - ref_line = line; - ref_name = file_name; - Location.Push (ref_name); - return true; - } - - try { - int pos; - - if ((pos = arg.IndexOf (' ')) != -1 && pos != 0){ - ref_line = System.Int32.Parse (arg.Substring (0, pos)); - pos++; - - char [] quotes = { '\"' }; - - string name = arg.Substring (pos). Trim (quotes); - ref_name = name; // TODO: Synchronize with mcs: Location.LookupFile (name); - Location.Push (ref_name); - } else { - ref_line = System.Int32.Parse (arg); - } - } catch { - return false; - } - - return true; - } - - // - // Handles #define and #undef - // - void PreProcessDefinition (bool is_define, string arg) + public void PositionCursorAtNextPreProcessorDirective() { - if (arg == "" || arg == "true" || arg == "false"){ - Report.Error (1001, Location, "Missing identifer to pre-processor directive"); - return; - } - - char[] whitespace = { ' ', '\t' }; - if (arg.IndexOfAny (whitespace) != -1){ - Report.Error (1025, Location, "Single-line comment or end-of-line expected"); - return; - } - - foreach (char c in arg){ - if (!Char.IsLetter (c) && (c != '_')){ - Report.Error (1001, Location, "Identifier expected"); - return; - } - } - - if (is_define){ - if (defines == null) - defines = new Hashtable (); - define (arg); - } else { - if (defines == null) - return; - if (defines.Contains (arg)) - defines.Remove (arg); - } - } - - bool eval_val (string s) - { - if (s == "true") - return true; - if (s == "false") - return false; + int t; - if (defines == null) - return false; - if (defines.Contains (s)) - return true; - - return false; - } - - bool pp_primary (ref string s) - { - s = s.Trim (); - int len = s.Length; - - if (len > 0){ - char c = s [0]; - - if (c == '('){ - s = s.Substring (1); - bool val = pp_expr (ref s); - if (s.Length > 0 && s [0] == ')'){ - s = s.Substring (1); - return val; - } - Error_InvalidDirective (); - return false; - } - - if (is_identifier_start_character (c)){ - int j = 1; + for(t = token(); t != Token.HASH && t != Token.EOF ; t = token()); - while (j < len){ - c = s [j]; - - if (is_identifier_part_character (c)){ - j++; - continue; - } - bool v = eval_val (s.Substring (0, j)); - s = s.Substring (j); - return v; - } - bool vv = eval_val (s); - s = ""; - return vv; - } - } - Error_InvalidDirective (); - return false; - } - - bool pp_unary (ref string s) - { - s = s.Trim (); - int len = s.Length; - - if (len > 0){ - if (s [0] == '!'){ - if (len > 1 && s [1] == '='){ - Error_InvalidDirective (); - return false; - } - s = s.Substring (1); - return ! pp_primary (ref s); - } else - return pp_primary (ref s); - } else { - Error_InvalidDirective (); - return false; - } - } - - bool pp_eq (ref string s) - { - bool va = pp_unary (ref s); - - s = s.Trim (); - int len = s.Length; - if (len > 0){ - if (s [0] == '='){ - if (len > 2 && s [1] == '='){ - s = s.Substring (2); - return va == pp_unary (ref s); - } else { - Error_InvalidDirective (); - return false; - } - } else if (s [0] == '!' && len > 1 && s [1] == '='){ - s = s.Substring (2); - - return va != pp_unary (ref s); - - } - } - - return va; - - } - - bool pp_and (ref string s) - { - bool va = pp_eq (ref s); - - s = s.Trim (); - int len = s.Length; - if (len > 0){ - if (s [0] == '&'){ - if (len > 2 && s [1] == '&'){ - s = s.Substring (2); - return (va & pp_eq (ref s)); - } else { - Error_InvalidDirective (); - return false; - } - } - } - return va; - } - - // - // Evaluates an expression for `#if' or `#elif' - // - bool pp_expr (ref string s) - { - bool va = pp_and (ref s); - s = s.Trim (); - int len = s.Length; - if (len > 0){ - char c = s [0]; - - if (c == '|'){ - if (len > 2 && s [1] == '|'){ - s = s.Substring (2); - return va | pp_expr (ref s); - } else { - Error_InvalidDirective (); - return false; - } - } - } + if(t == Token.EOF) + throw new ApplicationException("Unexpected EOF while looking for a pre-processor directive"); - return va; - } - - bool eval (string s) - { - bool v = pp_expr (ref s); - s = s.Trim (); - if (s.Length != 0){ - Error_InvalidDirective (); - return false; + if(t == Token.HASH) { + tokens_seen = false; + putback('#'); } - - return v; - } - - void Error_InvalidDirective () - { - Report.Error (1517, Location, "Invalid pre-processor directive"); - } - - void Error_UnexpectedDirective (string extra) - { - Report.Error ( - 1028, Location, - "Unexpected processor directive (" + extra + ")"); - } - - void Error_TokensSeen () - { - Report.Error ( - 1032, Location, - "Cannot define or undefine pre-processor symbols after a token in the file"); - } - - // - // if true, then the code continues processing the code - // if false, the code stays in a loop until another directive is - // reached. - // - bool handle_preprocessing_directive (bool caller_is_taking) - { - //char [] blank = { ' ', '\t' }; - string cmd, arg; - bool region_directive = false; - - get_cmd_arg (out cmd, out arg); - // Eat any trailing whitespaces and single-line comments - if (arg.IndexOf ("'") != -1) - arg = arg.Substring (0, arg.IndexOf ("//")); - arg = arg.TrimEnd (' ', '\t'); - - // - // The first group of pre-processing instructions is always processed - // - switch (cmd.ToLower()){ - case "line": - if (!PreProcessLine (arg)) - Report.Error ( - 1576, Location, - "Argument to #line directive is missing or invalid"); - return true; - - case "region": - region_directive = true; - arg = "true"; - goto case "if"; - - case "end region": - region_directive = true; - goto case "end if"; - - case "if": - if (arg == ""){ - Error_InvalidDirective (); - return true; - } - bool taking = false; - if (ifstack == null) - ifstack = new Stack (); - - if (ifstack.Count == 0){ - taking = true; - } else { - int state = (int) ifstack.Peek (); - if ((state & TAKING) != 0) - taking = true; - } - - if (eval (arg) && taking){ - int push = TAKING | TAKEN_BEFORE | PARENT_TAKING; - if (region_directive) - push |= REGION; - ifstack.Push (push); - return true; - } else { - int push = (taking ? PARENT_TAKING : 0); - if (region_directive) - push |= REGION; - ifstack.Push (push); - return false; - } - - case "end if": - if (ifstack == null || ifstack.Count == 0){ - Error_UnexpectedDirective ("no #if for this #end if"); - return true; - } else { - int pop = (int) ifstack.Pop (); - - if (region_directive && ((pop & REGION) == 0)) - Report.Error (1027, Location, "#end if directive expected"); - else if (!region_directive && ((pop & REGION) != 0)) - Report.Error (1038, Location, "#end region directive expected"); - - if (ifstack.Count == 0) - return true; - else { - int state = (int) ifstack.Peek (); - - if ((state & TAKING) != 0) - return true; - else - return false; - } - } - - case "elseif": - if (ifstack == null || ifstack.Count == 0){ - Error_UnexpectedDirective ("no #if for this #elif"); - return true; - } else { - int state = (int) ifstack.Peek (); - - if ((state & REGION) != 0) { - Report.Error (1038, Location, "#end region directive expected"); - return true; - } - - if ((state & ELSE_SEEN) != 0){ - Error_UnexpectedDirective ("#elif not valid after #else"); - return true; - } - - if ((state & (TAKEN_BEFORE | TAKING)) != 0) - return false; - - if (eval (arg) && ((state & PARENT_TAKING) != 0)){ - state = (int) ifstack.Pop (); - ifstack.Push (state | TAKING | TAKEN_BEFORE); - return true; - } else - return false; - } - - case "else": - if (ifstack == null || ifstack.Count == 0){ - Report.Error ( - 1028, Location, - "Unexpected processor directive (no #if for this #else)"); - return true; - } else { - int state = (int) ifstack.Peek (); - - if ((state & REGION) != 0) { - Report.Error (1038, Location, "#end region directive expected"); - return true; - } - - if ((state & ELSE_SEEN) != 0){ - Error_UnexpectedDirective ("#else within #else"); - return true; - } - - ifstack.Pop (); - - bool ret; - if ((state & TAKEN_BEFORE) == 0){ - ret = ((state & PARENT_TAKING) != 0); - } else - ret = false; - - if (ret) - state |= TAKING; - else - state &= ~TAKING; - - ifstack.Push (state | ELSE_SEEN); - - return ret; - } - } - - // - // These are only processed if we are in a `taking' block - // - if (!caller_is_taking) - return false; - - switch (cmd.ToLower()){ - case "define": - /* if (any_token_seen){ - Error_TokensSeen (); - return true; - } */ - PreProcessDefinition (true, arg); - return true; - - case "undef": - /* if (any_token_seen){ - Error_TokensSeen (); - return true; - } */ - PreProcessDefinition (false, arg); - return true; - - case "error": - Report.Error (1029, Location, "#error: '" + arg + "'"); - return true; - - case "warning": - Report.Warning (1030, Location, "#warning: '" + arg + "'"); - return true; - } - - Report.Error (1024, Location, "Preprocessor directive expected (got: '" + cmd + "')"); - return true; } }