//
#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
+#define DEF_KW // Declare keyword values
+#include "kwtab.h" // Incl generated keyword tables & defs
-static char tokcl[128]; // Generated table of token classes
-static VALUE evstk[EVSTACKSIZE]; // Evaluator value stack
-static WORD evattr[EVSTACKSIZE]; // Evaluator attribute stack
+static char tokcl[128]; // Generated table of token classes
+static VALUE evstk[EVSTACKSIZE]; // Evaluator value stack
+static WORD evattr[EVSTACKSIZE]; // Evaluator attribute stack
// Token-class initialization list
char itokcl[] = {
- 0, // END
- CONST, SYMBOL, 0, // ID
- '(', '[', '{', 0, // OPAR
- ')', ']', '}', 0, // CPAR
- CR_DEFINED, CR_REFERENCED, // SUNARY (special unary)
+ 0, // END
+ CONST, SYMBOL, 0, // ID
+ '(', '[', '{', 0, // OPAR
+ ')', ']', '}', 0, // CPAR
+ CR_DEFINED, CR_REFERENCED, // SUNARY (special unary)
CR_STREQ, CR_MACDEF,
CR_DATE, CR_TIME, 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)
+ '!', '~', 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)
};
-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[]
//
{
VALUE v;
- for(v=0; *p; ++p)
+ for(v=0; *p; p++)
v = (v << 8) | (*p & 0xFF);
return v;
//
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)
+ for(i=0, p=itokcl; *p!=1; p++)
{
if (*p == 0)
- ++i;
+ i++;
else
tokcl[(int)(*p)] = (char)i;
}
+
+ symbolNum = 0;
}
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;
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;
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++ != ',')
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));
*tk++ = *tok++;
break;
case SYMBOL:
+#if 0
p = (char *)*tok++;
+#else
+ p = string[*tok++];
+#endif
j = 0;
if (*p == '.')
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)
}
*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)
//
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)
}
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;
*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;
}
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)
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;
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:
// [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;
if ((*sattr & TDB) != (sattr[1] & TDB))
error(seg_error);
- *sattr = ABS|DEFINED;
+ *sattr = ABS | DEFINED;
*sval = *sval <= sval[1];
break;
case GE:
if ((*sattr & TDB) != (sattr[1] & TDB))
error(seg_error);
- *sattr = ABS|DEFINED;
+ *sattr = ABS | DEFINED;
*sval = *sval >= sval[1];
break;
case '>':
if ((*sattr & TDB) != (sattr[1] & TDB))
error(seg_error);
- *sattr = ABS|DEFINED;
+ *sattr = ABS | DEFINED;
*sval = *sval > sval[1];
break;
case '<':
if ((*sattr & TDB) != (sattr[1] & TDB))
error(seg_error);
- *sattr = ABS|DEFINED;
+ *sattr = ABS | DEFINED;
*sval = *sval < sval[1];
break;
case NE:
if ((*sattr & TDB) != (sattr[1] & TDB))
error(seg_error);
- *sattr = ABS|DEFINED;
+ *sattr = ABS | DEFINED;
*sval = *sval != sval[1];
break;
case '=':
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");
break;
case '%':
--sval;
- --sattr; // Pop attrib
+ --sattr; // Pop attrib
if (sval[1] == 0)
return error("mod (%) by zero");
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
}
}
}
// 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;