X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=expr.c;h=44fd892bab2d0594170dd834741b411dc9498284;hp=063066ede1dd58ba9265ae1bba965d5789d4593e;hb=03dd34951a331e0b8971195ccef1600fffaea2e6;hpb=00b03aec5bf5c5b866d971a9c29e43acd276c87e diff --git a/expr.c b/expr.c index 063066e..44fd892 100644 --- a/expr.c +++ b/expr.c @@ -1,7 +1,7 @@ // -// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System +// RMAC - Reboot's Macro Assembler for all Atari computers // EXPR.C - Expression Analyzer -// Copyright (C) 199x Landon Dyer, 2011 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 // @@ -17,7 +17,7 @@ #include "symbol.h" #include "token.h" -#define DEF_KW // Declare keyword values +#define DEF_KW // Declare keyword values #include "kwtab.h" // Incl generated keyword tables & defs // N.B.: The size of tokenClass should be identical to the largest value of @@ -29,22 +29,22 @@ static WORD evattr[EVSTACKSIZE]; // Evaluator attribute stack // Token-class initialization list char itokcl[] = { 0, // END - CONST, SYMBOL, 0, // ID + CONST, SYMBOL, 0, // ID '(', '[', '{', 0, // OPAR - ')', ']', '}', 0, // CPAR + ')', ']', '}', 0, // CPAR CR_DEFINED, CR_REFERENCED, // SUNARY (special unary) CR_STREQ, CR_MACDEF, - CR_DATE, CR_TIME, + CR_DATE, CR_TIME, CR_ABSCOUNT, 0, '!', '~', UNMINUS, 0, // UNARY - '*', '/', '%', 0, // MULT - '+', '-', 0, // ADD - SHL, SHR, 0, // SHIFT - LE, GE, '<', '>', NE, '=', 0, // REL - '&', 0, // AND - '^', 0, // XOR - '|', 0, // OR - 1 // (the end) + '*', '/', '%', 0, // MULT + '+', '-', 0, // ADD + SHL, SHR, 0, // SHIFT + LE, GE, '<', '>', NE, '=', 0, // REL + '&', 0, // AND + '^', 0, // XOR + '|', 0, // OR + 1 // (the end) }; const char missym_error[] = "missing symbol"; @@ -55,7 +55,7 @@ static TOKEN * evalTokenBuffer; // Deposit tokens here (this is really a // pointer to exprbuf from direct.c) // (Can also be from others, like // riscasm.c) -static symbolNum; // Pointer to the entry in symbolPtr[] +static int symbolNum; // Pointer to the entry in symbolPtr[] // @@ -77,18 +77,17 @@ static VALUE str_value(char * p) // void InitExpression(void) { - int i; - char * p; - // Initialize token-class table (all set to END) - for(i=0; i<256; i++) + for(int i=0; i<256; i++) tokenClass[i] = END; - for(i=0, p=itokcl; *p!=1; p++) + int i = 0; + + for(char * p=itokcl; *p!=1; p++) { if (*p == 0) i++; - else + else tokenClass[(int)(*p)] = (char)i; } @@ -105,7 +104,7 @@ int expr0(void) if (expr1() != OK) return ERROR; - + while (tokenClass[*tok] >= MULT) { t = *tok++; @@ -211,7 +210,7 @@ getsym: break; } } - else + else return expr2(); return OK; @@ -244,7 +243,7 @@ int expr2(void) // Check register bank usage if (sy->sattre & EQUATEDREG) { - if ((regbank == BANK_0) && (sy->sattre & BANK_1) && !altbankok) + if ((regbank == BANK_0) && (sy->sattre & BANK_1) && !altbankok) warns("equated symbol \'%s\' cannot be used in register bank 0", sy->sname); if ((regbank == BANK_1) && (sy->sattre & BANK_0) && !altbankok) @@ -288,6 +287,20 @@ int expr2(void) *evalTokenBuffer++ = (orgactive ? orgaddr : pcloc); // '*' takes attributes of current section, not ABS! *evalTokenBuffer++ = cursect | DEFINED; + break; + case '{': + if (expr0() != OK) // Eat up first parameter (register or immediate) + return ERROR; + + if (*tok++ != ':') // Demand a ':' there + return error("missing colon ':'"); + + if (expr0() != OK) // Eat up second parameter (register or immediate) + return ERROR; + + if (*tok++ != '}') + return error("missing close bracket '}'"); + break; default: return error("bad expression"); @@ -395,7 +408,7 @@ if (symbol) // Check register bank usage if (symbol->sattre & EQUATEDREG) { - if ((regbank == BANK_0) && (symbol->sattre & BANK_1) && !altbankok) + if ((regbank == BANK_0) && (symbol->sattre & BANK_1) && !altbankok) warns("equated symbol '%s' cannot be used in register bank 0", symbol->sname); if ((regbank == BANK_1) && (symbol->sattre & BANK_0) && !altbankok) @@ -425,7 +438,7 @@ be converted from a linked list into an array). All that extra crap that was put into the svalue when doing the equr stuff is thrown away right here. What the hell is it for? */ - if (symbol->sattre & EQUATEDREG) + if (symbol->sattre & EQUATEDREG) *a_value &= 0x1F; *a_attr = (WORD)(symbol->sattr & ~GLOBAL); @@ -465,17 +478,12 @@ thrown away right here. What the hell is it for? // int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) { - WORD * sattr; - VALUE * sval; WORD attr; SYM * sy; - SYM * esym; - WORD sym_seg; - - sval = evstk; // (Empty) initial stack - sattr = evattr; - esym = NULL; // No external symbol involved - sym_seg = 0; + VALUE * sval = evstk; // (Empty) initial stack + WORD * sattr = evattr; + SYM * esym = NULL; // No external symbol involved + WORD sym_seg = 0; while (*tk != ENDEXPR) { @@ -484,7 +492,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) case SYMBOL: //printf("evexpr(): SYMBOL\n"); sy = symbolPtr[*tk++]; - sy->sattr |= REFERENCED; // Set "referenced" bit + sy->sattr |= REFERENCED; // Set "referenced" bit if (!(sy->sattr & DEFINED)) { @@ -508,7 +516,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) } else { - *++sval = 0; // 0 for undefined symbols + *++sval = 0; // 0 for undefined symbols } *++sattr = (WORD)(sy->sattr & ~GLOBAL); // Push attribs @@ -526,20 +534,20 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) break; // Binary "+" and "-" matrix: - // + // // ABS Sect Other // ---------------------------- // ABS | ABS | Sect | Other | // Sect | Sect | [1] | Error | // Other | Other | Error | [1] | // ---------------------------- - // + // // [1] + : Error // - : ABS case '+': //printf("evexpr(): +\n"); --sval; // Pop value - --sattr; // Pop attrib + --sattr; // Pop attrib //printf("--> N+N: %i + %i = ", *sval, sval[1]); *sval += sval[1]; // Compute value //printf("%i\n", *sval); @@ -553,7 +561,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) case '-': //printf("evexpr(): -\n"); --sval; // Pop value - --sattr; // Pop attrib + --sattr; // Pop attrib //printf("--> N-N: %i - %i = ", *sval, sval[1]); *sval -= sval[1]; // Compute value //printf("%i\n", *sval); @@ -599,8 +607,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); // are in the same segment, but that's the only requirement. case LE: //printf("evexpr(): LE\n"); - --sattr; - --sval; + sattr--; + sval--; if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); @@ -610,8 +618,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); break; case GE: //printf("evexpr(): GE\n"); - --sattr; - --sval; + sattr--; + sval--; if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); @@ -621,8 +629,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); break; case '>': //printf("evexpr(): >\n"); - --sattr; - --sval; + sattr--; + sval--; if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); @@ -632,8 +640,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); break; case '<': //printf("evexpr(): <\n"); - --sattr; - --sval; + sattr--; + sval--; if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); @@ -643,8 +651,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); break; case NE: //printf("evexpr(): NE\n"); - --sattr; - --sval; + sattr--; + sval--; if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); @@ -654,8 +662,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); break; case '=': //printf("evexpr(): =\n"); - --sattr; - --sval; + sattr--; + sval--; if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); @@ -675,15 +683,15 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); switch ((int)tk[-1]) { case '*': - --sval; - --sattr; // Pop attrib + sval--; + sattr--; // Pop attrib //printf("--> NxN: %i x %i = ", *sval, sval[1]); *sval *= sval[1]; //printf("%i\n", *sval); break; case '/': - --sval; - --sattr; // Pop attrib + sval--; + sattr--; // Pop attrib if (sval[1] == 0) return error("divide by zero"); @@ -697,8 +705,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); //printf("%i\n", *sval); break; case '%': - --sval; - --sattr; // Pop attrib + sval--; + sattr--; // Pop attrib if (sval[1] == 0) return error("mod (%) by zero"); @@ -706,28 +714,28 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); *sval %= sval[1]; break; case SHL: - --sval; - --sattr; // Pop attrib + sval--; + sattr--; // Pop attrib *sval <<= sval[1]; break; case SHR: - --sval; - --sattr; // Pop attrib + sval--; + sattr--; // Pop attrib *sval >>= sval[1]; break; case '&': - --sval; - --sattr; // Pop attrib + sval--; + sattr--; // Pop attrib *sval &= sval[1]; break; case '^': - --sval; - --sattr; // Pop attrib + sval--; + sattr--; // Pop attrib *sval ^= sval[1]; break; case '|': - --sval; - --sattr; // Pop attrib + sval--; + sattr--; // Pop attrib *sval |= sval[1]; break; default: @@ -745,7 +753,7 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]); // sym_seg added in 1.0.16 to solve a problem with forward symbols in // expressions where absolute values also existed. The absolutes were // overiding the symbol segments and not being included :( - //*a_attr = *sattr | sym_seg; // Copy value + attrib + //*a_attr = *sattr | sym_seg; // Copy value + attrib *a_attr = *sattr; // Copy value + attrib *a_value = *sval;