]> git.sur5r.net Git - cc65/blobdiff - src/cc65/scanner.c
Rewrote literal handling. Literals are now saved together with other function
[cc65] / src / cc65 / scanner.c
index cc073e37313157786eea0c0e761245ce868ee501..3dee4239f0acd3807fd95e0cd54bf9fce8c7c95f 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2008 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -42,6 +42,7 @@
 
 /* common */
 #include "chartype.h"
+#include "fp.h"
 #include "tgttrans.h"
 
 /* cc65 */
@@ -406,24 +407,42 @@ static void CharConst (void)
 static void StringConst (void)
 /* Parse a quoted string */
 {
-    NextTok.IVal = GetLiteralPoolOffs ();
+    /* String buffer */
+    StrBuf S = AUTO_STRBUF_INITIALIZER;
+
+    /* Assume next token is a string constant */
     NextTok.Tok  = TOK_SCONST;
 
-    /* Be sure to concatenate strings */
-    while (CurC == '\"') {
+    /* Concatenate strings. If at least one of the concenated strings is a wide
+     * character literal, the whole string is a wide char literal, otherwise
+     * it's a normal string literal.
+     */
+    while (1) {
 
-       /* Skip the quote char */
-       NextChar ();
+        /* Check if this is a normal or a wide char string */
+        if (CurC == 'L' && NextC == '\"') {
+            /* Wide character literal */
+            NextTok.Tok = TOK_WCSCONST;
+            NextChar ();
+            NextChar ();
+        } else if (CurC == '\"') {
+            /* Skip the quote char */
+           NextChar ();
+        } else {
+            /* No string */
+            break;
+        }
 
-       while (CurC != '\"') {
-           if (CurC == '\0') {
-               Error ("Unexpected newline");
-               break;
-           }
-           AddLiteralChar (ParseChar ());
-       }
+        /* Read until end of string */
+       while (CurC != '\"') {
+           if (CurC == '\0') {
+               Error ("Unexpected newline");
+               break;
+           }
+                   SB_AppendChar (&S, ParseChar ());
+       }
 
-       /* Skip closing quote char if there was one */
+       /* Skip closing quote char if there was one */
        NextChar ();
 
        /* Skip white space, read new input */
@@ -432,7 +451,13 @@ static void StringConst (void)
     }
 
     /* Terminate the string */
-    AddLiteralChar ('\0');
+    SB_AppendChar (&S, '\0');
+
+    /* Add the whole string to the literal pool */
+    NextTok.SVal = AddLiteralStr (&S);
+
+    /* Free the buffer */
+    SB_Done (&S);
 }
 
 
@@ -583,39 +608,28 @@ static void NumericConst (void)
     } else {
 
         /* Float constant */
-        double FVal = IVal;             /* Convert to float */
+        Double FVal = FP_D_FromInt (IVal);      /* Convert to double */
 
         /* Check for a fractional part and read it */
         if (CurC == '.') {
 
-            unsigned Digits;
-            unsigned long Frac;
-            unsigned long Scale;
+            Double Scale;
 
             /* Skip the dot */
             NextChar ();
 
-            /* Read fractional digits. Since we support only 32 bit floats
-             * with a maximum of 7 fractional digits, we read the fractional
-             * part as integer with up to 8 digits and drop the remainder.
-             * This avoids an overflow of Frac and Scale.
-             */
-            Digits = 0;
-            Frac   = 0;
-            Scale  = 1;
+            /* Read fractional digits */
+            Scale  = FP_D_Make (1.0);
             while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) {
-                if (Digits < 8) {
-                    Frac = Frac * Base + DigitVal;
-                    ++Digits;
-                    Scale *= Base;
-                }
+                /* Get the value of this digit */
+                Double FracVal = FP_D_Div (FP_D_FromInt (DigitVal * Base), Scale);
+                /* Add it to the float value */
+                FVal = FP_D_Add (FVal, FracVal);
+                /* Scale base */
+                Scale = FP_D_Mul (Scale, FP_D_FromInt (DigitVal));
+                /* Skip the digit */
                 NextChar ();
             }
-
-            /* Scale the fractional part and add it */
-            if (Frac) {
-                FVal += ((double) Frac) / ((double) Scale);
-            }
         }
 
         /* Check for an exponent and read it */
@@ -664,7 +678,7 @@ static void NumericConst (void)
 
             /* Scale the exponent and adjust the value accordingly */
             if (Exp) {
-                FVal *= pow (10, Exp);
+                FVal = FP_D_Mul (FVal, FP_D_Make (pow (10, Exp)));
             }
         }
 
@@ -728,6 +742,13 @@ void NextToken (void)
        return;
     }
 
+    /* Check for wide character literals */
+    if (CurC == 'L' && NextC == '\"') {
+        StringConst ();
+        return;
+    }
+
+    /* Check for keywords and identifiers */
     if (IsSym (token)) {
 
        /* Check for a keyword */
@@ -739,7 +760,7 @@ void NextToken (void)
        if (token[0] == '_' && token[1] == '_') {
            /* Special symbols */
             if (strcmp (token+2, "FILE__") == 0) {
-               NextTok.IVal = AddLiteral (GetCurrentFile());
+               NextTok.SVal = AddLiteral (GetCurrentFile());
                NextTok.Tok  = TOK_SCONST;
                return;
            } else if (strcmp (token+2, "LINE__") == 0) {
@@ -750,7 +771,7 @@ void NextToken (void)
                    } else if (strcmp (token+2, "func__") == 0) {
                /* __func__ is only defined in functions */
                if (CurrentFunc) {
-                   NextTok.IVal = AddLiteral (F_GetFuncName (CurrentFunc));
+                   NextTok.SVal = AddLiteral (F_GetFuncName (CurrentFunc));
                    NextTok.Tok  = TOK_SCONST;
                    return;
                }
@@ -1025,7 +1046,7 @@ int Consume (token_t Token, const char* ErrorMsg)
        NextToken ();
         return 1;
     } else {
-               Error (ErrorMsg);
+               Error ("%s", ErrorMsg);
         return 0;
     }
 }