X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=expr.c;h=e552c39e9becf0d853436565d7bc4d731f5730b1;hp=84018bd209f5c0ad5e5daa1b85e63bbb839bf282;hb=f6e6a55c4cdaf0dffa0897792dc5926c7b173a23;hpb=49cce96fba11282e4244187f15be418d5ae5bb8d diff --git a/expr.c b/expr.c index 84018bd..e552c39 100644 --- a/expr.c +++ b/expr.c @@ -7,14 +7,15 @@ // #include "expr.h" -#include "token.h" -#include "listing.h" +#include "direct.h" #include "error.h" +#include "listing.h" +#include "mach.h" #include "procln.h" -#include "symbol.h" +#include "riscasm.h" #include "sect.h" -#include "mach.h" -#include "risca.h" +#include "symbol.h" +#include "token.h" #define DEF_KW // Declare keyword values #include "kwtab.h" // Incl generated keyword tables & defs @@ -43,13 +44,13 @@ char itokcl[] = { 1 // (the end) }; -char missym_error[] = "missing symbol"; -char * str_error = "missing symbol or string"; +const char missym_error[] = "missing symbol"; +const char str_error[] = "missing symbol or string"; // Convert expression to postfix -static TOKEN * tk; // Deposit tokens here -SYM * lookup(); -SYM * newsym(); +static TOKEN * tk; // Deposit tokens here (this is really a + // pointer to exprbuf from direct.c) +static symbolNum; // Pointer to the entry in symbolPtr[] // @@ -59,7 +60,7 @@ static VALUE str_value(char * p) { VALUE v; - for(v=0; *p; ++p) + for(v=0; *p; p++) v = (v << 8) | (*p & 0xFF); return v; @@ -71,11 +72,11 @@ static VALUE str_value(char * p) // void init_expr(void) { - int i; // Iterator - char * p; // Token pointer + int i; // Iterator + char * p; // Token pointer // Initialize token-class table - for(i=0; i<128; ++i) // Mark all entries END + for(i=0; i<128; i++) // Mark all entries END tokcl[i] = END; for(i=0, p=itokcl; *p!=1; p++) @@ -85,6 +86,8 @@ void init_expr(void) else tokcl[(int)(*p)] = (char)i; } + + symbolNum = 0; } @@ -154,13 +157,12 @@ int expr1(void) if (*tok++ != SYMBOL) return error(missym_error); +#if 0 p = (char *)*tok++; - - if (lookup(p, MACRO, 0) == NULL) - w = 0; - else - w = 1; - +#else + p = string[*tok++]; +#endif + w = (lookup(p, MACRO, 0) == NULL ? 0 : 1); *tk++ = CONST; *tk++ = (TOKEN)w; break; @@ -173,17 +175,17 @@ getsym: if (*tok++ != SYMBOL) return error(missym_error); +#if 0 p = (char *)*tok++; +#else + p = string[*tok++]; +#endif j = 0; if (*p == '.') j = curenv; - if ((sy = lookup(p, LABEL, j)) != NULL && (sy->sattr & w)) - w = 1; - else - w = 0; - + w = ((sy = lookup(p, LABEL, j)) != NULL && (sy->sattr & w) ? 1 : 0); *tk++ = CONST; *tk++ = (TOKEN)w; break; @@ -191,7 +193,11 @@ getsym: if (*tok != SYMBOL && *tok != STRING) return error(str_error); +#if 0 p = (char *)tok[1]; +#else + p = string[tok[1]]; +#endif tok +=2; if (*tok++ != ',') @@ -200,7 +206,11 @@ getsym: if (*tok != SYMBOL && *tok != STRING) return error(str_error); +#if 0 p2 = (char *)tok[1]; +#else + p = string[tok[1]]; +#endif tok += 2; w = (WORD)(!strcmp(p, p2)); @@ -232,7 +242,11 @@ int expr2(void) *tk++ = *tok++; break; case SYMBOL: +#if 0 p = (char *)*tok++; +#else + p = string[*tok++]; +#endif j = 0; if (*p == '.') @@ -241,7 +255,7 @@ int expr2(void) sy = lookup(p, LABEL, j); if (sy == NULL) - sy = newsym(p, LABEL, j); + sy = NewSymbol(p, LABEL, j); // Check register bank usage if (sy->sattre & EQUATEDREG) @@ -254,11 +268,21 @@ int expr2(void) } *tk++ = SYMBOL; +#if 0 *tk++ = (TOKEN)sy; +#else + *tk++ = symbolNum; + symbolPtr[symbolNum] = sy; + symbolNum++; +#endif break; case STRING: *tk++ = CONST; +#if 0 *tk++ = str_value((char *)*tok++); +#else + *tk++ = str_value(string[*tok++]); +#endif break; case '(': if (expr0() != OK) @@ -304,11 +328,17 @@ int expr2(void) // int expr(TOKEN * otk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) { + // Passed in values (once derefenced, that is) can all be zero. They are + // there so that the expression analyzer can fill them in as needed. The + // expression analyzer gets its input from "tok", and not from anything + // passed in by the user. SYM * sy; char * p; int j; - tk = otk; + tk = otk; // Set token pointer to 'exprbuf' (direct.c) + // Also set in various other places too (riscasm.c, e.g.) +// symbolNum = 0; // Set symbol number in symbolPtr[] to 0 // Optimize for single constant or single symbol. if ((tok[1] == EOL) @@ -356,31 +386,50 @@ int expr(TOKEN * otk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) } else { - p = (char *)tok[1]; + p = string[tok[1]]; + +#if 0 j = 0; if (*p == '.') j = curenv; +#else + j = (*p == '.' ? curenv : 0); +#endif sy = lookup(p, LABEL, j); if (sy == NULL) - sy = newsym(p, LABEL, j); + sy = NewSymbol(p, LABEL, j); sy->sattr |= REFERENCED; + // Check for undefined register equates + if (sy->sattre & UNDEF_EQUR) + { + errors("undefined register equate '%s'", sy->sname); +//if we return right away, it returns some spurious errors... +// return ERROR; + } + // Check register bank usage 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); + warns("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); + warns("equated symbol '%s' cannot be used in register bank 1", sy->sname); } *tk++ = SYMBOL; +#if 0 *tk++ = (TOKEN)sy; +#else + *tk++ = symbolNum; + symbolPtr[symbolNum] = sy; + symbolNum++; +#endif if (sy->sattr & DEFINED) *a_value = sy->svalue; @@ -392,7 +441,7 @@ int expr(TOKEN * otk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) *a_attr = (WORD)(sy->sattr & ~GLOBAL); - if ((sy->sattr & (GLOBAL|DEFINED)) == GLOBAL && a_esym != NULL) + if ((sy->sattr & (GLOBAL | DEFINED)) == GLOBAL && a_esym != NULL) *a_esym = sy; } @@ -424,9 +473,9 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) SYM * esym; WORD sym_seg; - sval = evstk; // (Empty) initial stack + sval = evstk; // (Empty) initial stack sattr = evattr; - esym = NULL; // No external symbol involved + esym = NULL; // No external symbol involved sym_seg = 0; while (*tk != ENDEXPR) @@ -434,19 +483,21 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) switch ((int)*tk++) { case SYMBOL: - sy = (SYM *)*tk++; - sy->sattr |= REFERENCED; // Set "referenced" bit +// sy = (SYM *)*tk++; + sy = symbolPtr[*tk++]; + sy->sattr |= REFERENCED; // Set "referenced" bit if (!(sy->sattr & DEFINED)) { + // Reference to undefined symbol if (!(sy->sattr & GLOBAL)) - { // Reference to undefined symbol + { *a_attr = 0; *a_value = 0; return OK; } - if (esym != NULL) // Check for multiple externals + if (esym != NULL) // Check for multiple externals return error(seg_error); esym = sy; @@ -454,23 +505,23 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) if (sy->sattr & DEFINED) { - *++sval = sy->svalue; // Push symbol's value + *++sval = sy->svalue; // Push symbol's value } else { - *++sval = 0; // 0 for undefined symbols + *++sval = 0; // 0 for undefined symbols } - *++sattr = (WORD)(sy->sattr & ~GLOBAL); // Push attribs - sym_seg = (WORD)(sy->sattr & (TEXT|DATA|BSS)); + *++sattr = (WORD)(sy->sattr & ~GLOBAL); // Push attribs + sym_seg = (WORD)(sy->sattr & (TEXT | DATA | BSS)); break; case CONST: - *++sval = *tk++; // Push value - *++sattr = ABS|DEFINED; // Push simple attribs + *++sval = *tk++; // Push value + *++sattr = ABS | DEFINED; // Push simple attribs break; case ACONST: - *++sval = *tk++; // Push value - *++sattr = (WORD)*tk++; // Push attribs + *++sval = *tk++; // Push value + *++sattr = (WORD)*tk++; // Push attribs break; // Binary "+" and "-" matrix: @@ -485,58 +536,58 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) // [1] + : Error // - : ABS case '+': - --sval; // Pop value - --sattr; // Pop attrib - *sval += sval[1]; // Compute value + --sval; // Pop value + --sattr; // Pop attrib + *sval += sval[1]; // Compute value - if (!(*sattr & (TEXT|DATA|BSS))) + if (!(*sattr & (TEXT | DATA | BSS))) *sattr = sattr[1]; - else if (sattr[1] & (TEXT|DATA|BSS)) + else if (sattr[1] & (TEXT | DATA | BSS)) return error(seg_error); break; case '-': - --sval; // Pop value - --sattr; // Pop attrib - *sval -= sval[1]; // Compute value + --sval; // Pop value + --sattr; // Pop attrib + *sval -= sval[1]; // Compute value - attr = (WORD)(*sattr & (TEXT|DATA|BSS)); + attr = (WORD)(*sattr & (TEXT | DATA | BSS)); if (!attr) *sattr = sattr[1]; - else if (sattr[1] & (TEXT|DATA|BSS)) + else if (sattr[1] & (TEXT | DATA | BSS)) { if (!(attr & sattr[1])) return error(seg_error); else - *sattr &= ~(TEXT|DATA|BSS); + *sattr &= ~(TEXT | DATA | BSS); } break; - // Unary operators only work on ABS items + // Unary operators only work on ABS items case UNMINUS: - if (*sattr & (TEXT|DATA|BSS)) + if (*sattr & (TEXT | DATA | BSS)) error(seg_error); *sval = -(int)*sval; - *sattr = ABS|DEFINED; // Expr becomes absolute + *sattr = ABS | DEFINED; // Expr becomes absolute break; case '!': - if (*sattr & (TEXT|DATA|BSS)) + if (*sattr & (TEXT | DATA | BSS)) error(seg_error); *sval = !*sval; - *sattr = ABS|DEFINED; // Expr becomes absolute + *sattr = ABS | DEFINED; // Expr becomes absolute break; case '~': - if (*sattr & (TEXT|DATA|BSS)) + if (*sattr & (TEXT | DATA | BSS)) error(seg_error); *sval = ~*sval; - *sattr = ABS|DEFINED; // Expr becomes absolute + *sattr = ABS | DEFINED; // Expr becomes absolute break; - // Comparison operators must have two values that - // are in the same segment, but that's the only requirement. + // Comparison operators must have two values that + // are in the same segment, but that's the only requirement. case LE: --sattr; --sval; @@ -544,7 +595,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); - *sattr = ABS|DEFINED; + *sattr = ABS | DEFINED; *sval = *sval <= sval[1]; break; case GE: @@ -554,7 +605,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); - *sattr = ABS|DEFINED; + *sattr = ABS | DEFINED; *sval = *sval >= sval[1]; break; case '>': @@ -564,7 +615,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); - *sattr = ABS|DEFINED; + *sattr = ABS | DEFINED; *sval = *sval > sval[1]; break; case '<': @@ -574,7 +625,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); - *sattr = ABS|DEFINED; + *sattr = ABS | DEFINED; *sval = *sval < sval[1]; break; case NE: @@ -584,7 +635,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); - *sattr = ABS|DEFINED; + *sattr = ABS | DEFINED; *sval = *sval != sval[1]; break; case '=': @@ -594,27 +645,27 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) if ((*sattr & TDB) != (sattr[1] & TDB)) error(seg_error); - *sattr = ABS|DEFINED; + *sattr = ABS | DEFINED; *sval = *sval == sval[1]; break; - // All other binary operators must have two ABS items - // to work with. They all produce an ABS value. + // All other binary operators must have two ABS items + // to work with. They all produce an ABS value. default: // GH - Removed for v1.0.15 as part of the fix for indexed loads. //if ((*sattr & (TEXT|DATA|BSS)) || (*--sattr & (TEXT|DATA|BSS))) //error(seg_error); - *sattr = ABS|DEFINED; // Expr becomes absolute + *sattr = ABS | DEFINED; // Expr becomes absolute switch ((int)tk[-1]) { case '*': --sval; - --sattr; // Pop attrib + --sattr; // Pop attrib *sval *= sval[1]; break; case '/': --sval; - --sattr; // Pop attrib + --sattr; // Pop attrib if (sval[1] == 0) return error("divide by zero"); @@ -623,7 +674,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) break; case '%': --sval; - --sattr; // Pop attrib + --sattr; // Pop attrib if (sval[1] == 0) return error("mod (%) by zero"); @@ -632,31 +683,31 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) break; case SHL: --sval; - --sattr; // Pop attrib + --sattr; // Pop attrib *sval <<= sval[1]; break; case SHR: --sval; - --sattr; // Pop attrib + --sattr; // Pop attrib *sval >>= sval[1]; break; case '&': --sval; - --sattr; // Pop attrib + --sattr; // Pop attrib *sval &= sval[1]; break; case '^': --sval; - --sattr; // Pop attrib + --sattr; // Pop attrib *sval ^= sval[1]; break; case '|': --sval; - --sattr; // Pop attrib + --sattr; // Pop attrib *sval |= sval[1]; break; default: - interror(5); // Bad operator in expression stream + interror(5); // Bad operator in expression stream } } } @@ -672,7 +723,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) // overiding the symbol segments and not being included :( //*a_attr = *sattr | sym_seg; // Copy value + attrib - *a_attr = *sattr; // Copy value + attrib + *a_attr = *sattr; // Copy value + attrib *a_value = *sval; return OK;