/* */
/* */
/* */
-/* (C) 1998-2000 Ullrich von Bassewitz */
+/* (C) 1998-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
+int SignExtendChar (int C)
+/* Do correct sign extension of a character */
+{
+ if (SignedChars && (C & 0x80) != 0) {
+ return C | ~0xFF;
+ } else {
+ return C & 0xFF;
+ }
+}
+
+
+
type GetDefaultChar (void)
/* Return the default char type (signed/unsigned) depending on the settings */
{
/* */
/* */
/* */
-/* (C) 1998 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2002 Ullrich von Bassewitz */
+/* Wacholderweg 14 */
+/* D-70597 Stuttgart */
+/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
void TypeFree (type* Type);
/* Free a type string */
+int SignExtendChar (int C);
+/* Do correct sign extension of a character */
+
type GetDefaultChar (void);
/* Return the default char type (signed/unsigned) depending on the settings */
} else {
Error ("String literal expected");
- }
+ }
/* Call the string buf destructor */
DoneStrBuf (&S);
static void CharMapPragma (StrBuf* B)
/* Change the character map */
{
- unsigned Index, C;
-
- ExprDesc Val;
+ long Index, C;
/* Read the character index */
- ConstIntExpr (&Val);
- if (Val.ConstVal < 1 || Val.ConstVal > 255) {
- Error ("Character index out of range");
- Index = 'A';
- } else {
- Index = Val.ConstVal;
+ if (!SB_GetNumber (B, &Index)) {
+ return;
+ }
+ if (Index < 1 || Index > 255) {
+ Error ("Character index out of range");
+ return;
}
/* Comma follows */
- ConsumeComma ();
+ SB_SkipWhite (B);
+ if (SB_Get (B) != ',') {
+ Error ("Comma expected");
+ return;
+ }
+ SB_SkipWhite (B);
/* Read the character code */
- ConstIntExpr (&Val);
- if (Val.ConstVal < 1 || Val.ConstVal > 255) {
+ if (!SB_GetNumber (B, &C)) {
+ return;
+ }
+ if (C < 1 || C > 255) {
Error ("Character code out of range");
- C = 'A';
- } else {
- C = Val.ConstVal;
+ return;
}
/* Remap the character */
- TgtTranslateSet (Index, C);
+ printf ("Translating %04lX to %04lX\n", Index, C);
+ TgtTranslateSet ((unsigned) Index, (unsigned char) C);
}
Error ("')' expected");
return;
}
+ SB_SkipWhite (&B);
+
+ /* Allow an optional semicolon to be compatible with the old syntax */
+ if (SB_Peek (&B) == ';') {
+ SB_Skip (&B);
+ SB_SkipWhite (&B);
+ }
/* Make sure nothing follows */
- SB_SkipWhite (&B);
if (SB_Peek (&B) != '\0') {
Error ("Unexpected input following pragma directive");
}
-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. */
{
void NextToken (void)
/* Get next token from input stream */
-{
+{
ident token;
/* We have to skip white space here before shifting tokens, since the
/* 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;
/* common */
#include "chartype.h"
+#include "tgttrans.h"
/* cc65 */
+#include "datatype.h"
#include "error.h"
#include "hexval.h"
#include "ident.h"
+int SB_GetNumber (StrBuf* B, long* Val)
+/* Get a number from the string buffer. Accepted formats are decimal, octal,
+ * hex and character constants. Numeric constants may be preceeded by a
+ * minus or plus sign. The function returns 1 if a number was found and
+ * zero otherwise.
+ */
+{
+ int Sign;
+ char C;
+ unsigned Base;
+ unsigned DigitVal;
+
+ /* Initialize Val */
+ *Val = 0;
+
+ /* Check for a sign */
+ Sign = 1;
+ switch (SB_Peek (B)) {
+ case '-':
+ Sign = -1;
+ /* FALLTHROUGH */
+ case '+':
+ SB_Skip (B);
+ SB_SkipWhite (B);
+ break;
+ }
+
+ /* Check for the different formats */
+ C = SB_Peek (B);
+ if (IsDigit (C)) {
+
+ if (C == '0') {
+ /* Hex or octal */
+ SB_Skip (B);
+ if (tolower (SB_Peek (B)) == 'x') {
+ SB_Skip (B);
+ Base = 16;
+ if (!IsXDigit (SB_Peek (B))) {
+ Error ("Invalid hexadecimal number");
+ return 0;
+ }
+ } else {
+ Base = 8;
+ }
+ } else {
+ Base = 10;
+ }
+
+ /* Read the number */
+ while (IsXDigit (C = SB_Peek (B)) && (DigitVal = HexVal (C)) < Base) {
+ *Val = (*Val * Base) + DigitVal;
+ SB_Skip (B);
+ }
+
+ /* Allow optional 'U' and 'L' modifiers */
+ C = SB_Peek (B);
+ if (C == 'u' || C == 'U') {
+ SB_Skip (B);
+ C = SB_Peek (B);
+ if (C == 'l' || C == 'L') {
+ SB_Skip (B);
+ }
+ } else if (C == 'l' || C == 'L') {
+ SB_Skip (B);
+ C = SB_Peek (B);
+ if (C == 'u' || C == 'U') {
+ SB_Skip (B);
+ }
+ }
+
+ } else if (C == '\'') {
+
+ /* Character constant */
+ SB_Skip (B);
+ *Val = SignExtendChar (TgtTranslateChar (ParseChar (B)));
+ if (SB_Peek (B) != '\'') {
+ Error ("`\'' expected");
+ return 0;
+ } else {
+ /* Skip the quote */
+ SB_Skip (B);
+ }
+
+ } else {
+
+ /* Invalid number */
+ Error ("Numeric constant expected");
+ return 0;
+
+ }
+
+ /* Success, value read is in Val */
+ return 1;
+}
+
+
+
* returns 1 if a string was found and 0 otherwise.
*/
+int SB_GetNumber (StrBuf* B, long* Val);
+/* Get a number from the string buffer. Accepted formats are decimal, octal,
+ * hex and character constants. Numeric constants may be preceeded by a
+ * minus or plus sign. The function returns 1 if a number was found and
+ * zero otherwise.
+ */