]> git.sur5r.net Git - cc65/commitdiff
Added zilog/intel style hex numbers
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 11 Oct 2004 19:01:51 +0000 (19:01 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 11 Oct 2004 19:01:51 +0000 (19:01 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@3242 b7a2c559-68d2-44c3-8de9-860c34a00d81

doc/ca65.sgml
src/ca65/scanner.c

index 04e14fd04b574bada834ae700a618bc59df3a864..444f9e34189b3efe2c7df66f717871ada2b55d4e 100644 (file)
@@ -402,10 +402,10 @@ name="http://www.6502.org/source/interpreters/sweet16.htm">.
 
 <sect1>Number format<p>
 
-For literal values, the assembler accepts the widely used number formats:
-A preceeding '&dollar;' denotes a hex value, a preceeding '%' denotes a
-binary value, and a bare number is interpeted as a decimal. There are
-currently no octal values and no floats.
+For literal values, the assembler accepts the widely used number formats: A
+preceeding '&dollar;' or a trailing 'h' denotes a hex value, a preceeding '%'
+denotes a binary value, and a bare number is interpeted as a decimal. There
+are currently no octal values and no floats.
 
 
 <sect1>Conditional assembly<p>
index 91c091212d8f3e214c84eafe300eabeb2fb293f2..30b0828a6e395429884bb4739210f8cddde47dc1 100644 (file)
 enum Token Tok = TOK_NONE;             /* Current token */
 int WS;                                        /* Flag: Whitespace before token */
 long IVal;                             /* Integer token attribute */
-char SVal [MAX_STR_LEN+1];             /* String token attribute */
+char SVal[MAX_STR_LEN+1];               /* String token attribute */
 
 FilePos        CurPos = { 0, 0, 0 };           /* Name and position in current file */
 
 
 
-/* Struct to handle include files. Note: The length of the input line may
- * not exceed 255+1, since the column is stored in the file position struct
- * as a character. Increasing this value means changing the FilePos struct,
- * and the read and write routines in the assembler and linker.
- */
-typedef struct InputFile_ InputFile;
-struct InputFile_ {
+/* Struct to handle include files. */
+typedef struct InputFile InputFile;
+struct InputFile {
     FILE*                  F;                  /* Input file descriptor */
     FilePos        Pos;                /* Position in file */
     enum Token     Tok;                /* Last token */
@@ -94,8 +90,8 @@ struct InputFile_ {
 };
 
 /* Struct to handle textual input data */
-typedef struct InputData_ InputData;
-struct InputData_ {
+typedef struct InputData InputData;
+struct InputData {
     char*          Data;               /* Pointer to the data */
     const char*     Pos;               /* Pointer to current position */
     int                    Malloced;           /* Memory was malloced */
@@ -111,7 +107,7 @@ static unsigned       ICount        = 0;    /* Count of input files */
 static int       C             = 0;    /* Current input character */
 
 /* Force end of assembly */
-int              ForcedEnd = 0;
+int              ForcedEnd     = 0;
 
 /* List of dot keywords with the corresponding tokens */
 struct DotKeyword {
@@ -752,19 +748,62 @@ Again:
        return;
     }
 
-    /* Decimal number? */
+    /* Number? */
     if (IsDigit (C)) {
 
-       /* Read the number */
+        char Buf[16];
+        unsigned Digits;
+        unsigned Base;
+        unsigned I;
+        long     Max;
+        unsigned DVal;
+
+        /* Ignore leading zeros */
+        while (C == '0') {
+            NextChar ();
+        }
+
+        /* Read the number into Buf counting the digits */
+        Digits = 0;
+        while (IsXDigit (C)) {
+
+            /* Buf is big enough to allow any decimal and hex number to
+             * overflow, so ignore excess digits here, they will be detected
+             * when we convert the value.
+             */
+            if (Digits < sizeof (Buf)) {
+                Buf[Digits++] = C;
+            }
+
+            NextChar ();
+        }
+
+        /* Allow zilog/intel style hex numbers with a 'h' suffix */
+        if (C == 'h' || C == 'H') {
+            NextChar ();
+            Base = 16;
+            Max  = 0xFFFFFFFFUL / 16;
+        } else {
+            Base = 10;
+            Max  = 0xFFFFFFFFUL / 10;
+        }
+
+        /* Convert the number using the given base */
        IVal = 0;
-       while (IsDigit (C)) {
-                   if (IVal > (long) (0xFFFFFFFFUL / 10)) {
-                       Error ("Overflow in decimal number");
-               IVal = 0;
+        for (I = 0; I < Digits; ++I) {
+                   if (IVal > Max) {
+                       Error ("Number out of range");
+               IVal = 0;
+                break;
            }
-           IVal = (IVal * 10) + DigitVal (C);
-           NextChar ();
-       }
+            DVal = DigitVal (Buf[I]);
+            if (DVal > Base) {
+                Error ("Invalid digits in number");
+                IVal = 0;
+                break;
+            }
+           IVal = (IVal * Base) + DVal;
+        }
 
        /* This is an integer constant */
                Tok = TOK_INTCON;