X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=token.c;h=d6426600b8f5de1c94acf12256a80b0094eaac81;hb=refs%2Ftags%2Fv2.1.9;hp=9d6decf5468709082b4c4551c4ed3948f219b837;hpb=9153334781cd2e23750f4dc002e847606c07a1f0;p=rmac diff --git a/token.c b/token.c index 9d6decf..d642660 100644 --- 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-2018 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; @@ -560,7 +553,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", (uint64_t)*tk++); +// sprintf(numbuf, "$%lx", (uint64_t)*tk++); + sprintf(numbuf, "$%" PRIX64, (uint64_t)*tk++); tk++; d = numbuf; break; @@ -603,6 +597,9 @@ DEBUG { printf("ExM: SYMBOL=\"%s\"", d); } case CR_ABSCOUNT: d = "^^abscount"; break; + case CR_FILESIZE: + d = "^^filesize"; + break; case CR_DATE: d = "^^date"; break; @@ -669,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 @@ -703,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 @@ -712,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; @@ -788,7 +809,7 @@ int fpop(void) if (numUnmatched > 0) warn("missing %d .endif(s)", numUnmatched); - tok = inobj->in_otok; // Restore tok and otok + tok = inobj->in_otok; // Restore tok and etok etok = inobj->in_etok; switch (inobj->in_type) @@ -949,7 +970,6 @@ int TokenizeLine(void) uint8_t c; // Random char 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; @@ -1041,7 +1061,13 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } // macro-type blocks, since it is expensive to unconditionally copy every // line. if (lnsave) + { + // Sanity check + if (strlen(ln) > LNSIZ) + return error("line too long (%d, max %d)", strlen(ln), LNSIZ); + strcpy(lnbuf, ln); + } // General housekeeping tok = tokeol; // Set "tok" to EOL in case of error @@ -1072,6 +1098,12 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } // o handle multiple-character tokens (constants, strings, etc.). for(; *ln!=EOS;) { + // Check to see if there's enough space in the token buffer + if (tk.cp >= ((uint8_t *)(&tokbuf[TOKBUFSIZE])) - 20) + { + return error("token buffer overrun"); + } + // Skip whitespace, handle EOL while (chrtab[*ln] & WHITE) ln++; @@ -1170,7 +1202,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } } // Make j = -1 if user tries to use a RISC register while in 68K mode - if (!(rgpu || rdsp) && ((TOKEN)j >= KW_R0 && (TOKEN)j <= KW_R31)) + if (!(rgpu || rdsp || dsp56001) && ((TOKEN)j >= KW_R0 && (TOKEN)j <= KW_R31)) { j = -1; } @@ -1286,6 +1318,10 @@ dostring: case '\\': c = '\\'; break; + case '{': + // If we're evaluating a macro + // this is valid because it's + // a parameter expansion case '!': // If we're evaluating a macro // this is valid and expands to @@ -1315,45 +1351,20 @@ dostring: while (hextab[*ln] >= 0) v = (v << 4) + (int)hextab[*ln++]; - if (*ln == '.') - { - if (obj_format == BSD) - { - if ((*(ln + 1) & 0xDF) == 'B') - { - v &= 0x000000FF; - ln += 2; - } - else if ((*(ln + 1) & 0xDF) == 'W') - { - v &= 0x0000FFFF; - ln += 2; - } - else if ((*(ln + 1) & 0xDF) == 'L') - { - v &= 0xFFFFFFFF; - ln += 2; - } - } - } - *tk.u32++ = CONST; *tk.u64++ = v; - if (obj_format == ALCYON) + if (*ln == '.') { - if (*ln == '.') + if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) { - if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) - { - *tk.u32++ = DOTW; - ln += 2; - } - else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) - { - *tk.u32++ = DOTL; - ln += 2; - } + *tk.u32++ = DOTW; + ln += 2; + } + else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) + { + *tk.u32++ = DOTL; + ln += 2; } } } @@ -1669,7 +1680,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 @@ -1752,6 +1763,8 @@ void DumpToken(TOKEN t) printf("[ENDEXPR]"); else if (t == CR_ABSCOUNT) printf("[CR_ABSCOUNT]"); + else if (t == CR_FILESIZE) + printf("[CR_FILESIZE]"); else if (t == CR_DEFINED) printf("[CR_DEFINED]"); else if (t == CR_REFERENCED) @@ -1856,6 +1869,8 @@ void DumpTokenBuffer(void) printf("[ENDEXPR]"); else if (*t == CR_ABSCOUNT) printf("[CR_ABSCOUNT]"); + else if (*t == CR_FILESIZE) + printf("[CR_FILESIZE]"); else if (*t == CR_DEFINED) printf("[CR_DEFINED]"); else if (*t == CR_REFERENCED)