home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * eval.c
- * Copyright © 1992 Niklas Röjemo
- */
-
- #include "global.h"
- #include "eval.h"
- #include "help_eval.h"
- #include "error.h"
-
-
- #define COMPARE(OP) \
- if(lvalue->Tag == ValueFloat && lvalue->Tag == ValueFloat) { \
- lvalue->ValueBool.b = lvalue->ValueFloat.f OP rvalue->ValueFloat.f; \
- lvalue->Tag = ValueBool; \
- return TRUE; \
- } \
- if(!(lvalue->Tag & (ValueInt | ValueLateLabel)) || \
- !(rvalue->Tag & (ValueInt | ValueLateLabel))) \
- return FALSE; \
- \
- help_evalSubLate(lvalue,rvalue); \
- /* Might not be a ValueInt, but ValueLate* have i at the same place */ \
- if(lvalue->Tag != ValueInt) \
- return FALSE; \
- \
- lvalue->ValueBool.b = lvalue->ValueInt.i OP rvalue->ValueInt.i; \
- lvalue->Tag = ValueBool; \
- return TRUE /* Last ; is where macro is used */
-
-
- BOOL evalBinop(Operator op, Value *lvalue, Value *rvalue)
- {
- switch(op) {
- case Op_mul:
- if(lvalue->Tag != rvalue->Tag)
- return FALSE;
- switch(lvalue->Tag) {
- case ValueInt:
- lvalue->ValueInt.i *= rvalue->ValueInt.i;
- return TRUE;
- case ValueFloat:
- lvalue->ValueFloat.f *= rvalue->ValueFloat.f;
- return TRUE;
- }
- return FALSE;
- case Op_div:
- if(lvalue->Tag != rvalue->Tag)
- return FALSE;
- switch(lvalue->Tag) {
- case ValueInt:
- lvalue->ValueInt.i /= rvalue->ValueInt.i;
- return TRUE;
- case ValueFloat:
- lvalue->ValueFloat.f /= rvalue->ValueFloat.f;
- return TRUE;
- }
- return FALSE;
- case Op_mod:
- if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
- return FALSE;
- lvalue->ValueInt.i %= rvalue->ValueInt.i;
- return TRUE;
- case Op_add:
- if(lvalue->Tag == ValueFloat && lvalue->Tag == ValueFloat) {
- lvalue->ValueFloat.f += rvalue->ValueFloat.f;
- return TRUE;
- }
- if(!(lvalue->Tag & (ValueInt | ValueLateLabel)) ||
- !(rvalue->Tag & (ValueInt | ValueLateLabel)))
- return FALSE;
-
- help_evalAddLate(lvalue,rvalue);
- /* Might not be a ValueInt, but ValueLate* have i at the same place */
- lvalue->ValueInt.i += rvalue->ValueInt.i;
- return TRUE;
- case Op_sub:
- if(lvalue->Tag == ValueFloat && lvalue->Tag == ValueFloat) {
- lvalue->ValueFloat.f -= rvalue->ValueFloat.f;
- return TRUE;
- }
- if(!(lvalue->Tag & (ValueInt | ValueLateLabel)) ||
- !(rvalue->Tag & (ValueInt | ValueLateLabel)))
- return FALSE;
-
- help_evalSubLate(lvalue,rvalue);
- /* Might not be a ValueInt, but ValueLate* have i at the same place */
- lvalue->ValueInt.i -= rvalue->ValueInt.i;
- return TRUE;
- case Op_and:
- if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
- return FALSE;
- lvalue->ValueInt.i &= rvalue->ValueInt.i;
- return TRUE;
- case Op_or:
- if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
- return FALSE;
- lvalue->ValueInt.i |= rvalue->ValueInt.i;
- return TRUE;
- case Op_xor:
- if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
- return FALSE;
- lvalue->ValueInt.i ^= rvalue->ValueInt.i;
- return TRUE;
- case Op_asr:
- if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
- return FALSE;
- lvalue->ValueInt.i = ((signed int)lvalue->ValueInt.i) >> rvalue->ValueInt.i;
- return TRUE;
- case Op_sr:
- if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
- return FALSE;
- lvalue->ValueInt.i = ((unsigned int)lvalue->ValueInt.i) >> rvalue->ValueInt.i;
- return TRUE;
- case Op_sl:
- if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
- return FALSE;
- lvalue->ValueInt.i <<= rvalue->ValueInt.i;
- return TRUE;
- case Op_ror:
- if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
- return FALSE;
- lvalue->ValueInt.i = (((unsigned int)lvalue->ValueInt.i) >> rvalue->ValueInt.i) |
- ((lvalue->ValueInt.i) << (32-rvalue->ValueInt.i));
- case Op_rol:
- if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
- return FALSE;
- lvalue->ValueInt.i = ((lvalue->ValueInt.i) << rvalue->ValueInt.i) |
- (((unsigned int)lvalue->ValueInt.i) >> (32-rvalue->ValueInt.i));
- return TRUE;
- case Op_le: COMPARE(<=);
- case Op_ge: COMPARE(>=);
- case Op_lt: COMPARE(<);
- case Op_gt: COMPARE(>);
- case Op_eq: COMPARE(==);
- case Op_ne: COMPARE(!=);
- case Op_land:
- if(lvalue->Tag != ValueBool || rvalue->Tag != ValueBool)
- return FALSE;
- lvalue->ValueBool.b = lvalue->ValueBool.b && rvalue->ValueBool.b;
- return TRUE;
- case Op_lor:
- if(lvalue->Tag != ValueBool || rvalue->Tag != ValueBool)
- return FALSE;
- lvalue->ValueBool.b = lvalue->ValueBool.b || rvalue->ValueBool.b;
- return TRUE;
- default:
- error(ErrorError,TRUE,"Illegal binary operator.");
- }
- error(ErrorError,TRUE,"Illegal fall through in evalBinop.");
- return FALSE;
- }
-
- BOOL evalUnop(Operator op, Value *value)
- {
- switch(op) {
- case Op_lnot:
- if(value->Tag != ValueBool)
- return FALSE;
- value->ValueBool.b = !value->ValueBool.b;
- return TRUE;
- case Op_not:
- if(value->Tag != ValueInt)
- return FALSE;
- value->ValueInt.i = ~value->ValueInt.i;
- return TRUE;
- case Op_neg:
- if(value->Tag == ValueFloat)
- value->ValueFloat.f = -value->ValueFloat.f;
- else {
- if(!(value->Tag & (ValueInt | ValueLateLabel)))
- return FALSE;
- help_evalNegLate(value);
- value->ValueInt.i = -value->ValueInt.i;
- }
- return TRUE;
- default:
- error(ErrorError,TRUE,"Illegal unary operator.");
- }
- error(ErrorSerious,FALSE,"Illegal fall through in evalUnop.");
- return FALSE;
- }
-