X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fscanner.c;h=360305852c1be7b13e7ad2ee583ae765c6d15b45;hb=35e1184901ca38bdb2e56d154ed3b71f6096eacc;hp=b0bb8a9bc2f6bd264c177045244f579110547d0f;hpb=0e0183020dc232306b126176c9b36d049fe37cb0;p=cc65 diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index b0bb8a9bc..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,13 +93,16 @@ 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 }, { "__near__", TOK_NEAR, TT_C89 | TT_C99 | TT_CC65 }, { "asm", TOK_ASM, TT_CC65 }, { "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 }, @@ -114,6 +118,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 }, @@ -197,6 +202,16 @@ 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_CDECL) || + (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 @@ -395,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 */ @@ -421,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); } @@ -431,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; @@ -459,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 (); @@ -495,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) { @@ -573,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 */ @@ -624,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 @@ -652,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))); } } @@ -716,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 */ @@ -727,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) { @@ -738,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; } @@ -1013,7 +1049,7 @@ int Consume (token_t Token, const char* ErrorMsg) NextToken (); return 1; } else { - Error (ErrorMsg); + Error ("%s", ErrorMsg); return 0; } }