]> Shamusworld >> Repos - rmac/blobdiff - token.c
Addendum for #193: Do less tokenisation processing when inside a disabled code block
[rmac] / token.c
diff --git a/token.c b/token.c
index 1e5428200bf0ce952b748445e15349f42bd09765..93d958f7c6ca948105354854e1347c1ceebf3711 100644 (file)
--- a/token.c
+++ b/token.c
@@ -1,7 +1,7 @@
 //
-// RMAC - Reboot's Macro Assembler for all Atari computers
+// RMAC - Renamed Macro Assembler for all Atari computers
 // TOKEN.C - Token Handling
-// Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2021 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -22,7 +22,7 @@
 
 
 int lnsave;                                    // 1; strcpy() text of current line
-uint16_t curlineno;                    // Current line number (64K max currently)
+uint32_t curlineno;                    // Current line number (64K max currently)
 int totlines;                          // Total # of lines
 int mjump_align = 0;           // mjump alignment flag
 char lntag;                                    // Line tag
@@ -40,13 +40,6 @@ TOKEN tokeol[1] = {EOL};     // Bailout end-of-line token
 char * string[TOKBUFSIZE*2];// Token buffer string pointer storage
 int optimizeOff;                       // Optimization override flag
 
-// File record, used to maintain a list of every include file ever visited
-#define FILEREC struct _filerec
-FILEREC
-{
-   FILEREC * frec_next;
-   char * frec_name;
-};
 
 FILEREC * filerec;
 FILEREC * last_fr;
@@ -673,7 +666,6 @@ overflow:
 char * GetNextMacroLine(void)
 {
        IMACRO * imacro = cur_inobj->inobj.imacro;
-//     LONG * strp = imacro->im_nextln;
        LLIST * strp = imacro->im_nextln;
 
        if (strp == NULL)                                               // End-of-macro
@@ -707,7 +699,7 @@ char * GetNextRepeatLine(void)
                        DEBUG { printf("end-repeat-block\n"); }
                        return NULL;
                }
-
+               reptuniq++;
 //             strp = irept->ir_nextln;
        }
        // Mark the current macro line in the irept object
@@ -716,8 +708,33 @@ char * GetNextRepeatLine(void)
        // error reporting anyway)
        irept->lineno = irept->ir_nextln->lineno;
 
-//     strcpy(irbuf, (char *)(irept->ir_nextln + 1));
-       strcpy(irbuf, irept->ir_nextln->line);
+       // Copy the rept lines verbatim, unless we're in nest level 0.
+       // Then, expand any \~ labels to unique numbers (Rn)
+       if (rptlevel)
+       {
+               strcpy(irbuf, irept->ir_nextln->line);
+       }
+       else
+       {
+               uint32_t linelen = strlen(irept->ir_nextln->line);
+               uint8_t *p_line = irept->ir_nextln->line;
+               char *irbufwrite = irbuf;
+               for (int i = 0; i <= linelen; i++)
+               {
+                       uint8_t c;
+                       c = *p_line++;
+                       if (c == '\\' && *p_line == '~')
+                       {
+                               p_line++;
+                               irbufwrite += sprintf(irbufwrite, "R%u", reptuniq);
+                       }
+                       else
+                       {
+                               *irbufwrite++ = c;
+                       }
+               }
+       }
+
        DEBUG { printf("repeat line='%s'\n", irbuf); }
 //     irept->ir_nextln = (LONG *)*strp;
        irept->ir_nextln = irept->ir_nextln->next;
@@ -957,6 +974,8 @@ int TokenizeLine(void)
        int stuffnull;                          // 1:terminate SYMBOL '\0' at *nullspot
        uint8_t c1;
        int stringNum = 0;                      // Pointer to string locations in tokenized line
+       SYM* sy;                                        // For looking up symbols (.equr)
+       int equrundef = 0;                      // Flag for equrundef scanning
 
 retry:
 
@@ -988,26 +1007,6 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); }
                curlineno++;                    // Bump line number
                lntag = SPACE;
 
-               if (as68_flag)
-               {
-                       // AS68 compatibility, throw away all lines starting with
-                       // back-quotes, tildes, or '*'
-                       // On other lines, turn the first '*' into a semi-colon.
-                       if (*ln == '`' || *ln == '~' || *ln == '*')
-                               *ln = ';';
-                       else
-                       {
-                               for(p=ln; *p!=EOS; p++)
-                               {
-                                       if (*p == '*')
-                                       {
-                                               *p = ';';
-                                               break;
-                                       }
-                               }
-                       }
-               }
-
                break;
 
        // Macro-block:
@@ -1082,7 +1081,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); }
        for(; *ln!=EOS;)
        {
                // Check to see if there's enough space in the token buffer
-               if (tk.cp >= ((uint8_t *)(&tokbuf[TOKBUFSIZE])))
+               if (tk.cp >= ((uint8_t *)(&tokbuf[TOKBUFSIZE])) - 20)
                {
                        return error("token buffer overrun");
                }
@@ -1200,12 +1199,41 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); }
                        case 119:   // macdef
                        case 120:   // time
                        case 121:   // date
+                       case KW_FILESIZE: // filesize
+                               j = -1;
+                       }
+                       
+                       // If we detected equrundef/regundef set relevant flag
+                       if (j == KW_EQURUNDEF)
+                       {
+                               equrundef = 1;
                                j = -1;
                        }
 
                        // If not tokenized keyword OR token was not found
                        if ((j < 0) || (state < 0))
                        {
+                               // Only proceed if no equrundef has been detected. In that case we need to store the symbol
+                               // because the directive handler (d_equrundef) will run outside this loop, further into procln.c
+                               if (!equrundef && !disabled)
+                               {
+                                       // Last attempt: let's see if this is an equated register.
+                                       // If yes, then just store the register's keyword value instead of the symbol
+                                       char temp = *ln;
+                                       *ln = 0;
+                                       sy = lookup(nullspot, LABEL, 0);
+                                       *ln = temp;
+                                       if (sy)
+                                       {
+                                               if (sy->sattre & EQUATEDREG)
+                                               {
+                                                       *tk.u32++ = sy->svalue;
+                                                       stuffnull = 0;
+                                                       continue;
+                                               }
+                                       }
+                               }
+                               // Ok, that failed, let's store the symbol instead
                                *tk.u32++ = SYMBOL;
                                string[stringNum] = nullspot;
                                *tk.u32++ = stringNum;
@@ -1663,7 +1691,7 @@ int d_goto(WORD unused)
                {
                        // Compare names (sleazo string compare)
                        char * s1 = sym;
-                       char * s2 = defln->line;
+                       char * s2 = defln->line + 1;
 
                        // Either we will match the strings to EOS on both, or we will
                        // match EOS on string 1 to whitespace on string 2. Otherwise, we