/* */
/* */
/* */
-/* (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 */
/* common */
#include "chartype.h"
+#include "fp.h"
#include "tgttrans.h"
/* cc65 */
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 */
}
/* 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);
}
} 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 */
/* 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)));
}
}
return;
}
+ /* Check for wide character literals */
+ if (CurC == 'L' && NextC == '\"') {
+ StringConst ();
+ return;
+ }
+
+ /* Check for keywords and identifiers */
if (IsSym (token)) {
/* Check for a keyword */
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) {
} 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;
}
NextToken ();
return 1;
} else {
- Error (ErrorMsg);
+ Error ("%s", ErrorMsg);
return 0;
}
}