]> git.sur5r.net Git - cc65/blobdiff - src/cc65/scanner.c
Fixed wrong code generation for
[cc65] / src / cc65 / scanner.c
index 435875800394cd44845bbd33c582a4bc902064ff..cc073e37313157786eea0c0e761245ce868ee501 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2004 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/* (C) 1998-2008 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -94,6 +94,7 @@ static const struct Keyword {
     { "__attribute__",         TOK_ATTRIBUTE,  TT_C89 | TT_C99 | TT_CC65  },
     { "__far__",               TOK_FAR,        TT_C89 | TT_C99 | TT_CC65  },
     { "__fastcall__",          TOK_FASTCALL,   TT_C89 | TT_C99 | TT_CC65  },
+    { "__inline__",     TOK_INLINE,            TT_C89 | TT_C99 | TT_CC65  },
     { "__near__",              TOK_NEAR,       TT_C89 | TT_C99 | TT_CC65  },
     { "asm",                   TOK_ASM,                          TT_CC65  },
     { "auto",                  TOK_AUTO,       TT_C89 | TT_C99 | TT_CC65  },
@@ -114,6 +115,7 @@ static const struct Keyword {
     { "for",                   TOK_FOR,        TT_C89 | TT_C99 | TT_CC65  },
     { "goto",                  TOK_GOTO,       TT_C89 | TT_C99 | TT_CC65  },
     { "if",                    TOK_IF,         TT_C89 | TT_C99 | TT_CC65  },
+    { "inline",         TOK_INLINE,              TT_C99 | TT_CC65  },
     { "int",                   TOK_INT,        TT_C89 | TT_C99 | TT_CC65  },
     { "long",                  TOK_LONG,       TT_C89 | TT_C99 | TT_CC65  },
     { "near",                  TOK_NEAR,                         TT_CC65  },
@@ -181,7 +183,7 @@ static int SkipWhite (void)
  */
 {
     while (1) {
-               while (CurC == 0) {
+               while (CurC == '\0') {
            if (NextLine () == 0) {
                return 0;
            }
@@ -197,27 +199,39 @@ static int SkipWhite (void)
 
 
 
-void SymName (char* s)
-/* Get symbol from input stream */
+int TokIsFuncSpec (const Token* T)
+/* Return true if the token is a function specifier */
 {
-    unsigned k = 0;
+    return (T->Tok == TOK_INLINE) || (T->Tok == TOK_FASTCALL) ||
+           (T->Tok == TOK_NEAR)   || (T->Tok == TOK_FAR);
+}
+
+
+
+void SymName (char* S)
+/* Read a symbol from the input stream. The first character must have been
+ * checked before calling this function. The buffer is expected to be at
+ * least of size MAX_IDENTLEN+1.
+ */
+{
+    unsigned Len = 0;
     do {
-               if (k != MAX_IDENTLEN) {
-                   ++k;
-                   *s++ = CurC;
-       }
+               if (Len < MAX_IDENTLEN) {
+                   ++Len;
+                   *S++ = CurC;
+       }
                NextChar ();
     } while (IsIdent (CurC) || IsDigit (CurC));
-    *s = '\0';
+    *S = '\0';
 }
 
 
 
-int IsSym (char *s)
-/* Get symbol from input stream or return 0 if not a symbol. */
+int IsSym (char* S)
+/* If a symbol follows, read it and return 1, otherwise return 0 */
 {
     if (IsIdent (CurC)) {
-       SymName (s);
+       SymName (S);
        return 1;
     } else {
        return 0;
@@ -245,11 +259,10 @@ static void SetTok (int tok)
 
 
 static int ParseChar (void)
-/* Parse a character. Converts \n into EOL, etc. */
+/* Parse a character. Converts escape chars into character codes. */
 {
-    int I;
-    unsigned Val;
     int C;
+    int HadError;
 
     /* Check for escape chars */
     if (CurC == '\\') {
@@ -291,10 +304,24 @@ static int ParseChar (void)
            case 'x':
            case 'X':
                /* Hex character constant */
-               NextChar ();
-               Val = HexVal (CurC) << 4;
-               NextChar ();
-                       C = Val | HexVal (CurC);        /* Do not translate */
+                if (!IsXDigit (NextC)) {
+                    Error ("\\x used with no following hex digits");
+                    C = ' ';
+                } else {
+                    HadError = 0;
+                    C = 0;
+                    while (IsXDigit (NextC)) {
+                        if ((C << 4) >= 256) {
+                            if (!HadError) {
+                                Error ("Hex character constant out of range");
+                                HadError = 1;
+                            }
+                        } else {
+                            C = (C << 4) | HexVal (NextC);
+                        }
+                        NextChar ();
+                    }
+                }
                break;
            case '0':
            case '1':
@@ -304,22 +331,24 @@ static int ParseChar (void)
            case '5':
            case '6':
            case '7':
-               /* Octal constant */
-               I = 0;
-                       Val = CurC - '0';
-                       while (NextC >= '0' && NextC <= '7' && ++I <= 3) {
-                   NextChar ();
-                   Val = (Val << 3) | (CurC - '0');
-               }
-                C = (int) Val;
-                if (Val >= 256) {
-                    Error ("Character constant out of range");
-                    C = ' ';
-                }
-               break;
+               /* Octal constant */
+                HadError = 0;
+                       C = HexVal (CurC);
+                       while (IsODigit (NextC)) {
+                    if ((C << 3) >= 256) {
+                        if (!HadError) {
+                            Error ("Octal character constant out of range");
+                            HadError = 1;
+                        }
+                    } else {
+                        C = (C << 3) | HexVal (NextC);
+                    }
+                   NextChar ();
+               }
+               break;
            default:
                Error ("Illegal character constant");
-               C = ' ';
+               C = ' ';
                 /* Try to do error recovery, otherwise the compiler will spit
                  * out thousands of errors in this place and abort.
                  */
@@ -413,7 +442,7 @@ static void NumericConst (void)
 {
     unsigned Base;              /* Temporary number base */
     unsigned Prefix;            /* Base according to prefix */
-    StrBuf   S;
+    StrBuf   S = STATIC_STRBUF_INITIALIZER;
     int      IsFloat;
     char     C;
     unsigned DigitVal;
@@ -441,7 +470,6 @@ static void NumericConst (void)
      * before converting it, so we can determine if it's a float or an
      * integer.
      */
-    InitStrBuf (&S);
     while (IsXDigit (CurC) && HexVal (CurC) < Base) {
         SB_AppendChar (&S, CurC);
         NextChar ();
@@ -477,7 +505,7 @@ static void NumericConst (void)
     }
 
     /* We don't need the string buffer any longer */
-    DoneStrBuf (&S);
+    SB_Done (&S);
 
     /* Distinguish between integer and floating point constants */
     if (!IsFloat) {
@@ -606,6 +634,8 @@ static void NumericConst (void)
             if (CurC == '-') {
                 Sign = -1;
                 NextChar ();
+            } else if (CurC == '+') {
+                NextChar ();
             }
 
             /* Read exponent digits. Since we support only 32 bit floats