X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=token.c;h=81a040a958aefc6971baf53ef30f8186cbc3e070;hp=4a06efedcbebf1a0fdb72aec48857e74d6286b5a;hb=9207a38ed4a09c60a1e9b9995a92bcd4580e3662;hpb=6c1bc379012b1c1ca369e71e39509f3538042382 diff --git a/token.c b/token.c index 4a06efe..81a040a 100644 --- a/token.c +++ b/token.c @@ -1,30 +1,32 @@ // // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System // TOKEN.C - Token Handling -// Copyright (C) 199x Landon Dyer, 2011-2012 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 -// Source Utilised with the Kind Permission of Landon Dyer +// Source utilised with the kind permission of Landon Dyer // #include "token.h" +#include "direct.h" #include "error.h" #include "macro.h" #include "procln.h" +#include "sect.h" #include "symbol.h" #define DECL_KW // Declare keyword arrays -#define DEF_KW // Declare keyword values +#define DEF_KW // Declare keyword values #include "kwtab.h" // Incl generated keyword tables & defs int lnsave; // 1; strcpy() text of current line -int curlineno; // Current line number +uint16_t curlineno; // Current line number (64K max currently) int totlines; // Total # of lines int mjump_align = 0; // mjump alignment flag char lntag; // Line tag char * curfname; // Current filename -char tolowertab[128]; // Uppercase ==> lowercase -char hextab[128]; // Table of hex values +char tolowertab[128]; // Uppercase ==> lowercase +int8_t hextab[128]; // Table of hex values char dotxtab[128]; // Table for ".b", ".s", etc. char irbuf[LNSIZ]; // Text for .rept block line char lnbuf[LNSIZ]; // Text of current line @@ -54,28 +56,28 @@ static IMACRO * f_imacro; // Ptr list of free IMACROs static TOKEN tokbuf[TOKBUFSIZE]; // Token buffer (stack-like, all files) char chrtab[] = { - ILLEG, ILLEG, ILLEG, ILLEG, // NUL SOH STX ETX - ILLEG, ILLEG, ILLEG, ILLEG, // EOT ENQ ACK BEL - ILLEG, WHITE, ILLEG, ILLEG, // BS HT LF VT - WHITE, ILLEG, ILLEG, ILLEG, // FF CR SO SI + ILLEG, ILLEG, ILLEG, ILLEG, // NUL SOH STX ETX + ILLEG, ILLEG, ILLEG, ILLEG, // EOT ENQ ACK BEL + ILLEG, WHITE, ILLEG, ILLEG, // BS HT LF VT + WHITE, ILLEG, ILLEG, ILLEG, // FF CR SO SI - ILLEG, ILLEG, ILLEG, ILLEG, // DLE DC1 DC2 DC3 - ILLEG, ILLEG, ILLEG, ILLEG, // DC4 NAK SYN ETB - ILLEG, ILLEG, ILLEG, ILLEG, // CAN EM SUB ESC - ILLEG, ILLEG, ILLEG, ILLEG, // FS GS RS US + ILLEG, ILLEG, ILLEG, ILLEG, // DLE DC1 DC2 DC3 + ILLEG, ILLEG, ILLEG, ILLEG, // DC4 NAK SYN ETB + ILLEG, ILLEG, ILLEG, ILLEG, // CAN EM SUB ESC + ILLEG, ILLEG, ILLEG, ILLEG, // FS GS RS US WHITE, MULTX, MULTX, SELF, // SP ! " # MULTX+CTSYM, MULTX, SELF, MULTX, // $ % & ' SELF, SELF, SELF, SELF, // ( ) * + SELF, SELF, STSYM, SELF, // , - . / - DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 0 1 - DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 2 3 - DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 4 5 - DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 6 7 - DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 8 9 - MULTX, MULTX, // : ; - MULTX, MULTX, MULTX, STSYM+CTSYM, // < = > ? + DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 0 1 + DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 2 3 + DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 4 5 + DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 6 7 + DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 8 9 + MULTX, MULTX, // : ; + MULTX, MULTX, MULTX, STSYM+CTSYM, // < = > ? MULTX, STSYM+CTSYM+HDIGIT, // @ A (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // B C @@ -96,10 +98,10 @@ char chrtab[] = { STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // h i j k (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // l m n o - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // p q r s - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // t u v w - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z { - SELF, SELF, SELF, ILLEG // | } ~ DEL + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // p q r s + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // t u v w + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z { + SELF, SELF, SELF, ILLEG // | } ~ DEL }; // Names of registers @@ -110,7 +112,7 @@ static char * regname[] = { }; static char * riscregname[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" @@ -118,7 +120,7 @@ static char * riscregname[] = { // -// Initialize Tokenizer +// Initialize tokenizer // void InitTokenizer(void) { @@ -155,15 +157,15 @@ void InitTokenizer(void) tolowertab[i] |= 0x20; // These characters are legal immediately after a period - dotxtab['b'] = DOTB; // .b .B .s .S + dotxtab['b'] = DOTB; // .b .B .s .S dotxtab['B'] = DOTB; dotxtab['s'] = DOTB; dotxtab['S'] = DOTB; - dotxtab['w'] = DOTW; // .w .W + dotxtab['w'] = DOTW; // .w .W dotxtab['W'] = DOTW; - dotxtab['l'] = DOTL; // .l .L + dotxtab['l'] = DOTL; // .l .L dotxtab['L'] = DOTL; - dotxtab['i'] = DOTI; // .i .I (???) + dotxtab['i'] = DOTI; // .i .I (???) dotxtab['I'] = DOTI; } @@ -230,7 +232,7 @@ INOBJ * a_inobj(int typ) inobj->inobj.ifile = ifile; break; - case SRC_IMACRO: // Alloc and init an IMACRO + case SRC_IMACRO: // Alloc and init an IMACRO if (f_imacro == NULL) imacro = malloc(sizeof(IMACRO)); else @@ -288,7 +290,6 @@ int ExpandMacro(char * src, char * dest, int destsiz) IMACRO * imacro = cur_inobj->inobj.imacro; int macnum = (int)(imacro->im_macro->sattr); -// destsiz--; char * dst = dest; // Next dest slot char * edst = dest + destsiz - 1; // End + 1(?) of dest buffer @@ -314,6 +315,11 @@ int ExpandMacro(char * src, char * dest, int destsiz) if (dst >= edst) goto overflow; + // Skip comments in case a loose @ or \ is in there + // In that case the tokeniser was trying to expand it. + if ((*s == ';') || ((*s == '/') && (*(s + 1) == '/'))) + goto skipcomments; + *dst++ = *s++; } // Do macro expansion @@ -330,11 +336,11 @@ int ExpandMacro(char * src, char * dest, int destsiz) *dst++ = *s++; continue; - case '?': // \? set `questmark' flag + case '?': // \? set `questmark' flag ++s; questmark = 1; break; - case '#': // \#, number of arguments + case '#': // \#, number of arguments sprintf(numbuf, "%d", (int)imacro->im_nargs); goto copystr; case '!': // \! size suffix supplied on invocation @@ -347,7 +353,7 @@ int ExpandMacro(char * src, char * dest, int destsiz) } goto copy_d; - case '~': // ==> unique label string Mnnnn... + case '~': // ==> unique label string Mnnnn... sprintf(numbuf, "M%u", curuniq); copystr: d = numbuf; @@ -452,7 +458,8 @@ arg_num: continue; } - if (tk != NULL) // arg # is in range, so expand it + // Argument # is in range, so expand it + if (tk != NULL) { while (*tk != EOL) { @@ -510,9 +517,9 @@ DEBUG printf("ExM: SYMBOL=\"%s\"", d); *dst++ = '"'; continue; break; -// Shamus: Changing the format specifier from %lx to %ux caused -// the assembler to choke on legitimate code... Need to investigate -// this further before changing anything else here! +// Shamus: Changing the format specifier from %lx to %ux caused the assembler +// to choke on legitimate code... Need to investigate this further +// before changing anything else here! case CONST: sprintf(numbuf, "$%lx", (LONG)*tk++); d = numbuf; @@ -553,6 +560,9 @@ DEBUG printf("ExM: SYMBOL=\"%s\"", d); case DOTL: d = ".l"; break; + case CR_ABSCOUNT: + d = "^^abscount"; + break; case CR_DATE: d = "^^date"; break; @@ -600,6 +610,8 @@ strcopy: } } +skipcomments: + *dst = EOS; DEBUG { printf("ExM: dst=\"%s\"\n", dest); } return OK; @@ -612,12 +624,10 @@ overflow: // -// Get Next Line of Text from a Macro +// Get next line of text from a macro // char * GetNextMacroLine(void) { - unsigned source_addr; - IMACRO * imacro = cur_inobj->inobj.imacro; // LONG * strp = imacro->im_nextln; struct LineList * strp = imacro->im_nextln; @@ -625,7 +635,6 @@ char * GetNextMacroLine(void) if (strp == NULL) // End-of-macro return NULL; -// imacro->im_nextln = (LONG *)*strp; imacro->im_nextln = strp->next; // ExpandMacro((char *)(strp + 1), imacro->im_lnbuf, LNSIZ); ExpandMacro(strp->line, imacro->im_lnbuf, LNSIZ); @@ -635,7 +644,7 @@ char * GetNextMacroLine(void) // -// Get Next Line of Text from a Repeat Block +// Get next line of text from a repeat block // char * GetNextRepeatLine(void) { @@ -667,21 +676,17 @@ char * GetNextRepeatLine(void) // -// Include a Source File used at the Root, and for ".include" Files +// Include a source file used at the root, and for ".include" files // int include(int handle, char * fname) { - IFILE * ifile; - INOBJ * inobj; - FILEREC * fr; - - // Verbose mode - if (verb_flag) + // Debug mode + if (debug) printf("[include: %s, cfileno=%u]\n", fname, cfileno); // Alloc and initialize include-descriptors - inobj = a_inobj(SRC_IFILE); - ifile = inobj->inobj.ifile; + 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 @@ -689,21 +694,20 @@ int include(int handle, char * fname) ifile->ifoldfname = curfname; // Save old filename ifile->ifno = cfileno; // Save old file number -// cfileno = filecount++; // Compute new 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 // Add another file to the file-record - fr = (FILEREC *)malloc(sizeof(FILEREC)); + FILEREC * fr = (FILEREC *)malloc(sizeof(FILEREC)); fr->frec_next = NULL; 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); @@ -713,7 +717,7 @@ int include(int handle, char * fname) // -// Pop the Current Input Level +// Pop the current input level // int fpop(void) { @@ -726,30 +730,41 @@ int fpop(void) { // Pop IFENT levels until we reach the conditional assembly context we // were at when the input object was entered. + int numUnmatched = 0; + while (ifent != inobj->in_ifent) - d_endif(); + { + if (d_endif() != 0) // Something bad happened during endif parsing? + return -1; // If yes, bail instead of getting stuck in a loop - tok = inobj->in_otok; // Restore tok and otok + numUnmatched++; + } + + // Give a warning to the user that we had to wipe their bum for them + if (numUnmatched > 0) + warni("missing %d .endif(s)", numUnmatched); + + tok = inobj->in_otok; // Restore tok and otok etok = inobj->in_etok; switch (inobj->in_type) { - case SRC_IFILE: // Pop and release an IFILE - if (verb_flag) + case SRC_IFILE: // Pop and release an IFILE + if (debug) printf("[Leaving: %s]\n", curfname); ifile = inobj->inobj.ifile; ifile->if_link = f_ifile; f_ifile = ifile; close(ifile->ifhandle); // Close source file -if (verb_flag) printf("[fpop (pre): curfname=%s]\n", curfname); +if (debug) printf("[fpop (pre): curfname=%s]\n", curfname); curfname = ifile->ifoldfname; // Set current filename -if (verb_flag) printf("[fpop (post): curfname=%s]\n", curfname); -if (verb_flag) printf("[fpop: (pre) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno); - curlineno = ifile->ifoldlineno; // Set current line# +if (debug) printf("[fpop (post): curfname=%s]\n", curfname); +if (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 -if (verb_flag) printf("[fpop: (post) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno); +if (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; @@ -794,11 +809,9 @@ char * GetNextLine(void) // Scan for next end-of-line; handle stupid text formats by treating // \r\n the same as \n. (lone '\r' at end of buffer means we have to // check for '\n'). - i = 0; - j = fl->ifcnt; d = &fl->ifbuf[fl->ifind]; - for(p=d; iifcnt; i= j) - { - break; // Look for '\n' to eat - } + break; // Need to read more, then look for '\n' to eat else if (p[1] == '\n') - { i++; - } } + // Cover up the newline with end-of-string sentinel *p = '\0'; fl->ifind += i; @@ -826,11 +836,20 @@ char * GetNextLine(void) // Handle hanging lines by ignoring them (Input file is exhausted, no // \r or \n on last line) + // Shamus: This is retarded. Never ignore any input! if (!readamt && fl->ifcnt) { +#if 0 fl->ifcnt = 0; *p = '\0'; return NULL; +#else + // Really should check to see if we're at the end of the buffer! + // :-P + fl->ifbuf[fl->ifind + fl->ifcnt] = '\0'; + fl->ifcnt = 0; + return &fl->ifbuf[fl->ifind]; +#endif } // Truncate and return absurdly long lines. @@ -855,7 +874,9 @@ char * GetNextLine(void) fl->ifind = fl->ifcnt & 1; } - if ((readamt = read(fl->ifhandle, &fl->ifbuf[fl->ifind + fl->ifcnt], QUANTUM)) < 0) + readamt = read(fl->ifhandle, &fl->ifbuf[fl->ifind + fl->ifcnt], QUANTUM); + + if (readamt < 0) return NULL; if ((fl->ifcnt += readamt) == 0) @@ -865,29 +886,29 @@ char * GetNextLine(void) // -// Tokenize a Line +// Tokenize a line // int TokenizeLine(void) { - char * ln = NULL; // Ptr to current position in line - char * p; // Random character ptr - TOKEN * tk; // Token-deposit ptr - int state = 0; // State for keyword detector - int j = 0; // Var for keyword detector - char c; // Random char - VALUE v; // Random value - char * nullspot = NULL; // Spot to clobber for SYMBOL terminatn - int stuffnull; // 1:terminate SYMBOL '\0' at *nullspot + char * ln = NULL; // Ptr to current position in line + char * p; // Random character ptr + TOKEN * tk; // Token-deposit ptr + int state = 0; // State for keyword detector + int j = 0; // Var for keyword detector + char c; // Random char + VALUE v; // Random value + char * nullspot = NULL; // Spot to clobber for SYMBOL termination + int stuffnull; // 1:terminate SYMBOL '\0' at *nullspot char c1; - int stringNum = 0; // Pointer to string locations in tokenized line + int stringNum = 0; // Pointer to string locations in tokenized line retry: if (cur_inobj == NULL) // Return EOF if input stack is empty return TKEOF; - // Get another line of input from the current input source: a file, - // a macro, or a repeat-block + // Get another line of input from the current input source: a file, a + // macro, or a repeat-block switch (cur_inobj->in_type) { // Include-file: @@ -898,9 +919,14 @@ retry: case SRC_IFILE: if ((ln = GetNextLine()) == NULL) { -if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); - fpop(); // Pop input level - goto retry; // Try for more lines +if (debug) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); + if (fpop() == 0) // Pop input level + goto retry; // Try for more lines + else + { + ifent->if_prev = (IFENT *) - 1; //Signal Assemble() that we have reached EOF with unbalanced if/endifs + return TKEOF; + } } curlineno++; // Bump line number @@ -933,8 +959,10 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); case SRC_IMACRO: if ((ln = GetNextMacroLine()) == NULL) { - ExitMacro(); // 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 } lntag = '@'; @@ -945,7 +973,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); case SRC_IREPT: if ((ln = GetNextRepeatLine()) == NULL) { -if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); +if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); fpop(); goto retry; } @@ -961,10 +989,10 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); strcpy(lnbuf, ln); // General house-keeping - tok = tokeol; // Set "tok" to EOL in case of error - tk = etok; // Reset token ptr - stuffnull = 0; // Don't stuff nulls - totlines++; // Bump total #lines assembled + tok = tokeol; // Set "tok" to EOL in case of error + tk = etok; // Reset token ptr + stuffnull = 0; // Don't stuff nulls + totlines++; // Bump total #lines assembled // See if the entire line is a comment. This is a win if the programmer // puts in lots of comments @@ -984,7 +1012,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); ln++; // Handle EOL, comment with ';' - if (*ln == EOS || *ln == ';'|| ((*ln == '/') && (*(ln + 1) == '/'))) + if (*ln == EOS || *ln == ';'|| ((*ln == '/') && (*(ln + 1) == '/'))) break; // Handle start of symbol. Symbols are null-terminated in place. The @@ -994,12 +1022,33 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); if (c & STSYM) { - if (stuffnull) // Terminate old symbol from previous pass + if (stuffnull) // Terminate old symbol from previous pass *nullspot = EOS; - v = 0; // Assume no DOT attrib follows symbol + v = 0; // Assume no DOT attrib follows symbol stuffnull = 1; - p = nullspot = ln++; // Nullspot -> start of this symbol + + // In some cases, we need to check for a DOTx at the *beginning* + // of a symbol, as the "start" of the line we're currently looking + // at could be somewhere in the middle of that line! + if (*ln == '.') + { + // Make sure that it's *only* a .[bwsl] following, and not the + // start of a local symbol: + if ((chrtab[*(ln + 1)] & DOT) + && (dotxtab[*(ln + 1)] != 0) + && !(chrtab[*(ln + 2)] & CTSYM)) + { + // We found a legitimate DOTx construct, so add it to the + // token stream: + ln++; + stuffnull = 0; + *tk++ = (TOKEN)dotxtab[*ln++]; + continue; + } + } + + p = nullspot = ln++; // Nullspot -> start of this symbol // Find end of symbol (and compute its length) for(j=1; (int)chrtab[*ln]&CTSYM; j++) @@ -1009,20 +1058,20 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); // symbol or keyword: if (*ln == '.') { - *ln++ = EOS; // Terminate symbol - stuffnull = 0; // And never try it again + *ln++ = EOS; // Terminate symbol + stuffnull = 0; // And never try it again // Character following the `.' must have a DOT attribute, and // the chararacter after THAT one must not have a start-symbol // attribute (to prevent symbols that look like, for example, // "zingo.barf", which might be a good idea anyway....) - if ((((int)chrtab[*ln] & DOT) == 0) || ((int)dotxtab[*ln] <= 0)) - return error("[bwsl] must follow `.' in symbol"); + if (((chrtab[*ln] & DOT) == 0) || (dotxtab[*ln] == 0)) + return error("[bwsl] must follow '.' in symbol"); v = (VALUE)dotxtab[*ln++]; - if ((int)chrtab[*ln] & CTSYM) - return error("misuse of `.', not allowed in symbols"); + if (chrtab[*ln] & CTSYM) + return error("misuse of '.', not allowed in symbols"); } // If the symbol is small, check to see if it's really the name of @@ -1060,8 +1109,8 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); j = -1; } - //make j = -1 if time, date etc with no preceeding ^^ - //defined, referenced, streq, macdef, date and time + // Make j = -1 if time, date etc with no preceeding ^^ + // defined, referenced, streq, macdef, date and time switch ((TOKEN)j) { case 112: // defined @@ -1071,16 +1120,15 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); case 120: // time case 121: // date j = -1; -// break; } // If not tokenized keyword OR token was not found - if (j < 0 || state < 0) + if ((j < 0) || (state < 0)) { *tk++ = SYMBOL; //#warning -//problem here: nullspot is a char * but TOKEN is a uint32_t. On a 64-bit system, -//this will cause all kinds of mischief. +//problem here: nullspot is a char * but TOKEN is a uint32_t. On a 64-bit +//system, this will cause all kinds of mischief. #if 0 *tk++ = (TOKEN)nullspot; #else @@ -1114,9 +1162,10 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); // Handle multiple-character tokens if (c & MULTX) { + switch (*ln++) { - case '!': // ! or != + case '!': // ! or != if (*ln == '=') { *tk++ = NE; @@ -1126,20 +1175,21 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *tk++ = '!'; continue; - case '\'': // 'string' - case '\"': // "string" - c1 = ln[-1]; + case '\'': // 'string' + if (m6502) + { + // Hardcoded for now, maybe this will change in the future + *tk++ = STRINGA8; + goto dostring; + } + // Fall through + case '\"': // "string" *tk++ = STRING; -//#warning -// More char * stuffing (8 bytes) into the space of 4 (TOKEN). -// Need to figure out how to fix this crap. -#if 0 - *tk++ = (TOKEN)ln; -#else +dostring: + c1 = ln[-1]; string[stringNum] = ln; *tk++ = stringNum; stringNum++; -#endif for(p=ln; *ln!=EOS && *ln!=c1;) { @@ -1193,42 +1243,84 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *p++ = EOS; continue; - case '$': // $, hex constant - if ((int)chrtab[*ln] & HDIGIT) + case '$': // $, hex constant + if (chrtab[*ln] & HDIGIT) { v = 0; - while ((int)hextab[*ln] >= 0) + // Parse the hex value + while (hextab[*ln] >= 0) v = (v << 4) + (int)hextab[*ln++]; + // ggn: Okay, some comments here are in order I think.... + // The original madmac sources didn't parse the size at + // this point (i.e. .b/.w/.l). It was probably done at + // another point, although it's unclear to me exactly + // where. So why change this? My understanding (at least + // from what SCPCD said on IRC) is that .w addressing + // formats produce wrong code on jaguar (or doesn't execute + // properly? something like that). So the code was changed + // to mask off the upper bits depending on length (note: I + // don't think .b is valid at all! I only know of .w/.l, so + // this should probably be wiped). Then the code that + // parses the constant and checks to see if it's between + // $ffff0000 and $8000 never got triggered, so yay job + // done! ...now say we want to assemble a st .prg. One of + // the most widely spread optimisations is move.X expr.w,Y + // (or vice versa, or both, anyway...) to access hardware + // registers (which are mapped to $fxxxxx). This botchy + // thing would create "hilarious" code while trying to + // access hardware registers. So I made a condition to see + // if st mode or jaguar is active and apply the both or + // not. One last note: this is hardcoded to get optimised + // for now on ST mode, i.e. it can't generate code like + // move.w $00001234,d0 - it'll always get optimised to + // move.w $1234.w,d0. It's probably ok, but maybe a warning + // should be emitted? Or maybe finding a way to make it not + // auto-optimise? I think it's ok for now... if (*ln == '.') { - if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B')) + if (obj_format == BSD) { - v &= 0x000000FF; - ln += 2; + 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') + { + ln += 2; + } } + } + *tk++ = CONST; + *tk++ = v; + + if (obj_format == ALCYON) + { if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) { - v &= 0x0000FFFF; + *tk++ = DOTW; ln += 2; } - - if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) + else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) { + *tk++ = DOTL; ln += 2; } } - - *tk++ = CONST; - *tk++ = v; } else *tk++ = '$'; continue; - case '<': // < or << or <> or <= + case '<': // < or << or <> or <= switch (*ln) { case '<': @@ -1247,7 +1339,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *tk++ = '<'; continue; } - case ':': // : or :: + case ':': // : or :: if (*ln == ':') { *tk++ = DCOLON; @@ -1257,7 +1349,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *tk++ = ':'; continue; - case '=': // = or == + case '=': // = or == if (*ln == '=') { *tk++ = DEQUALS; @@ -1267,7 +1359,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *tk++ = '='; continue; - case '>': // > or >> or >= + case '>': // > or >> or >= switch (*ln) { case '>': @@ -1282,7 +1374,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *tk++ = '>'; continue; } - case '%': // % or binary constant + case '%': // % or binary constant if (*ln < '0' || *ln > '1') { *tk++ = '%'; @@ -1317,7 +1409,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *tk++ = CONST; *tk++ = v; continue; - case '@': // @ or octal constant + case '@': // @ or octal constant if (*ln < '0' || *ln > '7') { *tk++ = '@'; @@ -1352,7 +1444,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *tk++ = CONST; *tk++ = v; continue; - case '^': // ^ or ^^ + case '^': // ^ or ^^ if (*ln != '^') { *tk++ = '^'; @@ -1372,7 +1464,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); for(state=0; state>=0;) { - // Get char, convert to lowercase + // Get char, convert to lowercase j = *p++; if (j >= 'A' && j <= 'Z') @@ -1404,7 +1496,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *tk++ = (TOKEN)j; continue; default: - interror(2); // Bad MULTX entry in chrtab + interror(2); // Bad MULTX entry in chrtab continue; } } @@ -1438,6 +1530,7 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); *tk++ = CONST; *tk++ = v; +//printf("CONST: %i\n", v); continue; } @@ -1461,34 +1554,25 @@ goteol: // // .GOTO