}
*evalTokenBuffer++ = SYMBOL;
-#if 0
- *evalTokenBuffer++ = (TOKEN)sy;
-#else
*evalTokenBuffer++ = symbolNum;
symbolPtr[symbolNum] = sy;
symbolNum++;
-#endif
break;
case STRING:
*evalTokenBuffer++ = CONST;
case '*':
*evalTokenBuffer++ = ACONST; // Attributed const
+#if 0
if (orgactive)
*evalTokenBuffer++ = orgaddr;
else
*evalTokenBuffer++ = pcloc; // Location at start of line
+#else
+ // pcloc == location at start of line
+ *evalTokenBuffer++ = (orgactive ? orgaddr : pcloc);
+#endif
*evalTokenBuffer++ = ABS | DEFINED; // Store attribs
break;
evalTokenBuffer = otk; // Set token pointer to 'exprbuf' (direct.c)
// Also set in various other places too (riscasm.c, e.g.)
+//printf("expr(): tokens 0-2: %i %i %i (%c %c %c); tc[2] = %i\n", tok[0], tok[1], tok[2], tok[0], tok[1], tok[2], tokenClass[tok[2]]);
// Optimize for single constant or single symbol.
- if ((tok[1] == EOL)
+ // Shamus: Subtle bug here. EOL token is 101; if you have a constant token
+ // followed by the value 101, it will trigger a bad evaluation here.
+ // This is probably a really bad assumption to be making here...!
+ // (assuming tok[1] == EOL is a single token that is)
+// if ((tok[1] == EOL)
+ if ((tok[1] == EOL && tok[0] != CONST)
|| (((*tok == CONST || *tok == SYMBOL) || (*tok >= KW_R0 && *tok <= KW_R31))
&& (tokenClass[tok[2]] < UNARY)))
{
*a_esym = NULL;
tok++;
-// *evalTokenBuffer++ = ENDEXPR;
-// return OK;
}
else if (*tok == CONST)
{
*a_esym = NULL;
tok += 2;
+//printf("Quick eval in expr(): CONST = %i, tokenClass[tok[2]] = %i\n", *a_value, tokenClass[*tok]);
}
else if (*tok == '*')
{
if (a_esym != NULL)
*a_esym = NULL;
-// tok--;
tok++;
}
else if (*tok == STRING || *tok == SYMBOL)
return ERROR;
}
-// tok += 2;
*evalTokenBuffer++ = ENDEXPR;
return OK;
}
switch ((int)*tk++)
{
case SYMBOL:
-// sy = (SYM *)*tk++;
+//printf("evexpr(): SYMBOL\n");
sy = symbolPtr[*tk++];
sy->sattr |= REFERENCED; // Set "referenced" bit
sym_seg = (WORD)(sy->sattr & (TEXT | DATA | BSS));
break;
case CONST:
+//printf("evexpr(): CONST = %i\n", *tk);
*++sval = *tk++; // Push value
*++sattr = ABS | DEFINED; // Push simple attribs
break;
case ACONST:
+//printf("evexpr(): ACONST = %i\n", *tk);
*++sval = *tk++; // Push value
*++sattr = (WORD)*tk++; // Push attribs
break;
// [1] + : Error
// - : ABS
case '+':
+//printf("evexpr(): +\n");
--sval; // Pop value
--sattr; // Pop attrib
*sval += sval[1]; // Compute value
break;
case '-':
+//printf("evexpr(): -\n");
--sval; // Pop value
--sattr; // Pop attrib
*sval -= sval[1]; // Compute value
break;
// Unary operators only work on ABS items
case UNMINUS:
+//printf("evexpr(): UNMINUS\n");
if (*sattr & (TEXT | DATA | BSS))
error(seg_error);
*sattr = ABS | DEFINED; // Expr becomes absolute
break;
case '!':
+//printf("evexpr(): !\n");
if (*sattr & (TEXT | DATA | BSS))
error(seg_error);
*sattr = ABS | DEFINED; // Expr becomes absolute
break;
case '~':
+//printf("evexpr(): ~\n");
if (*sattr & (TEXT | DATA | BSS))
error(seg_error);
// Comparison operators must have two values that
// are in the same segment, but that's the only requirement.
case LE:
+//printf("evexpr(): LE\n");
--sattr;
--sval;
*sval = *sval <= sval[1];
break;
case GE:
+//printf("evexpr(): GE\n");
--sattr;
--sval;
*sval = *sval >= sval[1];
break;
case '>':
+//printf("evexpr(): >\n");
--sattr;
--sval;
*sval = *sval > sval[1];
break;
case '<':
+//printf("evexpr(): <\n");
--sattr;
--sval;
*sval = *sval < sval[1];
break;
case NE:
+//printf("evexpr(): NE\n");
--sattr;
--sval;
*sval = *sval != sval[1];
break;
case '=':
+//printf("evexpr(): =\n");
--sattr;
--sval;
// All other binary operators must have two ABS items
// to work with. They all produce an ABS value.
default:
+//printf("evexpr(): default\n");
// 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);