// EXPR.C - Expression Analyzer
// Copyright (C) 199x Landon Dyer, 2011 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 "expr.h"
// pcloc == location at start of line
*evalTokenBuffer++ = (orgactive ? orgaddr : pcloc);
- *evalTokenBuffer++ = ABS | DEFINED; // Store attribs
+ // '*' takes attributes of current section, not ABS!
+ *evalTokenBuffer++ = cursect | DEFINED;
break;
default:
return error("bad expression");
else
*evalTokenBuffer++ = *a_value = pcloc;
- *a_attr = ABS | DEFINED;
+ // '*' takes attributes of current section, not ABS!
+ *a_attr = cursect | DEFINED;
if (a_esym != NULL)
*a_esym = NULL;
j = (*p == '.' ? curenv : 0);
symbol = lookup(p, LABEL, j);
#if 0
-printf("eval: Looking up symbol [=%08X]\n", symbol);
+printf("eval: Looking up symbol (%s) [=%08X]\n", p, symbol);
if (symbol)
printf(" attr=%04X, attre=%08X, val=%i, name=%s\n", symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname);
#endif
symbol->sattr |= REFERENCED;
- // Check for undefined register equates
- if (symbol->sattre & UNDEF_EQUR)
+ // Check for undefined register equates, but only if it's not part
+ // of a #<SYMBOL> construct, as it could be that the label that's
+ // been undefined may later be used as an address label--which
+ // 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);
//if we return right away, it returns some spurious errors...
*a_attr = (WORD)(symbol->sattr & ~GLOBAL);
- if ((symbol->sattr & (GLOBAL | DEFINED)) == GLOBAL && a_esym != NULL)
+ if ((symbol->sattr & (GLOBAL | DEFINED)) == GLOBAL
+ && a_esym != NULL)
*a_esym = symbol;
tok += 2;
}
else
{
- // Unknown type here... Alert the user!
+ // Unknown type here... Alert the user!,
error("undefined RISC register in expression");
// Prevent spurious error reporting...
tok++;
}
*++sattr = (WORD)(sy->sattr & ~GLOBAL); // Push attribs
- sym_seg = (WORD)(sy->sattr & (TEXT | DATA | BSS));
+ sym_seg = (WORD)(sy->sattr & TDB);
break;
case CONST:
//printf("evexpr(): CONST = %i\n", *tk);
--sattr; // Pop attrib
*sval += sval[1]; // Compute value
- if (!(*sattr & (TEXT | DATA | BSS)))
+ if (!(*sattr & TDB))
*sattr = sattr[1];
- else if (sattr[1] & (TEXT | DATA | BSS))
+ else if (sattr[1] & TDB)
return error(seg_error);
break;
--sattr; // Pop attrib
*sval -= sval[1]; // Compute value
- attr = (WORD)(*sattr & (TEXT | DATA | BSS));
-
+ attr = (WORD)(*sattr & TDB);
+#if 0
+printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
+#endif
+ // If symbol1 is ABS, take attributes from symbol2
if (!attr)
*sattr = sattr[1];
- else if (sattr[1] & (TEXT | DATA | BSS))
- {
- if (!(attr & sattr[1]))
- return error(seg_error);
- else
- *sattr &= ~(TEXT | DATA | BSS);
- }
+ // Otherwise, they're both TDB and so attributes cancel out
+ else if (sattr[1] & TDB)
+ *sattr &= ~TDB;
break;
// Unary operators only work on ABS items
case UNMINUS:
//printf("evexpr(): UNMINUS\n");
- if (*sattr & (TEXT | DATA | BSS))
+ if (*sattr & TDB)
error(seg_error);
*sval = -(int)*sval;
break;
case '!':
//printf("evexpr(): !\n");
- if (*sattr & (TEXT | DATA | BSS))
+ if (*sattr & TDB)
error(seg_error);
*sval = !*sval;
break;
case '~':
//printf("evexpr(): ~\n");
- if (*sattr & (TEXT | DATA | BSS))
+ if (*sattr & TDB)
error(seg_error);
*sval = ~*sval;