home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / language / as / source / c / eval < prev    next >
Encoding:
Text File  |  1994-05-23  |  7.0 KB  |  225 lines

  1.  
  2. /*
  3.  * eval.c
  4.  * Copyright © 1992 Niklas Röjemo
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include "global.h"
  9. #include "eval.h"
  10. #include "help_eval.h"
  11. #include "error.h"
  12. #include "include.h"
  13.  
  14. #ifndef SEEK_END
  15. #define SEEK_END 2
  16. #endif
  17.  
  18. #define COMPARE(OP) \
  19.       if(lvalue->Tag == ValueFloat && rvalue->Tag == ValueFloat) { \
  20.         lvalue->ValueBool.b = lvalue->ValueFloat.f OP rvalue->ValueFloat.f; \
  21.         lvalue->Tag = ValueBool; \
  22.         return TRUE; \
  23.       }   \
  24.       if(!(lvalue->Tag & (ValueInt | ValueLateLabel)) || \
  25.          !(rvalue->Tag & (ValueInt | ValueLateLabel))) \
  26.         return FALSE; \
  27.  \
  28.       help_evalSubLate(lvalue,rvalue); \
  29.  /* Might not be a ValueInt, but ValueLate* have i at the same place */ \
  30.       if(lvalue->Tag != ValueInt) \
  31.         return FALSE; \
  32.  \
  33.       lvalue->ValueBool.b = lvalue->ValueInt.i OP rvalue->ValueInt.i; \
  34.       lvalue->Tag = ValueBool; \
  35.       return TRUE  /* Last ; is where macro is used */
  36.  
  37.  
  38. BOOL evalBinop(Operator op, Value *lvalue, Value *rvalue)
  39. {
  40.   switch(op) {
  41.     case Op_mul:
  42.       if(lvalue->Tag != rvalue->Tag)
  43.         return FALSE;
  44.       switch(lvalue->Tag) {
  45.         case ValueInt:
  46.           lvalue->ValueInt.i *= rvalue->ValueInt.i;
  47.           return TRUE;
  48.         case ValueFloat:
  49.           lvalue->ValueFloat.f *= rvalue->ValueFloat.f;
  50.           return TRUE;
  51.        }
  52.        return FALSE;
  53.     case Op_div:
  54.       if(lvalue->Tag != rvalue->Tag)
  55.         return FALSE;
  56.       switch(lvalue->Tag) {
  57.         case ValueInt:
  58.           lvalue->ValueInt.i /= rvalue->ValueInt.i;
  59.           return TRUE;
  60.         case ValueFloat:
  61.           lvalue->ValueFloat.f /= rvalue->ValueFloat.f;
  62.           return TRUE;
  63.        }
  64.        return FALSE;
  65.     case Op_mod:
  66.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  67.         return FALSE;
  68.       lvalue->ValueInt.i %= rvalue->ValueInt.i;
  69.       return TRUE;
  70.     case Op_add:
  71.       if(lvalue->Tag == ValueFloat && rvalue->Tag == ValueFloat) {
  72.         lvalue->ValueFloat.f += rvalue->ValueFloat.f;
  73.         return TRUE;
  74.       }  
  75.       if(!(lvalue->Tag & (ValueInt | ValueLateLabel)) ||
  76.          !(rvalue->Tag & (ValueInt | ValueLateLabel)))
  77.         return FALSE;
  78.  
  79.       help_evalAddLate(lvalue,rvalue);
  80.  /* Might not be a ValueInt, but ValueLate* have i at the same place */
  81.       lvalue->ValueInt.i += rvalue->ValueInt.i;
  82.       return TRUE;
  83.     case Op_sub:
  84.       if(lvalue->Tag == ValueFloat && rvalue->Tag == ValueFloat) {
  85.         lvalue->ValueFloat.f -= rvalue->ValueFloat.f;
  86.         return TRUE;
  87.       }  
  88.       if(!(lvalue->Tag & (ValueInt | ValueLateLabel)) ||
  89.          !(rvalue->Tag & (ValueInt | ValueLateLabel)))
  90.         return FALSE;
  91.  
  92.       help_evalSubLate(lvalue,rvalue);
  93.  /* Might not be a ValueInt, but ValueLate* have i at the same place */
  94.       lvalue->ValueInt.i -= rvalue->ValueInt.i;
  95.       return TRUE;
  96.     case Op_and:
  97.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  98.         return FALSE;
  99.       lvalue->ValueInt.i &= rvalue->ValueInt.i;
  100.       return TRUE;
  101.     case Op_or:
  102.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  103.         return FALSE;
  104.       lvalue->ValueInt.i |= rvalue->ValueInt.i;
  105.       return TRUE;
  106.     case Op_xor:
  107.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  108.         return FALSE;
  109.       lvalue->ValueInt.i ^= rvalue->ValueInt.i;
  110.       return TRUE;
  111.     case Op_asr:
  112.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  113.         return FALSE;
  114.       lvalue->ValueInt.i = ((signed int)lvalue->ValueInt.i) >> rvalue->ValueInt.i;
  115.       return TRUE;
  116.     case Op_sr:
  117.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  118.         return FALSE;
  119.       lvalue->ValueInt.i = ((WORD)lvalue->ValueInt.i) >> rvalue->ValueInt.i;
  120.       return TRUE;
  121.     case Op_sl:
  122.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  123.         return FALSE;
  124.       lvalue->ValueInt.i <<= rvalue->ValueInt.i;
  125.       return TRUE;
  126.     case Op_ror:
  127.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  128.         return FALSE;
  129.       lvalue->ValueInt.i = (((WORD)lvalue->ValueInt.i) >> rvalue->ValueInt.i) |
  130.                            ((lvalue->ValueInt.i) << (32-rvalue->ValueInt.i));
  131.     case Op_rol:
  132.       if(lvalue->Tag != ValueInt || rvalue->Tag != ValueInt)
  133.         return FALSE;
  134.       lvalue->ValueInt.i = ((lvalue->ValueInt.i) << rvalue->ValueInt.i) |
  135.                            (((WORD)lvalue->ValueInt.i) >> (32-rvalue->ValueInt.i));
  136.       return TRUE;
  137.     case Op_le: COMPARE(<=);
  138.     case Op_ge: COMPARE(>=);
  139.     case Op_lt: COMPARE(<);
  140.     case Op_gt: COMPARE(>);
  141.     case Op_eq: COMPARE(==);
  142.     case Op_ne: COMPARE(!=);
  143.     case Op_land:
  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.     case Op_lor:
  149.       if(lvalue->Tag != ValueBool || rvalue->Tag != ValueBool)
  150.         return FALSE;
  151.       lvalue->ValueBool.b = lvalue->ValueBool.b || rvalue->ValueBool.b;
  152.       return TRUE;
  153.     default:
  154.       error(ErrorError,TRUE,"Illegal binary operator.");
  155.     }
  156.   error(ErrorError,TRUE,"Illegal fall through in evalBinop.");
  157.   return FALSE;
  158. }
  159.  
  160. BOOL evalUnop(Operator op, Value *value)
  161. {
  162.   switch(op) {
  163.     case Op_fattr:
  164.       if(value->Tag != ValueString)
  165.         return FALSE;
  166.       error(ErrorError,TRUE,"fattr not implemented\n");
  167.       return TRUE;
  168.     case Op_fexec:
  169.       if(value->Tag != ValueString)
  170.         return FALSE;
  171.       error(ErrorError,TRUE,"fexec not implemented\n");
  172.       return TRUE;
  173.     case Op_fload:
  174.       if(value->Tag != ValueString)
  175.         return FALSE;
  176.       error(ErrorError,TRUE,"fload not implemented\n");
  177.       return TRUE;
  178.     case Op_fsize:
  179.       if(value->Tag != ValueString)
  180.         return FALSE;
  181.       value->ValueString.s[value->ValueString.len] = 0;
  182.       { FILE *fp = getInclude(value->ValueString.s,"r");
  183.         if(!fp) {
  184.           error(ErrorError, TRUE, "cannot open file \"%s\"",value->ValueString.s);
  185.           return FALSE;
  186.         }
  187.         if(fseek(fp,0l,SEEK_END)) {
  188.           error(ErrorError, TRUE, "cannot seek to end of file \"%s\"",value->ValueString.s);
  189.           return FALSE;
  190.         }
  191.         if(-1 == (value->ValueInt.i = (int)ftell(fp))) {
  192.           error(ErrorError, TRUE, "cannot find size of file \"%s\"",value->ValueString.s);
  193.           return FALSE;
  194.         }
  195.         fclose(fp);
  196.         value->Tag = ValueInt;
  197.       }
  198.       return TRUE;
  199.     case Op_lnot:
  200.       if(value->Tag != ValueBool)
  201.         return FALSE;
  202.       value->ValueBool.b = !value->ValueBool.b;
  203.       return TRUE;
  204.     case Op_not:
  205.       if(value->Tag != ValueInt)
  206.         return FALSE;
  207.       value->ValueInt.i = ~value->ValueInt.i;
  208.       return TRUE;
  209.     case Op_neg:
  210.       if(value->Tag == ValueFloat)
  211.         value->ValueFloat.f = -value->ValueFloat.f;
  212.       else {        
  213.         if(!(value->Tag & (ValueInt | ValueLateLabel)))
  214.           return FALSE;
  215.         help_evalNegLate(value);
  216.         value->ValueInt.i = -value->ValueInt.i;
  217.       }
  218.       return TRUE;
  219.     default:
  220.       error(ErrorError,TRUE,"Illegal unary operator.");
  221.   }
  222.   error(ErrorSerious,FALSE,"Illegal fall through in evalUnop.");
  223.   return FALSE;
  224. }
  225.