]> Shamusworld >> Repos - rmac/blobdiff - token.c
Added floating point support to expression evaluator, introduced FLOAT token, fixup...
[rmac] / token.c
diff --git a/token.c b/token.c
index b53b7decbf552b3366ed81df86cc9e057baae13c..f719dc356791e84142046f6e6251afe62e2ad345 100644 (file)
--- a/token.c
+++ b/token.c
@@ -568,7 +568,8 @@ DEBUG { printf("ExM: SYMBOL=\"%s\"", d); }
 //         to choke on legitimate code... Need to investigate this further
 //         before changing anything else here!
                                                        case CONST:
-                                                               sprintf(numbuf, "$%lx", (long unsigned int)*tk++);
+                                                               sprintf(numbuf, "$%lx", (uint64_t)*tk++);
+                                                               tk++;
                                                                d = numbuf;
                                                                break;
                                                        case DEQUALS:
@@ -949,11 +950,14 @@ int TokenizeLine(void)
        int state = 0;                          // State for keyword detector
        int j = 0;                                      // Var for keyword detector
        uint8_t c;                                      // Random char
-       VALUE v;                                        // Random value
+       uint64_t v;                                     // Random value
+       uint32_t cursize = 0;           // Current line's size (.b, .w, .l, .s, .q, .d)
+       double f;                                       // Random float
        uint8_t * nullspot = NULL;      // Spot to clobber for SYMBOL termination
        int stuffnull;                          // 1:terminate SYMBOL '\0' at *nullspot
        uint8_t c1;
        int stringNum = 0;                      // Pointer to string locations in tokenized line
+       uint64_t * tk64;
 
 retry:
 
@@ -1133,7 +1137,8 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); }
                                if (((chrtab[*ln] & DOT) == 0) || (dotxtab[*ln] == 0))
                                        return error("[bwsl] must follow '.' in symbol");
 
-                               v = (VALUE)dotxtab[*ln++];
+                               v = (uint32_t)dotxtab[*ln++];
+                               cursize = (uint32_t)v;
 
                                if (chrtab[*ln] & CTSYM)
                                        return error("misuse of '.'; not allowed in symbols");
@@ -1292,11 +1297,11 @@ dostring:
                                                case '\\':
                                                        c = '\\';
                                                        break;
-                        case '!':
-                            // If we're evaluating a macro
-                            // this is valid and expands to
-                            // "dot-size"
-                            break;
+                                               case '!':
+                                                       // If we're evaluating a macro
+                                                       // this is valid and expands to
+                                                       // "dot-size"
+                                                       break;
                                                default:
                                                        warn("bad backslash code in string");
                                                        ln--;
@@ -1315,6 +1320,19 @@ dostring:
                        case '$':               // $, hex constant
                                if (chrtab[*ln] & HDIGIT)
                                {
+                                       if (cursize == 'q' || cursize == 'Q')
+                                       {
+                                               // Parse 64-bit integer
+                                               uint64_t v64 = 0;
+
+                                               while (hextab[*ln] >= 0)
+                                                       v64 = (v64 << 4) + (int)hextab[*ln++];
+
+                                               *(uint64_t *)tk = v64;
+                                               tk = tk + 2;
+
+                                               continue;
+                                       }
                                        v = 0;
 
                                        // Parse the hex value
@@ -1337,13 +1355,16 @@ dostring:
                                                        }
                                                        else if ((*(ln + 1) & 0xDF) == 'L')
                                                        {
+                                                               v &= 0xFFFFFFFF;
                                                                ln += 2;
                                                        }
                                                }
                                        }
 
                                        *tk++ = CONST;
-                                       *tk++ = v;
+                                       tk64 = (uint64_t *)tk;
+                                       *tk64++ = v;
+                                       tk = (TOKEN *)tk64;
 
                                        if (obj_format == ALCYON)
                                        {
@@ -1448,12 +1469,15 @@ dostring:
 
                                        if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
                                        {
+                                               v &= 0xFFFFFFFF;
                                                ln += 2;
                                        }
                                }
 
                                *tk++ = CONST;
-                               *tk++ = v;
+                               tk64 = (uint64_t *)tk;
+                               *tk64++ = v;
+                               tk = (TOKEN *)tk64;
                                continue;
                        case '@':               // @ or octal constant
                                if (*ln < '0' || *ln > '7')
@@ -1483,12 +1507,15 @@ dostring:
 
                                        if ((*(ln+1) == 'l') || (*(ln+1) == 'L'))
                                        {
+                                               v &= 0xFFFFFFFF;
                                                ln += 2;
                                        }
                                }
 
                                *tk++ = CONST;
-                               *tk++ = v;
+                               tk64 = (uint64_t *)tk;
+                               *tk64++ = v;
+                               tk = (TOKEN *)tk64;
                                continue;
                        case '^':               // ^ or ^^ <operator-name>
                                if (*ln != '^')
@@ -1562,31 +1589,61 @@ dostring:
                                {
                                        v &= 0x000000FF;
                                        ln += 2;
-                    *tk++ = CONST;
-                    *tk++ = v;
-                    *tk++ = DOTB;
+                                       *tk++ = CONST;
+                                       tk64 = (uint64_t *)tk;
+                                       *tk64++ = v;
+                                       tk = (uint32_t *)tk64;
+                                       *tk++ = DOTB;
                                }
                                else if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
                                {
                                        v &= 0x0000FFFF;
                                        ln += 2;
-                    *tk++ = CONST;
-                    *tk++ = v;
-                    *tk++ = DOTW;
+                                       *tk++ = CONST;
+                                       tk64 = (uint64_t *)tk;
+                                       *tk64++ = v;
+                                       tk = (uint32_t *)tk64;
+
+                                       *tk++ = DOTW;
                                }
                                else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
                                {
+                                       v &= 0xFFFFFFFF;
                                        ln += 2;
-                    *tk++ = CONST;
-                    *tk++ = v;
-                    *tk++ = DOTL;
-                }
-            }
-            else
-            {
-                *tk++ = CONST;
-                *tk++ = v;
-            }
+                                       *tk++ = CONST;
+                                       tk64 = (uint64_t *)tk;
+                                       *tk64++ = v;
+                                       tk = (uint32_t *)tk64;
+
+                                       *tk++ = DOTL;
+                               }
+                               else if ((int)chrtab[*(ln + 1)] & DIGIT)
+                               {
+                                       // Hey, more digits after the dot, so assume it's a
+                                       // fractional number
+                                       double fract = 10;
+                                       ln++;
+                                       f = (double)v;
+
+                                       while ((int)chrtab[*ln] & DIGIT)
+                                       {
+                                               f = f + (double)(*ln++ - '0') / fract;
+                                               fract *= 10;
+                                       }
+
+                                       *tk++ = FCONST;
+                                       *((double *)tk) = f;
+                                       tk += 2;
+                                       continue;
+                               }
+                       }
+                       else
+                       {
+                               *tk++ = CONST;
+                               tk64 = (uint64_t *)tk;
+                               *tk64++ = v;
+                               tk = (TOKEN *)tk64;
+                       }
 
 //printf("CONST: %i\n", v);
                        continue;
@@ -1685,8 +1742,8 @@ void DumpTokenBuffer(void)
                        printf("[COLON]");
                else if (*t == CONST)
                {
-                       t++;
-                       printf("[CONST: $%X]", (uint32_t)*t);
+                       printf("[CONST: $%lX]", ((uint64_t)t[1] << 32) | (uint64_t)t[2]);
+                       t += 2;
                }
                else if (*t == ACONST)
                {