X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=token.c;h=5f076a231cff1793394adaa0bba7a1a9b6fbed2d;hp=53f76a98c2e283e4e9042c4987aac4d081201e54;hb=d0c28c349ddfb8393568037f68bddbe8979ce0df;hpb=11a78647f7f170e6ea39dd04a3734a359151debb diff --git a/token.c b/token.c index 53f76a9..5f076a2 100644 --- a/token.c +++ b/token.c @@ -3,7 +3,7 @@ // TOKEN.C - Token Handling // Copyright (C) 199x Landon Dyer, 2011-2012 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" @@ -117,6 +117,57 @@ static char * riscregname[] = { }; +// +// Initialize tokenizer +// +void InitTokenizer(void) +{ + int i; // Iterator + char * htab = "0123456789abcdefABCDEF"; // Hex character table + + lnsave = 0; // Don't save lines + curfname = ""; // No file, empty filename + filecount = (WORD)-1; + cfileno = (WORD)-1; // cfileno gets bumped to 0 + curlineno = 0; + totlines = 0; + etok = tokbuf; + f_inobj = NULL; + f_ifile = NULL; + f_imacro = NULL; + cur_inobj = NULL; + filerec = NULL; + last_fr = NULL; + lntag = SPACE; + + // Initialize hex, "dot" and tolower tables + for(i=0; i<128; i++) + { + hextab[i] = -1; + dotxtab[i] = 0; + tolowertab[i] = (char)i; + } + + for(i=0; htab[i]!=EOS; i++) + hextab[htab[i]] = (char)((i < 16) ? i : i - 6); + + for(i='A'; i<='Z'; i++) + tolowertab[i] |= 0x20; + + // These characters are legal immediately after a period + dotxtab['b'] = DOTB; // .b .B .s .S + dotxtab['B'] = DOTB; + dotxtab['s'] = DOTB; + dotxtab['S'] = DOTB; + dotxtab['w'] = DOTW; // .w .W + dotxtab['W'] = DOTW; + dotxtab['l'] = DOTL; // .l .L + dotxtab['L'] = DOTL; + dotxtab['i'] = DOTI; // .i .I (???) + dotxtab['I'] = DOTI; +} + + void SetFilenameForErrorReporting(void) { WORD fnum = cfileno; @@ -401,7 +452,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) { @@ -561,9 +613,9 @@ overflow: // -// Get Next Line of Text from a Macro +// Get next line of text from a macro // -char * getmln(void) +char * GetNextMacroLine(void) { unsigned source_addr; @@ -579,41 +631,14 @@ char * getmln(void) // ExpandMacro((char *)(strp + 1), imacro->im_lnbuf, LNSIZ); ExpandMacro(strp->line, imacro->im_lnbuf, LNSIZ); -// bollocks -#if 0 - if (!strcmp(imacro->im_macro->sname, "mjump") && !mjump_align) - { - // if we need to adjust the alignment of the jump source address to - // meet the rules of gpu main execution we need to skip the first nop - // of the macro. This is simpler than trying to insert nop's mid macro. - source_addr = (orgactive ? orgaddr : sloc); - source_addr += 8; - - if (source_addr % 4) - { - strp = imacro->im_nextln; - - if (strp == NULL) - return NULL; - -// imacro->im_nextln = (LONG *)*strp; -// ExpandMacro((char *)(strp + 1), imacro->im_lnbuf, LNSIZ); - imacro->im_nextln = strp->next; - ExpandMacro(strp->line, imacro->im_lnbuf, LNSIZ); - } - - mjump_align = 1; - } -#endif - return imacro->im_lnbuf; } // -// Get Next Line of Text from a Repeat Block +// Get next line of text from a repeat block // -char * getrln(void) +char * GetNextRepeatLine(void) { IREPT * irept = cur_inobj->inobj.irept; @@ -643,7 +668,7 @@ char * getrln(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) { @@ -689,58 +714,7 @@ int include(int handle, char * fname) // -// Initialize Tokenizer -// -void init_token(void) -{ - int i; // Iterator - char * htab = "0123456789abcdefABCDEF"; // Hex character table - - lnsave = 0; // Don't save lines - curfname = ""; // No file, empty filename - filecount = (WORD)-1; - cfileno = (WORD)-1; // cfileno gets bumped to 0 - curlineno = 0; - totlines = 0; - etok = tokbuf; - f_inobj = NULL; - f_ifile = NULL; - f_imacro = NULL; - cur_inobj = NULL; - filerec = NULL; - last_fr = NULL; - lntag = SPACE; - - // Initialize hex, "dot" and tolower tables - for(i=0; i<128; i++) - { - hextab[i] = -1; - dotxtab[i] = 0; - tolowertab[i] = (char)i; - } - - for(i=0; htab[i]!=EOS; i++) - hextab[htab[i]] = (char)((i < 16) ? i : i - 6); - - for(i='A'; i<='Z'; i++) - tolowertab[i] |= 0x20; - - // These characters are legal immediately after a period - dotxtab['b'] = DOTB; // .b .B .s .S - dotxtab['B'] = DOTB; - dotxtab['s'] = DOTB; - dotxtab['S'] = DOTB; - dotxtab['w'] = DOTW; // .w .W - dotxtab['W'] = DOTW; - dotxtab['l'] = DOTL; // .l .L - dotxtab['L'] = DOTL; - dotxtab['I'] = DOTI; // .l .L - dotxtab['I'] = DOTI; -} - - -// -// Pop the Current Input Level +// Pop the current input level // int fpop(void) { @@ -809,7 +783,7 @@ if (verb_flag) printf("[fpop: (post) cfileno=%d ifile->ifno=%d]\n", (int)cfileno // Get line from file into buf, return NULL on EOF or ptr to the start of a // null-term line // -char * getln(void) +char * GetNextLine(void) { int i, j; char * p, * d; @@ -821,11 +795,9 @@ char * getln(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; @@ -853,11 +822,20 @@ char * getln(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. @@ -882,7 +860,9 @@ char * getln(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) @@ -892,29 +872,29 @@ char * getln(void) // -// Tokenize a Line +// Tokenize a line // -int tokln(void) +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: +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: @@ -923,9 +903,9 @@ int tokln(void) // o tag the listing-line with a space; // o kludge lines generated by Alcyon C. case SRC_IFILE: - if ((ln = getln()) == NULL) + if ((ln = GetNextLine()) == NULL) { -if (verb_flag) printf("tokln: Calling fpop() from SRC_IFILE...\n"); +if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); fpop(); // Pop input level goto retry; // Try for more lines } @@ -958,7 +938,7 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IFILE...\n"); // o Handle end-of-macro; // o tag the listing-line with an at (@) sign. case SRC_IMACRO: - if ((ln = getmln()) == NULL) + if ((ln = GetNextMacroLine()) == NULL) { ExitMacro(); // Exit macro (pop args, do fpop(), etc) goto retry; // Try for more lines... @@ -970,9 +950,9 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IFILE...\n"); // o Handle end-of-repeat-block; // o tag the listing-line with a pound (#) sign. case SRC_IREPT: - if ((ln = getrln()) == NULL) + if ((ln = GetNextRepeatLine()) == NULL) { -if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); +if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); fpop(); goto retry; } @@ -988,10 +968,10 @@ if (verb_flag) printf("tokln: 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 @@ -1021,12 +1001,12 @@ if (verb_flag) printf("tokln: 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 + p = nullspot = ln++; // Nullspot -> start of this symbol // Find end of symbol (and compute its length) for(j=1; (int)chrtab[*ln]&CTSYM; j++) @@ -1036,8 +1016,8 @@ if (verb_flag) printf("tokln: 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 @@ -1081,8 +1061,14 @@ if (verb_flag) printf("tokln: 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 user tries to use a RISC register while in 68K mode + if (!(rgpu || rdsp) && ((TOKEN)j >= KW_R0 && (TOKEN)j <= KW_R31)) + { + j = -1; + } + + // Make j = -1 if time, date etc with no preceeding ^^ + // defined, referenced, streq, macdef, date and time switch ((TOKEN)j) { case 112: // defined @@ -1092,15 +1078,15 @@ if (verb_flag) printf("tokln: 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) { *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 @@ -1136,7 +1122,7 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); { switch (*ln++) { - case '!': // ! or != + case '!': // ! or != if (*ln == '=') { *tk++ = NE; @@ -1146,8 +1132,8 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); *tk++ = '!'; continue; - case '\'': // 'string' - case '\"': // "string" + case '\'': // 'string' + case '\"': // "string" c1 = ln[-1]; *tk++ = STRING; //#warning @@ -1200,7 +1186,7 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); break; default: warn("bad backslash code in string"); - --ln; + ln--; break; } } @@ -1213,7 +1199,7 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); *p++ = EOS; continue; - case '$': // $, hex constant + case '$': // $, hex constant if ((int)chrtab[*ln] & HDIGIT) { v = 0; @@ -1223,19 +1209,19 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); if (*ln == '.') { - if ((*(ln+1) == 'b') || (*(ln+1) == 'B')) + if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B')) { v &= 0x000000FF; ln += 2; } - if ((*(ln+1) == 'w') || (*(ln+1) == 'W')) + if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) { v &= 0x0000FFFF; ln += 2; } - if ((*(ln+1) == 'l') || (*(ln+1) == 'L')) + if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) { ln += 2; } @@ -1248,7 +1234,7 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); *tk++ = '$'; continue; - case '<': // < or << or <> or <= + case '<': // < or << or <> or <= switch (*ln) { case '<': @@ -1267,7 +1253,7 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); *tk++ = '<'; continue; } - case ':': // : or :: + case ':': // : or :: if (*ln == ':') { *tk++ = DCOLON; @@ -1277,7 +1263,7 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); *tk++ = ':'; continue; - case '=': // = or == + case '=': // = or == if (*ln == '=') { *tk++ = DEQUALS; @@ -1287,22 +1273,22 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); *tk++ = '='; continue; - case '>': // > or >> or >= + case '>': // > or >> or >= switch (*ln) { case '>': *tk++ = SHR; - ++ln; + ln++; continue; case '=': *tk++ = GE; - ++ln; + ln++; continue; default: *tk++ = '>'; continue; } - case '%': // % or binary constant + case '%': // % or binary constant if (*ln < '0' || *ln > '1') { *tk++ = '%'; @@ -1337,7 +1323,7 @@ if (verb_flag) printf("tokln: 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++ = '@'; @@ -1372,7 +1358,7 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); *tk++ = CONST; *tk++ = v; continue; - case '^': // ^ or ^^ + case '^': // ^ or ^^ if (*ln != '^') { *tk++ = '^'; @@ -1424,7 +1410,7 @@ if (verb_flag) printf("tokln: 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; } } @@ -1437,22 +1423,20 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); while ((int)chrtab[*ln] & DIGIT) v = (v * 10) + *ln++ - '0'; - // See if there's a .[bwl] after the constant, & deal with it + // See if there's a .[bwl] after the constant & deal with it if so if (*ln == '.') { - if ((*(ln+1) == 'b') || (*(ln+1) == 'B')) + if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B')) { v &= 0x000000FF; ln += 2; } - - if ((*(ln+1) == 'w') || (*(ln+1) == 'W')) + else if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) { v &= 0x0000FFFF; ln += 2; } - - if ((*(ln+1) == 'l') || (*(ln+1) == 'L')) + else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) { ln += 2; } @@ -1460,6 +1444,7 @@ if (verb_flag) printf("tokln: Calling fpop() from SRC_IREPT...\n"); *tk++ = CONST; *tk++ = v; +//printf("CONST: %i\n", v); continue; } @@ -1500,11 +1485,7 @@ goteol: //int d_goto(void) int d_goto(WORD unused) { -// char * sym; // Label to search for -// LONG * defln; // Macro definition strings - char * s1; // Temps for string comparison - char * s2; -// IMACRO * imacro; // Macro invocation block + char * s1, * s2; // Setup for the search if (*tok != SYMBOL) @@ -1530,6 +1511,7 @@ int d_goto(WORD unused) { // Compare names (sleazo string compare) // This string compare is not right. Doesn't check for lengths. + // (actually it does, but in a crappy, unclear way.) #warning "!!! Bad string comparison !!!" s1 = sym; // s2 = (char *)(defln + 1) + 1; @@ -1576,7 +1558,6 @@ void DumpTokenBuffer(void) else if (*t == ACONST) printf("[ACONST]"); else if (*t == STRING) -// printf("[STRING]"); { t++; printf("[STRING:\"%s\"]", string[*t]); @@ -1642,7 +1623,6 @@ void DumpTokenBuffer(void) printf("[A%u]", ((uint32_t)*t) - 0x88); else printf("[%X:%c]", (uint32_t)*t, (char)*t); -// printf("[%X]", (uint32_t)*t); } printf("[EOL]\n");