test.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // If the number of args is odd then the last arg is the default result.
  2. #include "stdafx.h"
  3. #include "defs.h"
  4. void
  5. eval_test(void)
  6. {
  7. p1 = cdr(p1);
  8. while (iscons(p1)) {
  9. if (cdr(p1) == symbol(NIL)) {
  10. push(car(p1)); // default case
  11. eval();
  12. return;
  13. }
  14. push(car(p1));
  15. eval_predicate();
  16. p2 = pop();
  17. if (!iszero(p2)) {
  18. push(cadr(p1));
  19. eval();
  20. return;
  21. }
  22. p1 = cddr(p1);
  23. }
  24. push_integer(0);
  25. }
  26. // The test for equality is weaker than the other relational operators.
  27. // For example, A<=B causes a stop when the result of A minus B is not a
  28. // numerical value.
  29. // However, A==B never causes a stop.
  30. // For A==B, any nonzero result for A minus B indicates inequality.
  31. void
  32. eval_testeq(void)
  33. {
  34. push(cadr(p1));
  35. eval();
  36. push(caddr(p1));
  37. eval();
  38. subtract();
  39. p1 = pop();
  40. if (iszero(p1))
  41. push_integer(1);
  42. else
  43. push_integer(0);
  44. }
  45. // Relational operators expect a numeric result for operand difference.
  46. void
  47. eval_testge(void)
  48. {
  49. if (cmp_args() >= 0)
  50. push_integer(1);
  51. else
  52. push_integer(0);
  53. }
  54. void
  55. eval_testgt(void)
  56. {
  57. if (cmp_args() > 0)
  58. push_integer(1);
  59. else
  60. push_integer(0);
  61. }
  62. void
  63. eval_testle(void)
  64. {
  65. if (cmp_args() <= 0)
  66. push_integer(1);
  67. else
  68. push_integer(0);
  69. }
  70. void
  71. eval_testlt(void)
  72. {
  73. if (cmp_args() < 0)
  74. push_integer(1);
  75. else
  76. push_integer(0);
  77. }
  78. void
  79. eval_not(void)
  80. {
  81. push(cadr(p1));
  82. eval_predicate();
  83. p1 = pop();
  84. if (iszero(p1))
  85. push_integer(1);
  86. else
  87. push_integer(0);
  88. }
  89. void
  90. eval_and(void)
  91. {
  92. p1 = cdr(p1);
  93. while (iscons(p1)) {
  94. push(car(p1));
  95. eval_predicate();
  96. p2 = pop();
  97. if (iszero(p2)) {
  98. push_integer(0);
  99. return;
  100. }
  101. p1 = cdr(p1);
  102. }
  103. push_integer(1);
  104. }
  105. void
  106. eval_or(void)
  107. {
  108. p1 = cdr(p1);
  109. while (iscons(p1)) {
  110. push(car(p1));
  111. eval_predicate();
  112. p2 = pop();
  113. if (!iszero(p2)) {
  114. push_integer(1);
  115. return;
  116. }
  117. p1 = cdr(p1);
  118. }
  119. push_integer(0);
  120. }
  121. // use subtract for cases like A < A + 1
  122. int
  123. cmp_args(void)
  124. {
  125. int t;
  126. push(cadr(p1));
  127. eval();
  128. push(caddr(p1));
  129. eval();
  130. subtract();
  131. p1 = pop();
  132. // try floating point if necessary
  133. if (p1->k != NUM && p1->k != DOUBLE) {
  134. push(p1);
  135. yyfloat();
  136. eval();
  137. p1 = pop();
  138. }
  139. if (iszero(p1))
  140. return 0;
  141. switch (p1->k) {
  142. case NUM:
  143. if (MSIGN(p1->u.q.a) == -1)
  144. t = -1;
  145. else
  146. t = 1;
  147. break;
  148. case DOUBLE:
  149. if (p1->u.d < 0.0)
  150. t = -1;
  151. else
  152. t = 1;
  153. break;
  154. default:
  155. stop("relational operator: cannot determine due to non-numerical comparison");
  156. t = 0;
  157. }
  158. return t;
  159. }