/* */
/* */
/* */
-/* (C) 1998-2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
unsigned char Type; /* Token type */
} Keywords [] = {
{ "_Pragma", TOK_PRAGMA, TT_C },
+ { "__AX__", TOK_AX, TT_C },
{ "__A__", TOK_A, TT_C },
- { "__AX__", TOK_AX, TT_C },
- { "__EAX__", TOK_EAX, TT_C },
- { "__X__", TOK_X, TT_C },
- { "__Y__", TOK_Y, TT_C },
- { "__asm__", TOK_ASM, TT_C },
- { "__attribute__", TOK_ATTRIBUTE, TT_C },
- { "__far__", TOK_FAR, TT_C },
- { "__fastcall__", TOK_FASTCALL, TT_C },
+ { "__EAX__", TOK_EAX, TT_C },
+ { "__X__", TOK_X, TT_C },
+ { "__Y__", TOK_Y, TT_C },
+ { "__asm__", TOK_ASM, TT_C },
+ { "__attribute__", TOK_ATTRIBUTE, TT_C },
+ { "__far__", TOK_FAR, TT_C },
+ { "__fastcall__", TOK_FASTCALL, TT_C },
+ { "__near__", TOK_NEAR, TT_C },
{ "asm", TOK_ASM, TT_EXT },
{ "auto", TOK_AUTO, TT_C },
{ "break", TOK_BREAK, TT_C },
{ "if", TOK_IF, TT_C },
{ "int", TOK_INT, TT_C },
{ "long", TOK_LONG, TT_C },
+ { "near", TOK_NEAR, TT_EXT },
{ "register", TOK_REGISTER, TT_C },
+ { "restrict", TOK_RESTRICT, TT_C },
{ "return", TOK_RETURN, TT_C },
{ "short", TOK_SHORT, TT_C },
{ "signed", TOK_SIGNED, TT_C },
-static int SignExtendChar (int C)
-/* Do correct sign extension of a character */
-{
- if (SignedChars && (C & 0x80) != 0) {
- return C | ~0xFF;
- } else {
- return C & 0xFF;
- }
-}
-
-
-
static int ParseChar (void)
/* Parse a character. Converts \n into EOL, etc. */
{
- int i;
- unsigned val;
+ int I;
+ unsigned Val;
int C;
/* Check for escape chars */
switch (CurC) {
case 'b':
C = '\b';
- break;
+ break;
case 'f':
- C = '\f';
- break;
+ C = '\f';
+ break;
case 'r':
- C = '\r';
- break;
+ C = '\r';
+ break;
case 'n':
- C = '\n';
- break;
+ C = '\n';
+ break;
case 't':
- C = '\t';
- break;
+ C = '\t';
+ break;
+ case 'v':
+ C = '\v';
+ break;
case '\"':
- C = '\"';
- break;
+ C = '\"';
+ break;
case '\'':
- C = '\'';
- break;
+ C = '\'';
+ break;
case '\\':
- C = '\\';
- break;
+ C = '\\';
+ break;
case 'x':
case 'X':
- /* Hex character constant */
- NextChar ();
- val = HexVal (CurC) << 4;
- NextChar ();
- C = val | HexVal (CurC); /* Do not translate */
- break;
+ /* Hex character constant */
+ NextChar ();
+ Val = HexVal (CurC) << 4;
+ NextChar ();
+ C = Val | HexVal (CurC); /* Do not translate */
+ break;
case '0':
case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
/* Octal constant */
- i = 0;
- C = CurC - '0';
- while (NextC >= '0' && NextC <= '7' && i++ < 4) {
+ I = 0;
+ Val = CurC - '0';
+ while (NextC >= '0' && NextC <= '7' && ++I <= 3) {
NextChar ();
- C = (C << 3) | (CurC - '0');
+ Val = (Val << 3) | (CurC - '0');
}
+ C = (int) Val;
+ if (Val >= 256) {
+ Error ("Character constant out of range");
+ C = ' ';
+ }
break;
default:
Error ("Illegal character constant");
C = ' ';
+ /* Try to do error recovery, otherwise the compiler will spit
+ * out thousands of errors in this place and abort.
+ */
+ if (CurC != '\'' && CurC != '\0') {
+ while (NextC != '\'' && NextC != '\"' && NextC != '\0') {
+ NextChar ();
+ }
+ }
break;
}
} else {
}
CurTok = NextTok;
+ /* When reading the first time from the file, the line info in NextTok,
+ * which was copied to CurTok is invalid. Since the information from
+ * the token is used for error messages, we must make it valid.
+ */
+ if (CurTok.LI == 0) {
+ CurTok.LI = UseLineInfo (GetCurLineInfo ());
+ }
+
/* Remember the starting position of the next token */
NextTok.LI = UseLineInfo (GetCurLineInfo ());
/* A number */
int HaveSuffix; /* True if we have a type suffix */
unsigned types; /* Possible types */
- unsigned base;
- unsigned long k; /* Value */
+ unsigned Base;
+ unsigned DigitVal;
+ unsigned long k; /* Value */
k = 0;
- base = 10;
+ Base = 10;
types = IT_INT | IT_LONG | IT_ULONG;
if (CurC == '0') {
/* gobble 0 and examin next char */
NextChar ();
if (toupper (CurC) == 'X') {
- base = 16;
- NextTok.Type = type_uint;
+ Base = 16;
+ NextTok.Type = type_uint;
NextChar (); /* gobble "x" */
} else {
- base = 8;
- }
- }
- while (1) {
- if (IsDigit (CurC)) {
- k = k * base + (CurC - '0');
- } else if (base == 16 && IsXDigit (CurC)) {
- k = (k << 4) + HexVal (CurC);
- } else {
- break; /* not digit */
+ Base = 8;
}
- NextChar (); /* gobble char */
}
+ while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) {
+ k = k * Base + DigitVal;
+ NextChar ();
+ }
+ /* Check for errorneous digits */
+ if (Base == 8 && IsDigit (CurC)) {
+ Error ("Numeric constant contains digits beyond the radix");
+ /* Do error recovery */
+ do {
+ NextChar ();
+ } while (IsDigit (CurC));
+ } else if (Base != 16 && IsXDigit (CurC)) {
+ Error ("Nondigits in number and not hexadecimal");
+ do {
+ NextChar ();
+ } while (IsXDigit (CurC));
+ }
/* Check for a suffix */
HaveSuffix = 1;