X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fscanner.c;h=360305852c1be7b13e7ad2ee583ae765c6d15b45;hb=35e1184901ca38bdb2e56d154ed3b71f6096eacc;hp=e8e13ee6a20e6e55d738779d68a4e58867b28d1c;hpb=f196e7c5c93c3f29f1bb672d70be20e120d68729;p=cc65 diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index e8e13ee6a..360305852 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2010, 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 */ @@ -92,6 +93,7 @@ static const struct Keyword { { "__Y__", TOK_Y, TT_C89 | TT_C99 | TT_CC65 }, { "__asm__", TOK_ASM, TT_C89 | TT_C99 | TT_CC65 }, { "__attribute__", TOK_ATTRIBUTE, TT_C89 | TT_C99 | TT_CC65 }, + { "__cdecl__", TOK_CDECL, 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 }, @@ -100,6 +102,7 @@ static const struct Keyword { { "auto", TOK_AUTO, TT_C89 | TT_C99 | TT_CC65 }, { "break", TOK_BREAK, TT_C89 | TT_C99 | TT_CC65 }, { "case", TOK_CASE, TT_C89 | TT_C99 | TT_CC65 }, + { "cdecl", TOK_CDECL, TT_CC65 }, { "char", TOK_CHAR, TT_C89 | TT_C99 | TT_CC65 }, { "const", TOK_CONST, TT_C89 | TT_C99 | TT_CC65 }, { "continue", TOK_CONTINUE, TT_C89 | TT_C99 | TT_CC65 }, @@ -202,8 +205,9 @@ static int SkipWhite (void) int TokIsFuncSpec (const Token* T) /* Return true if the token is a function specifier */ { - return (T->Tok == TOK_INLINE) || (T->Tok == TOK_FASTCALL) || - (T->Tok == TOK_NEAR) || (T->Tok == TOK_FAR); + return (T->Tok == TOK_INLINE) || + (T->Tok == TOK_FASTCALL) || (T->Tok == TOK_CDECL) || + (T->Tok == TOK_NEAR) || (T->Tok == TOK_FAR); } @@ -406,24 +410,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 +454,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); } @@ -442,7 +470,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; @@ -470,7 +498,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 (); @@ -506,7 +533,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) { @@ -584,39 +611,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 */ @@ -635,6 +651,8 @@ static void NumericConst (void) if (CurC == '-') { Sign = -1; NextChar (); + } else if (CurC == '+') { + NextChar (); } /* Read exponent digits. Since we support only 32 bit floats @@ -663,7 +681,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))); } } @@ -727,6 +745,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 */ @@ -738,7 +763,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) { @@ -749,7 +774,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; } @@ -1024,7 +1049,7 @@ int Consume (token_t Token, const char* ErrorMsg) NextToken (); return 1; } else { - Error (ErrorMsg); + Error ("%s", ErrorMsg); return 0; } }