]> git.sur5r.net Git - cc65/blobdiff - src/ca65/scanner.c
Allow conditional directives within .STRUCT7:UNION and .ENUM
[cc65] / src / ca65 / scanner.c
index 8bad4f6c2b40db21709b5f4a5956d74bc03d651e..cb4712a65b81fbacf5da17f3e2b3c3b0bc57767a 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -122,7 +122,7 @@ struct DotKeyword {
     { ".A8",                   TOK_A8          },
     { ".ADDR",                 TOK_ADDR        },
     { ".ALIGN",                TOK_ALIGN       },
-    { ".AND",          TOK_BAND        },
+    { ".AND",          TOK_BOOLAND     },
     { ".ASCIIZ",               TOK_ASCIIZ      },
     { ".ASSERT",        TOK_ASSERT      },
     { ".AUTOIMPORT",   TOK_AUTOIMPORT  },
@@ -154,13 +154,17 @@ struct DotKeyword {
     { ".ELSE",         TOK_ELSE        },
     { ".ELSEIF",       TOK_ELSEIF      },
     { ".END",          TOK_END         },
+    { ".ENDENUM",       TOK_ENDENUM     },
     { ".ENDIF",        TOK_ENDIF       },
     { ".ENDMAC",       TOK_ENDMACRO    },
     { ".ENDMACRO",     TOK_ENDMACRO    },
     { ".ENDPROC",      TOK_ENDPROC     },
     { ".ENDREP",       TOK_ENDREP      },
     { ".ENDREPEAT",    TOK_ENDREP      },
+    { ".ENDSCOPE",      TOK_ENDSCOPE    },
     { ".ENDSTRUCT",    TOK_ENDSTRUCT   },
+    { ".ENDUNION",             TOK_ENDUNION    },
+    { ".ENUM",          TOK_ENUM        },
     { ".ERROR",        TOK_ERROR       },
     { ".EXITMAC",      TOK_EXITMACRO   },
     { ".EXITMACRO",    TOK_EXITMACRO   },
@@ -205,9 +209,9 @@ struct DotKeyword {
     { ".MATCH",                TOK_MATCH       },
     { ".MID",          TOK_MID         },
     { ".MOD",          TOK_MOD         },
-    { ".NOT",          TOK_BNOT        },
+    { ".NOT",          TOK_BOOLNOT     },
     { ".NULL",         TOK_NULL        },
-    { ".OR",           TOK_BOR         },
+    { ".OR",           TOK_BOOLOR      },
     { ".ORG",                  TOK_ORG         },
     { ".OUT",                  TOK_OUT         },
     { ".P02",                  TOK_P02         },
@@ -227,10 +231,12 @@ struct DotKeyword {
     { ".RES",                  TOK_RES         },
     { ".RIGHT",                TOK_RIGHT       },
     { ".RODATA",       TOK_RODATA      },
+    { ".SCOPE",         TOK_SCOPE       },
     { ".SEGMENT",      TOK_SEGMENT     },
     { ".SETCPU",       TOK_SETCPU      },
     { ".SHL",          TOK_SHL         },
     { ".SHR",          TOK_SHR         },
+    { ".SIZEOF",        TOK_SIZEOF      },
     { ".SMART",                TOK_SMART       },
     { ".STRAT",                TOK_STRAT       },
     { ".STRING",       TOK_STRING      },
@@ -245,7 +251,7 @@ struct DotKeyword {
     { ".WARNING",      TOK_WARNING     },
     { ".WORD",                 TOK_WORD        },
     { ".XMATCH",       TOK_XMATCH      },
-    { ".XOR",                  TOK_BXOR        },
+    { ".XOR",                  TOK_BOOLXOR     },
     { ".ZEROPAGE",     TOK_ZEROPAGE    },
 };
 
@@ -307,7 +313,7 @@ void NewInputFile (const char* Name)
 
        /* Error (fatal error if this is the main file) */
        if (ICount == 0) {
-           Fatal (FAT_CANNOT_OPEN_INPUT, Name, strerror (errno));
+           Fatal ("Cannot open input file `%s': %s", Name, strerror (errno));
                }
 
                /* We are on include level. Search for the file in the include
@@ -316,7 +322,7 @@ void NewInputFile (const char* Name)
        PathName = FindInclude (Name);
                if (PathName == 0 || (F = fopen (PathName, "r")) == 0) {
            /* Not found or cannot open, print an error and bail out */
-           Error (ERR_CANNOT_OPEN_INCLUDE, Name, strerror (errno));
+           Error ("Cannot open include file `%s': %s", Name, strerror (errno));
        }
 
        /* Free the allocated memory */
@@ -332,7 +338,7 @@ void NewInputFile (const char* Name)
        /* Stat the file and remember the values */
        struct stat Buf;
        if (fstat (fileno (F), &Buf) != 0) {
-           Fatal (FAT_CANNOT_STAT_INPUT, Name, strerror (errno));
+           Fatal ("Cannot stat input file `%s': %s", Name, strerror (errno));
        }
 
        /* Add the file to the input file table and remember the index */
@@ -579,13 +585,13 @@ static unsigned ReadStringConst (int StringTerm)
            break;
        }
        if (C == '\n' || C == EOF) {
-           Error (ERR_NEWLINE_IN_STRING);
+           Error ("Newline in string constant");
            break;
        }
 
        /* Check for string length, print an error message once */
        if (I == MAX_STR_LEN) {
-           Error (ERR_STRING_TOO_LONG);
+           Error ("Maximum string size exceeded");
        } else if (I < MAX_STR_LEN) {
            SVal [I] = C;
        }
@@ -651,7 +657,7 @@ Again:
                Tok = TOK_PC;
                return;
            } else {
-               Error (ERR_HEX_DIGIT_EXPECTED);
+               Error ("Hexadecimal digit expected");
            }
        }
 
@@ -659,7 +665,7 @@ Again:
        IVal = 0;
        while (IsXDigit (C)) {
            if (IVal & 0xF0000000) {
-               Error (ERR_NUM_OVERFLOW);
+               Error ("Overflow in hexadecimal number");
                IVal = 0;
            }
            IVal = (IVal << 4) + DigitVal (C);
@@ -677,14 +683,14 @@ Again:
 
        /* 0 or 1 must follow */
        if (!IsBDigit (C)) {
-           Error (ERR_01_EXPECTED);
+           Error ("Binary digit expected");
        }
 
        /* Read the number */
        IVal = 0;
        while (IsBDigit (C)) {
            if (IVal & 0x80000000) {
-               Error (ERR_NUM_OVERFLOW);
+               Error ("Overflow in binary number");
                IVal = 0;
            }
            IVal = (IVal << 1) + DigitVal (C);
@@ -703,7 +709,7 @@ Again:
        IVal = 0;
        while (IsDigit (C)) {
                    if (IVal > (long) (0xFFFFFFFFUL / 10)) {
-                       Error (ERR_NUM_OVERFLOW);
+                       Error ("Overflow in decimal number");
                IVal = 0;
            }
            IVal = (IVal * 10) + DigitVal (C);
@@ -719,7 +725,6 @@ Again:
     if (C == '.') {
 
        /* Remember and skip the dot */
-       SVal[0] = C;
        NextChar ();
 
        /* Check if it's just a dot */
@@ -731,6 +736,7 @@ Again:
        } else {
 
            /* Read the remainder of the identifier */
+            SVal[0] = '.';
            ReadIdent (1);
 
            /* Dot keyword, search for it */
@@ -742,7 +748,7 @@ Again:
                    Tok = TOK_IDENT;
                } else {
                    /* Invalid pseudo instruction */
-                   Error (ERR_PSEUDO_EXPECTED);
+                   Error ("`%s' is not a recognized control command", SVal);
                    goto Again;
                }
            }
@@ -759,7 +765,7 @@ Again:
 
        /* Start character alone is not enough */
         if (SVal [1] == '\0') {
-           Error (ERR_IDENT_EXPECTED);
+           Error ("Invalid cheap local symbol");
                    goto Again;
        }
 
@@ -873,7 +879,7 @@ CharAgain:
            NextChar ();
            if (C == '&') {
                NextChar ();
-               Tok = TOK_BAND;
+               Tok = TOK_BOOLAND;
            } else {
                Tok = TOK_AND;
            }
@@ -883,7 +889,7 @@ CharAgain:
            NextChar ();
            if (C == '|') {
                NextChar ();
-               Tok = TOK_BOR;
+               Tok = TOK_BOOLOR;
            } else {
                Tok = TOK_OR;
            }
@@ -987,7 +993,7 @@ CharAgain:
 
        case '!':
            NextChar ();
-           Tok = TOK_BNOT;
+           Tok = TOK_BOOLNOT;
            return;
 
        case '>':
@@ -1024,14 +1030,14 @@ CharAgain:
                /* Always a character constant */
                NextChar ();
                if (C == '\n' || C == EOF) {
-                   Error (ERR_ILLEGAL_CHARCON);
+                   Error ("Illegal character constant");
                    goto CharAgain;
                }
                IVal = C;
                Tok = TOK_CHARCON;
                NextChar ();
                if (C != '\'') {
-                   Error (ERR_ILLEGAL_CHARCON);
+                   Error ("Illegal character constant");
                } else {
                    NextChar ();
                }
@@ -1082,7 +1088,7 @@ CharAgain:
     /* If we go here, we could not identify the current character. Skip it
      * and try again.
      */
-    Error (ERR_INVALID_CHAR, C & 0xFF);
+    Error ("Invalid input character: 0x%02X", C & 0xFF);
     NextChar ();
     goto Again;
 }
@@ -1136,7 +1142,7 @@ int GetSubKey (const char** Keys, unsigned Count)
 
 
 
-unsigned ParseAddrSize (void)
+unsigned char ParseAddrSize (void)
 /* Check if the next token is a keyword that denotes an address size specifier.
  * If so, return the corresponding address size constant, otherwise output an
  * error message and return ADDR_SIZE_DEFAULT.
@@ -1150,7 +1156,7 @@ unsigned ParseAddrSize (void)
 
     /* Check for an identifier */
     if (Tok != TOK_IDENT) {
-        Error (ERR_ADDR_SIZE_EXPECTED);
+        Error ("Address size specifier expected");
         return ADDR_SIZE_DEFAULT;
     }
 
@@ -1158,13 +1164,13 @@ unsigned ParseAddrSize (void)
     switch (GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]))) {
         case 0:
         case 1:
-        case 2: return ADDR_SIZE_FAR;
+        case 2: return ADDR_SIZE_ZP;
         case 3:
         case 4:
         case 5: return ADDR_SIZE_ABS;
         case 6: return ADDR_SIZE_FAR;
         default:
-            Error (ERR_ADDR_SIZE_EXPECTED);
+            Error ("Address size specifier expected");
             return ADDR_SIZE_DEFAULT;
     }
 }