ch3bin.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* $Id$ */
  6. /* EVALUATION OF BINARY OPERATORS */
  7. #include "Lpars.h"
  8. #include "arith.h"
  9. #include "LLlex.h"
  10. #define arith_sign (1L << (sizeof(arith)*8-1))
  11. void ch3bin(arith *pval, int *pis_uns, int oper, arith val, int is_uns)
  12. {
  13. if (is_uns) *pis_uns = 1;
  14. switch (oper) {
  15. case '/':
  16. if (val == 0) {
  17. error("/ by 0");
  18. break;
  19. }
  20. if (*pis_uns) {
  21. #ifdef UNSIGNED_ARITH
  22. *pval /= (UNSIGNED_ARITH) val;
  23. #else
  24. /* this is more of a problem than you might
  25. think on C compilers which do not have
  26. unsigned arith (== long (probably)).
  27. */
  28. if (val & arith_sign) {/* val > max_arith */
  29. *pval = ! (*pval >= 0 || *pval < val);
  30. /* this is the unsigned test
  31. *pval < val for val > max_arith
  32. */
  33. }
  34. else { /* val <= max_arith */
  35. arith half, bit, hdiv, hrem, rem;
  36. half = (*pval >> 1) & ~arith_sign;
  37. bit = *pval & 01;
  38. /* now *pval == 2 * half + bit
  39. and half <= max_arith
  40. and bit <= max_arith
  41. */
  42. hdiv = half / val;
  43. hrem = half % val;
  44. rem = 2 * hrem + bit;
  45. *pval = 2 * hdiv + (rem < 0 || rem >= val);
  46. /* that is the unsigned compare
  47. rem >= val for val <= max_arith
  48. */
  49. }
  50. #endif
  51. }
  52. else {
  53. *pval = *pval / val;
  54. }
  55. break;
  56. case '%':
  57. if (val == 0) {
  58. error("%% by 0");
  59. break;
  60. }
  61. if (*pis_uns) {
  62. #ifdef UNSIGNED_ARITH
  63. *pval %= (UNSIGNED_ARITH) val;
  64. #else
  65. if (val & arith_sign) {/* val > max_arith */
  66. *pval = (*pval >= 0 || *pval < val) ? *pval : *pval - val;
  67. /* this is the unsigned test
  68. *pval < val for val > max_arith
  69. */
  70. }
  71. else { /* val <= max_arith */
  72. arith half, bit, hrem, rem;
  73. half = (*pval >> 1) & ~arith_sign;
  74. bit = *pval & 01;
  75. /* now *pval == 2 * half + bit
  76. and half <= max_arith
  77. and bit <= max_arith
  78. */
  79. hrem = half % val;
  80. rem = 2 * hrem + bit;
  81. *pval = (rem < 0 || rem >= val) ? rem - val : rem;
  82. }
  83. #endif
  84. }
  85. else {
  86. *pval = *pval % val;
  87. }
  88. break;
  89. case '*':
  90. *pval = *pval * val;
  91. break;
  92. case '+':
  93. *pval = *pval + val;
  94. break;
  95. case '-':
  96. *pval = *pval - val;
  97. break;
  98. case LEFT:
  99. *pval = *pval << val;
  100. break;
  101. case RIGHT:
  102. if (val == 0) break;
  103. if (*pis_uns) {
  104. *pval = (*pval >> 1) & ~arith_sign;
  105. *pval = *pval >> (val - 1);
  106. }
  107. else *pval = *pval >> val;
  108. break;
  109. case '<':
  110. { arith tmp = *pval; *pval = val; val = tmp; }
  111. /* fall through */
  112. case '>':
  113. if (*pis_uns) {
  114. #ifdef UNSIGNED_ARITH
  115. *pval = (UNSIGNED_ARITH) *pval > (UNSIGNED_ARITH) val;
  116. #else
  117. *pval = (*pval & arith_sign ?
  118. (val & arith_sign ? *pval > val : 1) :
  119. (val & arith_sign ? 0 : *pval > val)
  120. );
  121. #endif
  122. }
  123. else *pval = (*pval > val);
  124. break;
  125. case LESSEQ:
  126. { arith tmp = *pval; *pval = val; val = tmp; }
  127. /* fall through */
  128. case GREATEREQ:
  129. if (*pis_uns) {
  130. #ifdef UNSIGNED_ARITH
  131. *pval = (UNSIGNED_ARITH) *pval >= (UNSIGNED_ARITH) val;
  132. #else
  133. *pval = (*pval & arith_sign ?
  134. (val & arith_sign ? *pval >= val : 1) :
  135. (val & arith_sign ? 0 : *pval >= val)
  136. );
  137. #endif
  138. }
  139. else *pval = (*pval >= val);
  140. break;
  141. case EQUAL:
  142. *pval = (*pval == val);
  143. break;
  144. case NOTEQUAL:
  145. *pval = (*pval != val);
  146. break;
  147. case '&':
  148. *pval = *pval & val;
  149. break;
  150. case '^':
  151. *pval = *pval ^ val;
  152. break;
  153. case '|':
  154. *pval = *pval | val;
  155. break;
  156. case AND:
  157. *pval = (*pval && val);
  158. break;
  159. case OR:
  160. *pval = (*pval || val);
  161. break;
  162. case ',':
  163. *pis_uns = is_uns;
  164. *pval = val;
  165. break;
  166. }
  167. }