From: Shamus Hammons Date: Sat, 24 Jun 2017 00:03:24 +0000 (-0500) Subject: Fixed bad char reporting, revamp of the error/warning system. X-Git-Tag: v2.1.0~119 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=commitdiff_plain;h=96a5cd69571096f11a3a2a40f6133374f0adc9bb Fixed bad char reporting, revamp of the error/warning system. Somehow I put a unicode character in my assembly source and RMAC then barfed up an internal error #2. Chasing this down, I finally determined that the debug traces weren't lying to me and the input file had a problem. However, RMAC wasn't reporting the illegal character correctly either, so that was fixed (who knew that gcc was silently killing bit 7 of chars now?). I also realized that having five separate functions for reporting errors (and the cruft of using those crippled things) was just a wee bit insane, so now we have proper variable argument error and warning functions (they can be used just like a printf). Enjoy! --- diff --git a/direct.c b/direct.c index 5da6347..5714def 100644 --- a/direct.c +++ b/direct.c @@ -165,7 +165,7 @@ int d_error(char *str) return error(string[tok[1]]); break; default: - return error("error directive encountered - aborting assembling"); + return error("error directive encountered--aborting assembly"); } } } @@ -428,14 +428,13 @@ int d_incbin(void) int fd; int bytes = 0; long pos, size, bytesRead; - char msg[256]; char buf1[256]; int i; // Check to see if we're in BSS, and, if so, throw an error if (scattr & SBSS) { - errors("cannot include binary file \"%s\" in BSS section", string[tok[1]]); + error("cannot include binary file \"%s\" in BSS section", string[tok[1]]); return ERROR; } @@ -464,7 +463,7 @@ int d_incbin(void) goto allright; } - return errors("cannot open: \"%s\"", string[tok[1]]); + return error("cannot open: \"%s\"", string[tok[1]]); } allright: @@ -480,8 +479,7 @@ allright: if (bytesRead != size) { - sprintf(msg, "was only able to read %li bytes from binary file (%s, %li bytes)", bytesRead, string[tok[1]], size); - error(msg); + error("was only able to read %li bytes from binary file (%s, %li bytes)", bytesRead, string[tok[1]], size); return ERROR; } @@ -741,7 +739,7 @@ int d_include(void) // Make sure the user didn't try anything like: // .include equates.s if (*++tok != EOL) - return error("extra stuff after filename -- enclose it in quotes"); + return error("extra stuff after filename--enclose it in quotes"); // Attempt to open the include file in the current directory, then (if that // failed) try list of include files passed in the enviroment string or by @@ -762,7 +760,7 @@ int d_include(void) goto allright; } - return errors("cannot open: \"%s\"", fn); + return error("cannot open: \"%s\"", fn); } allright: @@ -1064,10 +1062,7 @@ int d_dc(WORD siz) return error("non-absolute byte value"); if (eval + 0x100 >= 0x200) - { - sprintf(buffer, "%s (value = $%X)", range_error, eval); - return error(buffer); - } + return error("%s (value = $%X)", range_error, eval); D_byte(eval); } @@ -1590,7 +1585,7 @@ int d_cargs(void) symbol->sattr = 0; } else if (symbol->sattr & DEFINED) - return errors("multiply-defined label '%s'", p); + return error("multiply-defined label '%s'", p); // Put symbol in "order of definition" list AddToSymbolDeclarationList(symbol); @@ -1706,7 +1701,7 @@ int d_cstruct(void) symbol->sattr = 0; } else if (symbol->sattr & DEFINED) - return errors("multiply-defined label '%s'", symbolName); + return error("multiply-defined label '%s'", symbolName); // Put symbol in "order of definition" list AddToSymbolDeclarationList(symbol); @@ -1839,11 +1834,7 @@ int d_opt(void) char * tmpstr = string[*tok++]; if (ParseOptimization(tmpstr) != OK) - { - char temperr[256]; - sprintf(temperr, "unknown optimization flag '%s'", tmpstr); - return error(temperr); - } + return error("unknown optimization flag '%s'", tmpstr); } else return error(".opt directive needs every switch enclosed inside quotation marks"); diff --git a/error.c b/error.c index 81f0633..6da93e2 100644 --- a/error.c +++ b/error.c @@ -7,13 +7,13 @@ // #include "error.h" -#include "token.h" +#include #include "listing.h" +#include "token.h" int errcnt; // Error count char * err_fname; // Name of error message file -static const char nl[] = "\n"; static long unused; // For supressing 'write' warnings @@ -22,13 +22,8 @@ static long unused; // For supressing 'write' warnings // int at_eol(void) { - char msg[256]; - if (*tok != EOL) - { - sprintf(msg, "syntax error. expected EOL, found $%X ('%c')", *tok, *tok); - error(msg); - } + error("syntax error. expected EOL, found $%X ('%c')", *tok, *tok); return 0; } @@ -46,17 +41,13 @@ void cantcreat(const char * fn) // // Setup for error message -// o Create error listing file (if necessary) -// o Set current filename +// o Create error listing file (if necessary) +// o Set current filename // void err_setup(void) { char fnbuf[FNSIZ]; -// This seems like it's unnecessary, as token.c seems to take care of this all by itself. -// Can restore if it's really needed. If not, into the bit bucket it goes. :-) -// setfnum(cfileno); - if (err_fname != NULL) { strcpy(fnbuf, err_fname); @@ -75,45 +66,24 @@ void err_setup(void) // -// Display error message +// Display error message (uses printf() style variable arguments) // -int error(const char * s) -{ - char buf[EBUFSIZ]; - unsigned int length; - - err_setup(); - - if (listing > 0) - ship_ln(s); - - sprintf(buf, "%s %d: Error: %s%s", curfname, curlineno, s, nl); - length = strlen(buf); - - if (err_flag) - unused = write(err_fd, buf, length); - else - printf("%s", buf); - - taglist('E'); - errcnt++; - - return ERROR; -} - - -int errors(const char * s, char * s1) +int error(const char * text, ...) { char buf[EBUFSIZ]; char buf1[EBUFSIZ]; err_setup(); - sprintf(buf, s, s1); + + va_list arg; + va_start(arg, text); + vsprintf(buf, text, arg); + va_end(arg); if (listing > 0) ship_ln(buf); - sprintf(buf1, "%s %d: Error: %s%s", curfname, curlineno, buf, nl); + sprintf(buf1, "%s %d: Error: %s\n", curfname, curlineno, buf); if (err_flag) unused = write(err_fd, buf1, (LONG)strlen(buf1)); @@ -121,70 +91,30 @@ int errors(const char * s, char * s1) printf("%s", buf1); taglist('E'); - ++errcnt; + errcnt++; return ERROR; } -int warn(const char * s) -{ - char buf[EBUFSIZ]; - - err_setup(); - - if (listing > 0) - ship_ln(s); - - sprintf(buf, "%s %d: Warning: %s%s", curfname, curlineno, s, nl); - - if (err_flag) - unused = write(err_fd, buf, (LONG)strlen(buf)); - else - printf("%s", buf); - - taglist('W'); - - return OK; -} - - -int warns(const char * s, char * s1) -{ - char buf[EBUFSIZ]; - char buf1[EBUFSIZ]; - - err_setup(); - sprintf(buf, s, s1); - - if (listing > 0) - ship_ln(s); - - sprintf(buf1, "%s %d: Warning: %s%s", curfname, curlineno, buf, nl); - - if (err_flag) - unused = write(err_fd, buf1, (LONG)strlen(buf1)); - else - printf("%s", buf1); - - taglist('W'); - - return OK; -} - - -int warni(const char * s, unsigned i) +// +// Display warning message (uses printf() style variable arguments) +// +int warn(const char * text, ...) { char buf[EBUFSIZ]; char buf1[EBUFSIZ]; err_setup(); - sprintf(buf, s, i); + va_list arg; + va_start(arg, text); + vsprintf(buf, text, arg); + va_end(arg); if (listing > 0) ship_ln(buf); - sprintf(buf1, "%s %d: Warning: %s%s", curfname, curlineno, buf, nl); + sprintf(buf1, "%s %d: Warning: %s\n", curfname, curlineno, buf); if (err_flag) unused = write(err_fd, buf1, (LONG)strlen(buf1)); @@ -206,7 +136,7 @@ int fatal(const char * s) if (listing > 0) ship_ln(s); - sprintf(buf, "%s %d: Fatal: %s%s", curfname, curlineno, s, nl); + sprintf(buf, "%s %d: Fatal: %s\n", curfname, curlineno, s); if (err_flag) unused = write(err_fd, buf, (LONG)strlen(buf)); @@ -222,7 +152,7 @@ int interror(int n) char buf[EBUFSIZ]; err_setup(); - sprintf(buf, "%s %d: Internal Error Number %d%s", curfname, curlineno, n, nl); + sprintf(buf, "%s %d: Internal error #%d\n", curfname, curlineno, n); if (listing > 0) ship_ln(buf); diff --git a/error.h b/error.h index 0e90b25..a81ede7 100644 --- a/error.h +++ b/error.h @@ -18,12 +18,9 @@ extern int errcnt; extern char * err_fname; // Exported functions -int error(const char *); -int errors(const char *, char *); +int error(const char *, ...); +int warn(const char *, ...); int fatal(const char *); -int warn(const char *); -int warns(const char *, char *); -int warni(const char *, unsigned); int interror(int); void cantcreat(const char *); void err_setup(void); diff --git a/expr.c b/expr.c index 44fd892..c89b182 100644 --- a/expr.c +++ b/expr.c @@ -244,10 +244,10 @@ int expr2(void) if (sy->sattre & EQUATEDREG) { if ((regbank == BANK_0) && (sy->sattre & BANK_1) && !altbankok) - warns("equated symbol \'%s\' cannot be used in register bank 0", sy->sname); + warn("equated symbol \'%s\' cannot be used in register bank 0", sy->sname); if ((regbank == BANK_1) && (sy->sattre & BANK_0) && !altbankok) - warns("equated symbol \'%s\' cannot be used in register bank 1", sy->sname); + warn("equated symbol \'%s\' cannot be used in register bank 1", sy->sname); } *evalTokenBuffer++ = SYMBOL; @@ -264,7 +264,7 @@ int expr2(void) return ERROR; if (*tok++ != ')') - return error("missing close parenthesis ')'"); + return error("missing closing parenthesis ')'"); break; case '[': @@ -272,7 +272,7 @@ int expr2(void) return ERROR; if (*tok++ != ']') - return error("missing close parenthesis ']'"); + return error("missing closing bracket ']'"); break; case '$': @@ -299,7 +299,7 @@ int expr2(void) return ERROR; if (*tok++ != '}') - return error("missing close bracket '}'"); + return error("missing closing brace '}'"); break; default: @@ -400,7 +400,7 @@ if (symbol) // means it will be fixed up later, and thus, not an error. if ((symbol->sattre & UNDEF_EQUR) && !riscImmTokenSeen) { - errors("undefined register equate '%s'", symbol->sname); + error("undefined register equate '%s'", symbol->sname); //if we return right away, it returns some spurious errors... // return ERROR; } @@ -409,10 +409,10 @@ if (symbol) if (symbol->sattre & EQUATEDREG) { if ((regbank == BANK_0) && (symbol->sattre & BANK_1) && !altbankok) - warns("equated symbol '%s' cannot be used in register bank 0", symbol->sname); + warn("equated symbol '%s' cannot be used in register bank 0", symbol->sname); if ((regbank == BANK_1) && (symbol->sattre & BANK_0) && !altbankok) - warns("equated symbol '%s' cannot be used in register bank 1", symbol->sname); + warn("equated symbol '%s' cannot be used in register bank 1", symbol->sname); } *evalTokenBuffer++ = SYMBOL; @@ -694,7 +694,7 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); sattr--; // Pop attrib if (sval[1] == 0) - return error("divide by zero"); + return error("division by zero"); //printf("--> N/N: %i / %i = ", sval[0], sval[1]); // Compiler is picky here: Without casting these, it discards diff --git a/macro.c b/macro.c index f0152ce..2ebaf52 100644 --- a/macro.c +++ b/macro.c @@ -332,7 +332,7 @@ int lncatch(int (* lnfunc)(), char * dirlist) { if (TokenizeLine() == TKEOF) { - errors("encountered end-of-file looking for '%s'", dirlist); + error("encountered end-of-file looking for '%s'", dirlist); fatal("cannot continue"); } diff --git a/mark.c b/mark.c index 088263b..664e318 100644 --- a/mark.c +++ b/mark.c @@ -90,18 +90,13 @@ if (symbol) // // Complain about some things are not allowed in '-p' (PRG) mode: - // o Marks that aren't to LONGs - // o External references + // o Marks that aren't to LONGs + // o External references // if (prg_flag) { -#if 0 - if ((flags & MLONG) == 0) - error("illegal word relocatable (in .PRG mode)"); -#endif - if (symbol != NULL) - errors("illegal external reference (in .PRG mode) to '%s'", + error("illegal external reference (in .PRG mode) to '%s'", symbol->sname); } diff --git a/procln.c b/procln.c index b5fa40b..989bc68 100644 --- a/procln.c +++ b/procln.c @@ -150,7 +150,7 @@ loop: // Line processing loop label // Get another line of tokens if (TokenizeLine() == TKEOF) { -if (debug) printf("Assemble: Found TKEOF flag...\n"); +DEBUG { printf("Assemble: Found TKEOF flag...\n"); } if (list_flag && listflag) // Flush last line of source listeol(); @@ -160,7 +160,7 @@ if (debug) printf("Assemble: Found TKEOF flag...\n"); return; } - DEBUG DumpTokenBuffer(); + DEBUG { DumpTokenBuffer(); } if (list_flag) { @@ -187,10 +187,11 @@ loop1: // Internal line processing loop // First token MUST be a symbol (Shamus: not sure why :-/) if (*tok != SYMBOL) { - if (*tok>=KW_D0 && *tok<=KW_R31) - error("cannot use reserved keyword as label name or .equ"); - else - error("syntax error; expected symbol"); + if ((*tok >= KW_D0) && (*tok <= KW_R31)) + error("cannot use reserved keyword as label name or .equ"); + else + error("syntax error; expected symbol"); + goto loop; } @@ -408,7 +409,7 @@ normal: } else { - errors("multiple equate to '%s'", sy->sname); + error("multiple equate to '%s'", sy->sname); goto loop; } } @@ -668,7 +669,7 @@ When checking to see if it's already been equated, issue a warning. if ((sy = lookup(opname, MACRO, 0)) != NULL) InvokeMacro(sy, siz); else - errors("unknown op '%s'", opname); + error("unknown op '%s'", opname); goto loop; } @@ -681,10 +682,10 @@ When checking to see if it's already been equated, issue a warning. } // Do mnemonics - // o can't deposit instrs in BSS or ABS - // o do automatic .EVEN for instrs - // o allocate space for largest possible instr - // o can't do ".b" operations with an address register + // o can't deposit instrs in BSS or ABS + // o do automatic .EVEN for instrs + // o allocate space for largest possible instr + // o can't do ".b" operations with an address register if (scattr & SBSS) { error("cannot initialize non-storage (BSS) section"); @@ -756,7 +757,7 @@ int HandleLabel(char * label, int labelType) symbol->sattre = 0; } else if (symbol->sattr & DEFINED) - return errors("multiply-defined label '%s'", label); + return error("multiply-defined label '%s'", label); // Put symbol in "order of definition" list if it's not already in it AddToSymbolDeclarationList(symbol); diff --git a/riscasm.c b/riscasm.c index 6238cf9..33c8cd3 100644 --- a/riscasm.c +++ b/riscasm.c @@ -127,38 +127,30 @@ void strtoupper(char * s) // static inline int MalformedOpcode(int signal) { - char buf[16]; - sprintf(buf, "%02X", signal); - return errors("Malformed opcode [internal $%s]", buf); + return error("Malformed opcode [internal $%02X]", signal); } + // // Function to return "Illegal Indexed Register" error // Anyone trying to index something other than R14 or R15 // static inline int IllegalIndexedRegister(int reg) { - char buf[16]; - sprintf(buf, "%d", reg - KW_R0); - return errors("Attempted index reference with non-indexable register (r%s)", buf); + return error("Attempted index reference with non-indexable register (r%d)", reg - KW_R0); } + // // Function to return "Illegal Indexed Register" error for EQUR scenarios // Trying to use register value within EQUR that isn't 14 or 15 // -static inline int IllegalIndexedRegisterEqur(SYM *sy) +static inline int IllegalIndexedRegisterEqur(SYM * sy) { - //char buf[160]; - char *buf = NULL; - buf = (char *)malloc((strlen(sy->sname) + 7) * sizeof(char)); - if (NULL != buf) { - sprintf(buf, "%s = r%d",sy->sname, sy->svalue); - return errors("Attempted index reference with non-indexable register within EQUR (%s)", buf); - } - return errors("Unable to allocate memory! (IllegalIndexRegisterEqur)", "OOPS"); + return error("Attempted index reference with non-indexable register within EQUR (%s = r%d)", sy->sname, sy->svalue); } + // // Build RISC instruction word // @@ -758,9 +750,7 @@ int GenerateRISCCode(int state) ccsym = lookup(string[tok[1]], LABEL, 0); if (ccsym && (ccsym->sattre & EQUATEDCC) && !(ccsym->sattre & UNDEF_CC)) - { val = ccsym->svalue; - } else return error("unknown condition code"); } @@ -805,7 +795,7 @@ int GenerateRISCCode(int state) reg2 = ((int)(eval - ((orgactive ? orgaddr : sloc) + 2))) / 2; if ((reg2 < -16) || (reg2 > 15)) - error("PC relative overflow"); + error("PC relative overflow (outside of -16 to 15)"); } BuildRISCIntructionWord(parm, reg2, reg1); diff --git a/rmac.h b/rmac.h index 40cb15c..31cbb85 100644 --- a/rmac.h +++ b/rmac.h @@ -163,38 +163,6 @@ #define ERROUT 2 // Error output #define CREATMASK 0 -// (Normally) non-printable tokens -#define COLON ':' // : (grumble: GNUmacs hates ':') -#define CONST 'a' // CONST -#define ACONST 'A' // ACONST -#define STRING 'b' // STRING
-#define STRINGA8 'S' // Atari 800 internal STRING
-#define SYMBOL 'c' // SYMBOL
-#define EOL 'e' // End of line -#define TKEOF 'f' // End of file (or macro) -#define DEQUALS 'g' // == -#define SET 149 // set -#define REG 'R' // reg -#define EQUREG 148 // equreg -#define CCDEF 183 // ccdef -#define DCOLON 'h' // :: -#define GE 'i' // >= -#define LE 'j' // <= -#define NE 'k' // <> or != -#define SHR 'l' // >> -#define SHL 'm' // << -#define UNMINUS 'n' // Unary '-' -#define DOTB 'B' // .b or .B or .s or .S -#define DOTW 'W' // .w or .W -#define DOTL 'L' // .l or .L -#define DOTI 'I' // .i or .I -#define DOTD 'D' // .d or .D -#define DOTS 'S' // .s or .S (FPU Single) -#define DOTQ 'Q' // .q oe .Q (FPU Quad) -#define DOTX 'X' // .x or .X (FPU Extended) -#define DOTP 'P' // .p or .P (FPU Packed) -#define ENDEXPR 'E' // End of expression - // Object code formats #define ALCYON 0 // Alcyon/DRI C object format #define MWC 1 // Mark Williams object format @@ -256,12 +224,13 @@ PTR #define EQUATEDCC 0x0020 #define UNDEF_CC 0x0040 -/* Construct binary constants at compile time -Code by Tom Torfs */ +// Construct binary constants at compile time +// Code by Tom Torfs -/* Helper macros */ +// Helper macros #define HEX__(n) 0x##n##LU -#define B8__(x) ((x&0x0000000FLU)?1:0) \ +#define B8__(x) \ + ((x&0x0000000FLU)?1:0) \ +((x&0x000000F0LU)?2:0) \ +((x&0x00000F00LU)?4:0) \ +((x&0x0000F000LU)?8:0) \ @@ -270,13 +239,12 @@ Code by Tom Torfs */ +((x&0x0F000000LU)?64:0) \ +((x&0xF0000000LU)?128:0) -/* User macros */ -#define B8(d) ((unsigned char)B8__(HEX__(d))) -#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \ -+ B8(dlsb)) -#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \ -+ ((unsigned long)B8(db2)<<16) \ -+ ((unsigned long)B8(db3)<<8) \ +// User macros +#define B8(d) ((uint8_t)B8__(HEX__(d))) +#define B16(dmsb,dlsb) (((uint16_t)B8(dmsb)<<8) + B8(dlsb)) +#define B32(dmsb,db2,db3,dlsb) (((uint32_t)B8(dmsb)<<24) \ ++ ((uint32_t)B8(db2)<<16) \ ++ ((uint32_t)B8(db3)<<8) \ + B8(dlsb)) // Optimisation defines diff --git a/token.c b/token.c index ac76526..6f42cca 100644 --- a/token.c +++ b/token.c @@ -55,7 +55,7 @@ static IMACRO * f_imacro; // Ptr list of free IMACROs static TOKEN tokbuf[TOKBUFSIZE]; // Token buffer (stack-like, all files) -char chrtab[] = { +uint8_t chrtab[0x100] = { ILLEG, ILLEG, ILLEG, ILLEG, // NUL SOH STX ETX ILLEG, ILLEG, ILLEG, ILLEG, // EOT ENQ ACK BEL ILLEG, WHITE, ILLEG, ILLEG, // BS HT LF VT @@ -79,29 +79,48 @@ char chrtab[] = { MULTX, MULTX, // : ; MULTX, MULTX, MULTX, STSYM+CTSYM, // < = > ? - MULTX, STSYM+CTSYM+HDIGIT, // @ A - (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // B C - (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // D E - STSYM+CTSYM+HDIGIT, STSYM+CTSYM, // F G - STSYM+CTSYM, (char)((BYTE)DOT)+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 - - (char)((BYTE)DOT)+STSYM+CTSYM, (char)((BYTE)DOT)+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, MULTX, STSYM+CTSYM, // \ ] ^ _ - - ILLEG, STSYM+CTSYM+HDIGIT, // ` a - (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // b c - (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // d e - STSYM+CTSYM+HDIGIT, STSYM+CTSYM, // f g - STSYM+CTSYM, (char)((BYTE)DOT)+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 - - (char)((BYTE)DOT)+STSYM+CTSYM, (char)((BYTE)DOT)+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 - (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z { - SELF, SELF, SELF, ILLEG // | } ~ DEL + MULTX, STSYM+CTSYM+HDIGIT, // @ A + DOT+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // B C + DOT+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // D E + STSYM+CTSYM+HDIGIT, STSYM+CTSYM, // F G + STSYM+CTSYM, DOT+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // H I J K + DOT+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // L M N O + + DOT+STSYM+CTSYM, DOT+STSYM+CTSYM, STSYM+CTSYM, DOT+STSYM+CTSYM, // P Q R S + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, DOT+STSYM+CTSYM, // T U V W + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF,// X Y Z [ + SELF, SELF, MULTX, STSYM+CTSYM, // \ ] ^ _ + + ILLEG, STSYM+CTSYM+HDIGIT, // ` a + DOT+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // b c + DOT+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // d e + STSYM+CTSYM+HDIGIT, STSYM+CTSYM, // f g + STSYM+CTSYM, DOT+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // h i j k + DOT+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // l m n o + + DOT+STSYM+CTSYM, DOT+STSYM+CTSYM, STSYM+CTSYM, DOT+STSYM+CTSYM, // p q r s + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, DOT+STSYM+CTSYM, // t u v w + DOT+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z { + SELF, SELF, SELF, ILLEG, // | } ~ DEL + + // Anything above $7F is illegal (and yes, we need to check for this, + // otherwise you get strange and spurious errors that will lead you astray) + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, + ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG, ILLEG }; // Names of registers @@ -276,7 +295,7 @@ INOBJ * a_inobj(int typ) break; case SRC_IREPT: // Alloc and init an IREPT inobj->inobj.irept = malloc(sizeof(IREPT)); - DEBUG printf("alloc IREPT\n"); + DEBUG { printf("alloc IREPT\n"); } break; } @@ -434,7 +453,7 @@ copy_d: *d++ = *s++; if (*s != '}') - return error("missing '}'"); + return error("missing closing brace ('}')"); else s++; } @@ -443,10 +462,10 @@ copy_d: // Lookup the argument and copy its (string) value into the // destination string - DEBUG printf("argument='%s'\n", mname); + DEBUG { printf("argument='%s'\n", mname); } if ((arg = lookup(mname, MACARG, macnum)) == NULL) - return errors("undefined argument: '%s'", mname); + return error("undefined argument: '%s'", mname); else { // Convert a string of tokens (terminated with EOL) back into @@ -454,7 +473,7 @@ 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 (argBase=%u)\n", i, imacro->argBase); } tk = NULL; if (i < imacro->im_nargs) @@ -519,7 +538,7 @@ arg_num: #else // This fix should be done for strings too d = symbolString[*tk++]; -DEBUG printf("ExM: SYMBOL=\"%s\"", d); +DEBUG { printf("ExM: SYMBOL=\"%s\"", d); } #endif break; case STRING: @@ -649,7 +668,7 @@ skipcomments: overflow: *dst = EOS; - DEBUG printf("*** OVERFLOW LINE ***\n%s\n", dest); + DEBUG { printf("*** OVERFLOW LINE ***\n%s\n", dest); } return fatal("line too long as a result of macro expansion"); } @@ -685,12 +704,12 @@ char * GetNextRepeatLine(void) // Do repeat at end of .rept block's string list if (strp == NULL) { - DEBUG printf("back-to-top-of-repeat-block count=%d\n", (int)irept->ir_count); + DEBUG { printf("back-to-top-of-repeat-block count=%d\n", (int)irept->ir_count); } irept->ir_nextln = irept->ir_firstln; // copy first line if (irept->ir_count-- == 0) { - DEBUG printf("end-repeat-block\n"); + DEBUG { printf("end-repeat-block\n"); } return NULL; } @@ -711,8 +730,7 @@ char * GetNextRepeatLine(void) int include(int handle, char * fname) { // Debug mode - if (debug) - printf("[include: %s, cfileno=%u]\n", fname, cfileno); + DEBUG { printf("[include: %s, cfileno=%u]\n", fname, cfileno); } // Alloc and initialize include-descriptors INOBJ * inobj = a_inobj(SRC_IFILE); @@ -740,7 +758,7 @@ int include(int handle, char * fname) last_fr->frec_next = fr; // Append to list of filerecs last_fr = fr; - DEBUG printf("[include: curfname: %s, cfileno=%u]\n", curfname, cfileno); + DEBUG { printf("[include: curfname: %s, cfileno=%u]\n", curfname, cfileno); } return OK; } @@ -772,7 +790,7 @@ int fpop(void) // Give a warning to the user that we had to wipe their bum for them if (numUnmatched > 0) - warni("missing %d .endif(s)", numUnmatched); + warn("missing %d .endif(s)", numUnmatched); tok = inobj->in_otok; // Restore tok and otok etok = inobj->in_etok; @@ -780,21 +798,20 @@ int fpop(void) switch (inobj->in_type) { case SRC_IFILE: // Pop and release an IFILE - if (debug) - printf("[Leaving: %s]\n", curfname); + 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 (debug) printf("[fpop (pre): curfname=%s]\n", curfname); +DEBUG { printf("[fpop (pre): curfname=%s]\n", curfname); } curfname = ifile->ifoldfname; // Set current filename -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); +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 -if (debug) printf("[fpop: (post) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno); +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; @@ -920,16 +937,16 @@ char * GetNextLine(void) // int TokenizeLine(void) { - char * ln = NULL; // Ptr to current position in line - char * p; // Random character ptr + uint8_t * ln = NULL; // Ptr to current position in line + uint8_t * 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 + uint8_t c; // Random char VALUE v; // Random value - char * nullspot = NULL; // Spot to clobber for SYMBOL termination + uint8_t * nullspot = NULL; // Spot to clobber for SYMBOL termination int stuffnull; // 1:terminate SYMBOL '\0' at *nullspot - char c1; + uint8_t c1; int stringNum = 0; // Pointer to string locations in tokenized line retry: @@ -949,7 +966,7 @@ retry: case SRC_IFILE: if ((ln = GetNextLine()) == NULL) { -if (debug) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); +DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } if (fpop() == 0) // Pop input level goto retry; // Try for more lines else @@ -1003,7 +1020,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); case SRC_IREPT: if ((ln = GetNextRepeatLine()) == NULL) { -if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); +DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); } fpop(); goto retry; } @@ -1030,15 +1047,15 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); goto goteol; // Main tokenization loop; - // o skip whitespace; - // o handle end-of-line; - // o handle symbols; - // o handle single-character tokens (operators, etc.); - // o handle multiple-character tokens (constants, strings, etc.). + // o skip whitespace; + // o handle end-of-line; + // o handle symbols; + // o handle single-character tokens (operators, etc.); + // o handle multiple-character tokens (constants, strings, etc.). for(; *ln!=EOS;) { // Skip whitespace, handle EOL - while ((int)chrtab[*ln] & WHITE) + while (chrtab[*ln] & WHITE) ln++; // Handle EOL, comment with ';' @@ -1101,7 +1118,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); v = (VALUE)dotxtab[*ln++]; if (chrtab[*ln] & CTSYM) - return error("misuse of '.', not allowed in symbols"); + return error("misuse of '.'; not allowed in symbols"); } // If the symbol is small, check to see if it's really the name of @@ -1192,7 +1209,6 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); // Handle multiple-character tokens if (c & MULTX) { - switch (*ln++) { case '!': // ! or != @@ -1542,7 +1558,7 @@ dostring: } // Handle illegal character - return error("illegal character"); + return error("illegal character $%02X found", *ln); } // Terminate line of tokens and return "success." diff --git a/token.h b/token.h index 58ffc0a..65b5b83 100644 --- a/token.h +++ b/token.h @@ -12,9 +12,9 @@ #include "rmac.h" // Include Files and Macros -#define SRC_IFILE 0 // Input source is IFILE -#define SRC_IMACRO 1 // Input source is IMACRO -#define SRC_IREPT 2 // Input source is IREPT +#define SRC_IFILE 0 // Input source is IFILE +#define SRC_IMACRO 1 // Input source is IMACRO +#define SRC_IREPT 2 // Input source is IREPT // Macros #define INOBJ struct _inobj @@ -25,59 +25,64 @@ #define IFENT struct _ifent // Tunable definitions -#define LNSIZ 1024 // Maximum size of a line of text -#define TOKBUFSIZE 400 // Size of token-line buffer -#define QUANTUM 4096L // # bytes to eat at a time from a file -#define LNBUFSIZ (QUANTUM*2) // Size of file's buffer -#define KWSIZE 7 // Maximum size of keyword in kwtab.h +#define LNSIZ 1024 // Maximum size of a line of text +#define TOKBUFSIZE 400 // Size of token-line buffer +#define QUANTUM 4096L // # bytes to eat at a time from a file +#define LNBUFSIZ (QUANTUM*2) // Size of file's buffer +#define KWSIZE 7 // Maximum size of keyword in kwtab.h // (Normally) non-printable tokens -#define COLON ':' // : (grumble: GNUmacs hates ':') -#define CONST 'a' // CONST -#define ACONST 'A' // ACONST -#define STRING 'b' // STRING
-#define SYMBOL 'c' // SYMBOL
-#define EOL 'e' // End of line -#define TKEOF 'f' // End of file (or macro) -#define DEQUALS 'g' // == -#define SET 149 // Set -#define REG 'R' // Reg -#define DCOLON 'h' // :: -#define GE 'i' // >= -#define LE 'j' // <= -#define NE 'k' // <> or != -#define SHR 'l' // >> -#define SHL 'm' // << -#define UNMINUS 'n' // Unary '-' -#define DOTB 'B' // .b or .B or .s or .S -#define DOTW 'W' // .w or .W -#define DOTL 'L' // .l or .L -#define DOTI 'I' // .l or .L -#define DOTX 'X' // .x or .X -#define DOTD 'D' // .d or .D -#define DOTP 'P' // .p or .P -#define DOTQ 'Q' // .q or .Q (essentially an alias for P) -#define ENDEXPR 'E' // End of expression +#define COLON ':' // : (grumble: GNUmacs hates ':') +#define CONST 'a' // CONST +#define ACONST 'A' // ACONST +#define STRING 'b' // STRING
+#define STRINGA8 'S' // Atari 800 internal STRING
+#define SYMBOL 'c' // SYMBOL
+#define EOL 'e' // End of line +#define TKEOF 'f' // End of file (or macro) +#define DEQUALS 'g' // == +#define SET 0x95 // Set +#define REG 'R' // Reg +#define EQUREG 0x94 // equreg +#define CCDEF 0xB7 // ccdef +#define DCOLON 'h' // :: +#define GE 'i' // >= +#define LE 'j' // <= +#define NE 'k' // <> or != +#define SHR 'l' // >> +#define SHL 'm' // << +#define UNMINUS 'n' // Unary '-' +#define DOTB 'B' // .b or .B or .s or .S +#define DOTW 'W' // .w or .W +#define DOTL 'L' // .l or .L +#define DOTI 'I' // .l or .L +#define DOTX 'X' // .x or .X +#define DOTD 'D' // .d or .D +#define DOTP 'P' // .p or .P +#define DOTQ 'Q' // .q or .Q (essentially an alias for P) +#define DOTS 'S' // .s or .S (FPU Single) +#define ENDEXPR 'E' // End of expression // ^^ operators -#define CR_DEFINED 'p' // ^^defined - is symbol defined? -#define CR_REFERENCED 'q' // ^^referenced - was symbol referenced? -#define CR_STREQ 'v' // ^^streq - compare two strings -#define CR_MACDEF 'w' // ^^macdef - is macro defined? -#define CR_TIME 'x' // ^^time - DOS format time -#define CR_DATE 'y' // ^^date - DOS format date -#define CR_ABSCOUNT 'z' // ^^abscount - count the number of bytes defined in curent .abs section +#define CR_DEFINED 'p' // ^^defined - is symbol defined? +#define CR_REFERENCED 'q' // ^^referenced - was symbol referenced? +#define CR_STREQ 'v' // ^^streq - compare two strings +#define CR_MACDEF 'w' // ^^macdef - is macro defined? +#define CR_TIME 'x' // ^^time - DOS format time +#define CR_DATE 'y' // ^^date - DOS format date +#define CR_ABSCOUNT 'z' // ^^abscount - count the number of bytes + // defined in curent .abs section // Character Attributes -#define ILLEG 0 // Illegal character (unused) -#define DIGIT 1 // 0-9 -#define HDIGIT 2 // A-F, a-f -#define STSYM 4 // A-Z, a-z, _~. -#define CTSYM 8 // A-Z, a-z, 0-9, _~$? -#define SELF 16 // Single-character tokens: ( ) [ ] etc -#define WHITE 32 // Whitespace (space, tab, etc.) -#define MULTX 64 // Multiple-character tokens -#define DOT 128 // [bwlsBWSL] for what follows a `.' +#define ILLEG 0 // Illegal character (unused) +#define DIGIT 1 // 0-9 +#define HDIGIT 2 // A-F, a-f +#define STSYM 4 // A-Z, a-z, _~. +#define CTSYM 8 // A-Z, a-z, 0-9, _~$? +#define SELF 16 // Single-character tokens: ( ) [ ] etc +#define WHITE 32 // Whitespace (space, tab, etc.) +#define MULTX 64 // Multiple-character tokens +#define DOT 128 // [bwlsBWSL] for what follows a '.' // Conditional assembly structures IFENT { diff --git a/version.h b/version.h index d24f303..dda6183 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define MAJOR 1 // Major version number #define MINOR 7 // Minor version number -#define PATCH 0 // Patch release number +#define PATCH 1 // Patch release number #endif // __VERSION_H__