X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=token.c;h=1722f63ee5bf8c4d8785fb7d551fda4528796f53;hp=6f42cca5d8f5306904c387e23f4f615bd928bfae;hb=49eac9eff9d177e717de7bc8799a632c46b79237;hpb=96a5cd69571096f11a3a2a40f6133374f0adc9bb diff --git a/token.c b/token.c index 6f42cca..1722f63 100644 --- a/token.c +++ b/token.c @@ -36,6 +36,7 @@ TOKEN * tok; // Ptr to current token TOKEN * etok; // Ptr past last token in tokbuf[] 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 @@ -48,12 +49,12 @@ FILEREC FILEREC * filerec; FILEREC * last_fr; -INOBJ * cur_inobj; // Ptr current input obj (IFILE/IMACRO) -static INOBJ * f_inobj; // Ptr list of free INOBJs -static IFILE * f_ifile; // Ptr list of free IFILEs -static IMACRO * f_imacro; // Ptr list of free IMACROs +INOBJ * cur_inobj; // Ptr current input obj (IFILE/IMACRO) +static INOBJ * f_inobj; // Ptr list of free INOBJs +static IFILE * f_ifile; // Ptr list of free IFILEs +static IMACRO * f_imacro; // Ptr list of free IMACROs -static TOKEN tokbuf[TOKBUFSIZE]; // Token buffer (stack-like, all files) +static TOKEN tokbuf[TOKBUFSIZE]; // Token buffer (stack-like, all files) uint8_t chrtab[0x100] = { ILLEG, ILLEG, ILLEG, ILLEG, // NUL SOH STX ETX @@ -282,6 +283,7 @@ INOBJ * a_inobj(int typ) inobj->inobj.ifile = ifile; break; + case SRC_IMACRO: // Alloc and init an IMACRO if (f_imacro == NULL) imacro = malloc(sizeof(IMACRO)); @@ -293,6 +295,7 @@ INOBJ * a_inobj(int typ) inobj->inobj.imacro = imacro; break; + case SRC_IREPT: // Alloc and init an IREPT inobj->inobj.irept = malloc(sizeof(IREPT)); DEBUG { printf("alloc IREPT\n"); } @@ -473,24 +476,18 @@ copy_d: // macro invocation) then it is ignored. i = (int)arg->svalue; arg_num: - DEBUG { printf("~argnumber=%d (argBase=%u)\n", i, imacro->argBase); } + DEBUG { printf("~argnumber=%d\n", i); } tk = NULL; if (i < imacro->im_nargs) { -#if 0 -// tk = argp[i]; -// tk = argPtrs[i]; - tk = argPtrs[imacro->argBase + i]; -#else tk = imacro->argument[i].token; symbolString = imacro->argument[i].string; //DEBUG //{ // printf("ExM: Preparing to parse argument #%u...\n", i); -// dumptok(tk); +// DumpTokens(tk); //} -#endif } // \?arg yields: @@ -680,7 +677,7 @@ char * GetNextMacroLine(void) { IMACRO * imacro = cur_inobj->inobj.imacro; // LONG * strp = imacro->im_nextln; - struct LineList * strp = imacro->im_nextln; + LLIST * strp = imacro->im_nextln; if (strp == NULL) // End-of-macro return NULL; @@ -699,10 +696,11 @@ char * GetNextMacroLine(void) char * GetNextRepeatLine(void) { IREPT * irept = cur_inobj->inobj.irept; - LONG * strp = irept->ir_nextln; // initial null +// LONG * strp = irept->ir_nextln; // initial null // Do repeat at end of .rept block's string list - if (strp == NULL) +// if (strp == NULL) + if (irept->ir_nextln == NULL) { DEBUG { printf("back-to-top-of-repeat-block count=%d\n", (int)irept->ir_count); } irept->ir_nextln = irept->ir_firstln; // copy first line @@ -713,12 +711,14 @@ char * GetNextRepeatLine(void) return NULL; } - strp = irept->ir_nextln; +// strp = irept->ir_nextln; } - strcpy(irbuf, (char *)(irept->ir_nextln + 1)); - DEBUG printf("repeat line='%s'\n", irbuf); - irept->ir_nextln = (LONG *)*strp; +// strcpy(irbuf, (char *)(irept->ir_nextln + 1)); + strcpy(irbuf, irept->ir_nextln->line); + DEBUG { printf("repeat line='%s'\n", irbuf); } +// irept->ir_nextln = (LONG *)*strp; + irept->ir_nextln = irept->ir_nextln->next; return irbuf; } @@ -736,16 +736,16 @@ int include(int handle, char * fname) INOBJ * inobj = a_inobj(SRC_IFILE); IFILE * ifile = inobj->inobj.ifile; - ifile->ifhandle = handle; // Setup file handle - ifile->ifind = ifile->ifcnt = 0; // Setup buffer indices - ifile->ifoldlineno = curlineno; // Save old line number - ifile->ifoldfname = curfname; // Save old filename - ifile->ifno = cfileno; // Save old file number + ifile->ifhandle = handle; // Setup file handle + ifile->ifind = ifile->ifcnt = 0; // Setup buffer indices + ifile->ifoldlineno = curlineno; // Save old line number + ifile->ifoldfname = curfname; // Save old filename + ifile->ifno = cfileno; // Save old file number // NB: This *must* be preincrement, we're adding one to the filecount here! - cfileno = ++filecount; // Compute NEW file number - curfname = strdup(fname); // Set current filename (alloc storage) - curlineno = 0; // Start on line zero + cfileno = ++filecount; // Compute NEW file number + curfname = strdup(fname); // Set current filename (alloc storage) + curlineno = 0; // Start on line zero // Add another file to the file-record FILEREC * fr = (FILEREC *)malloc(sizeof(FILEREC)); @@ -753,9 +753,9 @@ int include(int handle, char * fname) fr->frec_name = curfname; if (last_fr == NULL) - filerec = fr; // Add first filerec + filerec = fr; // Add first filerec else - last_fr->frec_next = fr; // Append to list of filerecs + last_fr->frec_next = fr; // Append to list of filerecs last_fr = fr; DEBUG { printf("[include: curfname: %s, cfileno=%u]\n", curfname, cfileno); } @@ -769,72 +769,78 @@ int include(int handle, char * fname) // int fpop(void) { - IFILE * ifile; - IMACRO * imacro; - LONG * p, * p1; INOBJ * inobj = cur_inobj; - if (inobj != NULL) - { - // Pop IFENT levels until we reach the conditional assembly context we - // were at when the input object was entered. - int numUnmatched = 0; + if (inobj == NULL) + return 0; - while (ifent != inobj->in_ifent) - { - if (d_endif() != 0) // Something bad happened during endif parsing? - return -1; // If yes, bail instead of getting stuck in a loop + // Pop IFENT levels until we reach the conditional assembly context we + // were at when the input object was entered. + int numUnmatched = 0; - numUnmatched++; - } + while (ifent != inobj->in_ifent) + { + if (d_endif() != 0) // Something bad happened during endif parsing? + return -1; // If yes, bail instead of getting stuck in a loop - // Give a warning to the user that we had to wipe their bum for them - if (numUnmatched > 0) - warn("missing %d .endif(s)", numUnmatched); + numUnmatched++; + } - tok = inobj->in_otok; // Restore tok and otok - etok = inobj->in_etok; + // Give a warning to the user that we had to wipe their bum for them + if (numUnmatched > 0) + warn("missing %d .endif(s)", numUnmatched); - switch (inobj->in_type) - { - case SRC_IFILE: // Pop and release an IFILE - DEBUG { printf("[Leaving: %s]\n", curfname); } + tok = inobj->in_otok; // Restore tok and otok + etok = inobj->in_etok; + + switch (inobj->in_type) + { + case SRC_IFILE: // Pop and release an IFILE + { + DEBUG { printf("[Leaving: %s]\n", curfname); } - ifile = inobj->inobj.ifile; - ifile->if_link = f_ifile; - f_ifile = ifile; - close(ifile->ifhandle); // Close source file + IFILE * ifile = inobj->inobj.ifile; + ifile->if_link = f_ifile; + f_ifile = ifile; + close(ifile->ifhandle); // Close source file DEBUG { printf("[fpop (pre): curfname=%s]\n", curfname); } - curfname = ifile->ifoldfname; // Set current filename + curfname = ifile->ifoldfname; // Set current filename DEBUG { printf("[fpop (post): curfname=%s]\n", curfname); } DEBUG { printf("[fpop: (pre) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno); } - curlineno = ifile->ifoldlineno; // Set current line# - DEBUG printf("cfileno=%d ifile->ifno=%d\n", (int)cfileno, (int)ifile->ifno); - cfileno = ifile->ifno; // Restore current file number + curlineno = ifile->ifoldlineno; // Set current line# + DEBUG { printf("cfileno=%d ifile->ifno=%d\n", (int)cfileno, (int)ifile->ifno); } + cfileno = ifile->ifno; // Restore current file number DEBUG { printf("[fpop: (post) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno); } - break; - case SRC_IMACRO: // Pop and release an IMACRO - imacro = inobj->inobj.imacro; - imacro->im_link = f_imacro; - f_imacro = imacro; - break; - case SRC_IREPT: // Pop and release an IREPT - DEBUG printf("dealloc IREPT\n"); - p = inobj->inobj.irept->ir_firstln; + break; + } - while (p != NULL) - { - p1 = (LONG *)*p; - p = p1; - } + case SRC_IMACRO: // Pop and release an IMACRO + { + IMACRO * imacro = inobj->inobj.imacro; + imacro->im_link = f_imacro; + f_imacro = imacro; + break; + } - break; + case SRC_IREPT: // Pop and release an IREPT + { + DEBUG { printf("dealloc IREPT\n"); } + LLIST * p = inobj->inobj.irept->ir_firstln; + + // Deallocate repeat lines + while (p != NULL) + { + free(p->line); + p = p->next; } - cur_inobj = inobj->in_link; - inobj->in_link = f_inobj; - f_inobj = inobj; + break; } + } + + cur_inobj = inobj->in_link; + inobj->in_link = f_inobj; + f_inobj = inobj; return 0; } @@ -971,7 +977,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } goto retry; // Try for more lines else { - ifent->if_prev = (IFENT *) - 1; //Signal Assemble() that we have reached EOF with unbalanced if/endifs + ifent->if_prev = (IFENT *)-1; //Signal Assemble() that we have reached EOF with unbalanced if/endifs return TKEOF; } } @@ -1000,27 +1006,29 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } } break; + // Macro-block: // o Handle end-of-macro; // o tag the listing-line with an at (@) sign. case SRC_IMACRO: if ((ln = GetNextMacroLine()) == NULL) { - if (ExitMacro() == 0) // Exit macro (pop args, do fpop(), etc) - goto retry; // Try for more lines... + if (ExitMacro() == 0) // Exit macro (pop args, do fpop(), etc) + goto retry; // Try for more lines... else - return TKEOF; // Oops, we got a non zero return code, signal EOF + return TKEOF; // Oops, we got a non zero return code, signal EOF } lntag = '@'; break; + // Repeat-block: // o Handle end-of-repeat-block; // o tag the listing-line with a pound (#) sign. case SRC_IREPT: if ((ln = GetNextRepeatLine()) == NULL) { -DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); } + DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); } fpop(); goto retry; } @@ -1029,13 +1037,13 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); } break; } - // Save text of the line. We only do this during listings and within + // Save text of the line. We only do this during listings and within // macro-type blocks, since it is expensive to unconditionally copy every // line. if (lnsave) strcpy(lnbuf, ln); - // General house-keeping + // General housekeeping tok = tokeol; // Set "tok" to EOL in case of error tk = etok; // Reset token ptr stuffnull = 0; // Don't stuff nulls @@ -1046,6 +1054,16 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); } if (*ln == '*' || *ln == ';' || ((*ln == '/') && (*(ln + 1) == '/'))) goto goteol; + // And here we have a very ugly hack for signalling a single line 'turn off + // optimization'. There's really no nice way to do this, so hack it is! + optimizeOff = 0; // Default is to take optimizations as they come + + if (*ln == '!') + { + optimizeOff = 1; // Signal that we don't want to optimize this line + ln++; // & skip over the darned thing + } + // Main tokenization loop; // o skip whitespace; // o handle end-of-line; @@ -1603,7 +1621,7 @@ int d_goto(WORD unused) return error("goto not in macro"); IMACRO * imacro = cur_inobj->inobj.imacro; - struct LineList * defln = imacro->im_macro->lineList; + LLIST * defln = imacro->im_macro->lineList; // Attempt to find the label, starting with the first line. for(; defln!=NULL; defln=defln->next) @@ -1642,10 +1660,9 @@ int d_goto(WORD unused) void DumpTokenBuffer(void) { - TOKEN * t; printf("Tokens [%X]: ", sloc); - for(t=tokbuf; *t!=EOL; t++) + for(TOKEN * t=tokbuf; *t!=EOL; t++) { if (*t == COLON) printf("[COLON]"); @@ -1655,7 +1672,10 @@ void DumpTokenBuffer(void) printf("[CONST: $%X]", (uint32_t)*t); } else if (*t == ACONST) - printf("[ACONST]"); + { + printf("[ACONST: $%X, $%X]", (uint32_t)t[1], (uint32_t)t[2]); + t += 2; + } else if (*t == STRING) { t++;