home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / assembler / as / src / c / eval < prev    next >
Encoding:
Text File  |  1993-02-10  |  5.7 KB  |  184 lines

  1.  
  2. /*
  3.  * eval.c
  4.  * Copyright © 1992 Niklas Röjemo
  5.  */
  6.  
  7. #include "global.h"
  8. #include "eval.h"
  9. #include "help_eval.h"
  10. #include "error.h"
  11.  
  12.  
  13. #define COMPARE(OP) \
  14.       if(lvalue->Tag == ValueFloat && lvalue->Tag == ValueFloat) { \
  15.         lvalue->ValueBool.b = lvalue->ValueFloat.f OP rvalue->ValueFloat.f; \
  16.         lvalue->Tag = ValueBool; \
  17.         return TRUE; \
  18.       }   \
  19.       if(!(lvalue->Tag & (ValueInt | ValueLateLabel)) || \
  20.          !(rvalue->Tag & (ValueInt | ValueLateLabel))) \
  21.         return FALSE; \
  22.  \
  23.       help_evalSubLate(lvalue,rvalue); \
  24.  /* Might not be a ValueInt, but ValueLate* have i at the same place */ \
  25.       if(lvalue->Tag != ValueInt) \
  26.         return FALSE; \
  27.  \
  28.       lvalue->ValueBool.b = lvalue->ValueInt.i OP rvalue->ValueInt.i; \
  29.       lvalue->Tag = ValueBool; \
  30.       return TRUE  /* Last ; is where macro is used */
  31.  
  32.  
  33. BOOL evalBinop(Operator op, Value *lvalue, Value *rvalue)
  34. {
  35.   switch(op) {
  36.     case Op_mul:
  37.       if(lvalue->Tag != rvalue->Tag)
  38.         return FALSE;
  39.       switch(lvalue->Tag) {
  40.         case ValueInt:
  41.           lvalue->ValueInt.i *= rvalue->ValueInt.i;
  42.           return TRUE;
  43.         case ValueFloat:
  44.           lvalue->ValueFloat.f *= rvalue->ValueFloat.f;
  45.           return TRUE;
  46.        }
  47.        return FALSE;
  48.     case Op_div:
  49.       if(lvalue->Tag != rvalue->Tag)
  50.         return FALSE;
  51.       switch(lvalue->Tag) {
  52.         case ValueInt:
  53.           lvalue->ValueInt.i /= rvalue->ValueInt.i;
  54.           return TRUE;
  55.         case ValueFloat:
  56.           lvalue->ValueFloat.f /= rvalue->ValueFloat.f;
  57.           return TRUE;
  58.        }
  59.        return FALSE;
  60.     case Op_mod:
  61.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  62.         return FALSE;
  63.       lvalue->ValueInt.i %= rvalue->ValueInt.i;
  64.       return TRUE;
  65.     case Op_add:
  66.       if(lvalue->Tag == ValueFloat && lvalue->Tag == ValueFloat) {
  67.         lvalue->ValueFloat.f += rvalue->ValueFloat.f;
  68.         return TRUE;
  69.       }  
  70.       if(!(lvalue->Tag & (ValueInt | ValueLateLabel)) ||
  71.          !(rvalue->Tag & (ValueInt | ValueLateLabel)))
  72.         return FALSE;
  73.  
  74.       help_evalAddLate(lvalue,rvalue);
  75.  /* Might not be a ValueInt, but ValueLate* have i at the same place */
  76.       lvalue->ValueInt.i += rvalue->ValueInt.i;
  77.       return TRUE;
  78.     case Op_sub:
  79.       if(lvalue->Tag == ValueFloat && lvalue->Tag == ValueFloat) {
  80.         lvalue->ValueFloat.f -= rvalue->ValueFloat.f;
  81.         return TRUE;
  82.       }  
  83.       if(!(lvalue->Tag & (ValueInt | ValueLateLabel)) ||
  84.          !(rvalue->Tag & (ValueInt | ValueLateLabel)))
  85.         return FALSE;
  86.  
  87.       help_evalSubLate(lvalue,rvalue);
  88.  /* Might not be a ValueInt, but ValueLate* have i at the same place */
  89.       lvalue->ValueInt.i -= rvalue->ValueInt.i;
  90.       return TRUE;
  91.     case Op_and:
  92.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  93.         return FALSE;
  94.       lvalue->ValueInt.i &= rvalue->ValueInt.i;
  95.       return TRUE;
  96.     case Op_or:
  97.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  98.         return FALSE;
  99.       lvalue->ValueInt.i |= rvalue->ValueInt.i;
  100.       return TRUE;
  101.     case Op_xor:
  102.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  103.         return FALSE;
  104.       lvalue->ValueInt.i ^= rvalue->ValueInt.i;
  105.       return TRUE;
  106.     case Op_asr:
  107.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  108.         return FALSE;
  109.       lvalue->ValueInt.i = ((signed int)lvalue->ValueInt.i) >> rvalue->ValueInt.i;
  110.       return TRUE;
  111.     case Op_sr:
  112.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  113.         return FALSE;
  114.       lvalue->ValueInt.i = ((unsigned int)lvalue->ValueInt.i) >> rvalue->ValueInt.i;
  115.       return TRUE;
  116.     case Op_sl:
  117.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  118.         return FALSE;
  119.       lvalue->ValueInt.i <<= rvalue->ValueInt.i;
  120.       return TRUE;
  121.     case Op_ror:
  122.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  123.         return FALSE;
  124.       lvalue->ValueInt.i = (((unsigned int)lvalue->ValueInt.i) >> rvalue->ValueInt.i) |
  125.                            ((lvalue->ValueInt.i) << (32-rvalue->ValueInt.i));
  126.     case Op_rol:
  127.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  128.         return FALSE;
  129.       lvalue->ValueInt.i = ((lvalue->ValueInt.i) << rvalue->ValueInt.i) |
  130.                            (((unsigned int)lvalue->ValueInt.i) >> (32-rvalue->ValueInt.i));
  131.       return TRUE;
  132.     case Op_le: COMPARE(<=);
  133.     case Op_ge: COMPARE(>=);
  134.     case Op_lt: COMPARE(<);
  135.     case Op_gt: COMPARE(>);
  136.     case Op_eq: COMPARE(==);
  137.     case Op_ne: COMPARE(!=);
  138.     case Op_land:
  139.       if(lvalue->Tag != ValueBool || rvalue->Tag != ValueBool)
  140.         return FALSE;
  141.       lvalue->ValueBool.b = lvalue->ValueBool.b && rvalue->ValueBool.b;
  142.       return TRUE;
  143.     case Op_lor:
  144.       if(lvalue->Tag != ValueBool || rvalue->Tag != ValueBool)
  145.         return FALSE;
  146.       lvalue->ValueBool.b = lvalue->ValueBool.b || rvalue->ValueBool.b;
  147.       return TRUE;
  148.     default:
  149.       error(ErrorError,TRUE,"Illegal binary operator.");
  150.     }
  151.   error(ErrorError,TRUE,"Illegal fall through in evalBinop.");
  152.   return FALSE;
  153. }
  154.  
  155. BOOL evalUnop(Operator op, Value *value)
  156. {
  157.   switch(op) {
  158.     case Op_lnot:
  159.       if(value->Tag != ValueBool)
  160.         return FALSE;
  161.       value->ValueBool.b = !value->ValueBool.b;
  162.       return TRUE;
  163.     case Op_not:
  164.       if(value->Tag != ValueInt)
  165.         return FALSE;
  166.       value->ValueInt.i = ~value->ValueInt.i;
  167.       return TRUE;
  168.     case Op_neg:
  169.       if(value->Tag == ValueFloat)
  170.         value->ValueFloat.f = -value->ValueFloat.f;
  171.       else {        
  172.         if(!(value->Tag & (ValueInt | ValueLateLabel)))
  173.           return FALSE;
  174.         help_evalNegLate(value);
  175.         value->ValueInt.i = -value->ValueInt.i;
  176.       }
  177.       return TRUE;
  178.     default:
  179.       error(ErrorError,TRUE,"Illegal unary operator.");
  180.   }
  181.   error(ErrorSerious,FALSE,"Illegal fall through in evalUnop.");
  182.   return FALSE;
  183. }
  184.