eq.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* Copyright (C) 1995,1996,1997,1998,2000,2001, 2003 Free Software Foundation, Inc.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2, or (at your option)
  6. * any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; see the file COPYING. If not, write to
  15. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  16. * Boston, MA 02110-1301 USA
  17. *
  18. * As a special exception, the Free Software Foundation gives permission
  19. * for additional uses of the text contained in its release of GUILE.
  20. *
  21. * The exception is that, if you link the GUILE library with other files
  22. * to produce an executable, this does not by itself cause the
  23. * resulting executable to be covered by the GNU General Public License.
  24. * Your use of that executable is in no way restricted on account of
  25. * linking the GUILE library code into it.
  26. *
  27. * This exception does not however invalidate any other reasons why
  28. * the executable file might be covered by the GNU General Public License.
  29. *
  30. * This exception applies only to the code released by the
  31. * Free Software Foundation under the name GUILE. If you copy
  32. * code from other Free Software Foundation releases into a copy of
  33. * GUILE, as the General Public License permits, the exception does
  34. * not apply to the code that you add in this way. To avoid misleading
  35. * anyone as to the status of such modified files, you must delete
  36. * this exception notice from them.
  37. *
  38. * If you write modifications of your own for GUILE, it is your choice
  39. * whether to permit this exception to apply to your modifications.
  40. * If you do not wish that, delete this exception notice. */
  41. #include "libguile/_scm.h"
  42. #include "libguile/ramap.h"
  43. #include "libguile/stackchk.h"
  44. #include "libguile/strorder.h"
  45. #include "libguile/async.h"
  46. #include "libguile/root.h"
  47. #include "libguile/smob.h"
  48. #include "libguile/unif.h"
  49. #include "libguile/vectors.h"
  50. #include "libguile/validate.h"
  51. #include "libguile/eq.h"
  52. SCM_DEFINE1 (scm_eq_p, "eq?", scm_tc7_rpsubr,
  53. (SCM x, SCM y),
  54. "Return @code{#t} iff @var{x} references the same object as @var{y}.\n"
  55. "@code{eq?} is similar to @code{eqv?} except that in some cases it is\n"
  56. "capable of discerning distinctions finer than those detectable by\n"
  57. "@code{eqv?}.")
  58. #define FUNC_NAME s_scm_eq_p
  59. {
  60. return SCM_BOOL (SCM_EQ_P (x, y));
  61. }
  62. #undef FUNC_NAME
  63. SCM_PRIMITIVE_GENERIC_1 (scm_eqv_p, "eqv?", scm_tc7_rpsubr,
  64. (SCM x, SCM y),
  65. "The @code{eqv?} procedure defines a useful equivalence relation on objects.\n"
  66. "Briefly, it returns @code{#t} if @var{x} and @var{y} should normally be\n"
  67. "regarded as the same object. This relation is left slightly open to\n"
  68. "interpretation, but works for comparing immediate integers, characters,\n"
  69. "and inexact numbers.")
  70. #define FUNC_NAME s_scm_eqv_p
  71. {
  72. if (SCM_EQ_P (x, y))
  73. return SCM_BOOL_T;
  74. if (SCM_IMP (x))
  75. return SCM_BOOL_F;
  76. if (SCM_IMP (y))
  77. return SCM_BOOL_F;
  78. /* this ensures that types and scm_length are the same. */
  79. if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
  80. {
  81. /* treat mixes of real and complex types specially */
  82. if (SCM_SLOPPY_INEXACTP (x))
  83. {
  84. if (SCM_SLOPPY_REALP (x))
  85. return SCM_BOOL (SCM_SLOPPY_COMPLEXP (y)
  86. && SCM_REAL_VALUE (x) == SCM_COMPLEX_REAL (y)
  87. && 0.0 == SCM_COMPLEX_IMAG (y));
  88. else
  89. return SCM_BOOL (SCM_SLOPPY_REALP (y)
  90. && SCM_COMPLEX_REAL (x) == SCM_REAL_VALUE (y)
  91. && SCM_COMPLEX_IMAG (x) == 0.0);
  92. }
  93. return SCM_BOOL_F;
  94. }
  95. if (SCM_NUMP (x))
  96. {
  97. if (SCM_BIGP (x)) {
  98. return SCM_BOOL (0 == scm_bigcomp (x, y));
  99. } else if (SCM_SLOPPY_REALP (x)) {
  100. return SCM_BOOL (SCM_REAL_VALUE (x) == SCM_REAL_VALUE (y));
  101. } else { /* complex */
  102. return SCM_BOOL (SCM_COMPLEX_REAL (x) == SCM_COMPLEX_REAL (y)
  103. && SCM_COMPLEX_IMAG (x) == SCM_COMPLEX_IMAG (y));
  104. }
  105. }
  106. if (SCM_UNPACK (g_scm_eqv_p))
  107. return scm_call_generic_2 (g_scm_eqv_p, x, y);
  108. else
  109. return SCM_BOOL_F;
  110. }
  111. #undef FUNC_NAME
  112. SCM_PRIMITIVE_GENERIC_1 (scm_equal_p, "equal?", scm_tc7_rpsubr,
  113. (SCM x, SCM y),
  114. "Return @code{#t} iff @var{x} and @var{y} are recursively @code{eqv?} equivalent.\n"
  115. "@code{equal?} recursively compares the contents of pairs,\n"
  116. "vectors, and strings, applying @code{eqv?} on other objects such as\n"
  117. "numbers and symbols. A rule of thumb is that objects are generally\n"
  118. "@code{equal?} if they print the same. @code{equal?} may fail to\n"
  119. "terminate if its arguments are circular data structures.")
  120. #define FUNC_NAME s_scm_equal_p
  121. {
  122. SCM_CHECK_STACK;
  123. tailrecurse:
  124. SCM_TICK;
  125. if (SCM_EQ_P (x, y))
  126. return SCM_BOOL_T;
  127. if (SCM_IMP (x))
  128. return SCM_BOOL_F;
  129. if (SCM_IMP (y))
  130. return SCM_BOOL_F;
  131. if (SCM_CONSP (x) && SCM_CONSP (y))
  132. {
  133. if (SCM_FALSEP (scm_equal_p (SCM_CAR (x), SCM_CAR (y))))
  134. return SCM_BOOL_F;
  135. x = SCM_CDR(x);
  136. y = SCM_CDR(y);
  137. goto tailrecurse;
  138. }
  139. if (SCM_TYP7S (x) == scm_tc7_string && SCM_TYP7S (y) == scm_tc7_string)
  140. return scm_string_equal_p (x, y);
  141. /* This ensures that types and scm_length are the same. */
  142. if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
  143. {
  144. /* treat mixes of real and complex types specially */
  145. if (SCM_SLOPPY_INEXACTP (x))
  146. {
  147. if (SCM_SLOPPY_REALP (x))
  148. return SCM_BOOL (SCM_SLOPPY_COMPLEXP (y)
  149. && SCM_REAL_VALUE (x) == SCM_COMPLEX_REAL (y)
  150. && 0.0 == SCM_COMPLEX_IMAG (y));
  151. else
  152. return SCM_BOOL (SCM_SLOPPY_REALP (y)
  153. && SCM_COMPLEX_REAL (x) == SCM_REAL_VALUE (y)
  154. && SCM_COMPLEX_IMAG (x) == 0.0);
  155. }
  156. return SCM_BOOL_F;
  157. }
  158. switch (SCM_TYP7 (x))
  159. {
  160. default:
  161. break;
  162. case scm_tc7_vector:
  163. case scm_tc7_wvect:
  164. return scm_vector_equal_p (x, y);
  165. case scm_tc7_smob:
  166. {
  167. int i = SCM_SMOBNUM (x);
  168. if (!(i < scm_numsmob))
  169. return SCM_BOOL_F;
  170. if (scm_smobs[i].equalp)
  171. return (scm_smobs[i].equalp) (x, y);
  172. else
  173. break;
  174. }
  175. #ifdef HAVE_ARRAYS
  176. case scm_tc7_bvect: case scm_tc7_uvect: case scm_tc7_ivect:
  177. case scm_tc7_fvect: case scm_tc7_cvect: case scm_tc7_dvect:
  178. case scm_tc7_svect:
  179. #ifdef HAVE_LONG_LONGS
  180. case scm_tc7_llvect:
  181. #endif
  182. case scm_tc7_byvect:
  183. if (scm_tc16_array && scm_smobs[SCM_TC2SMOBNUM (scm_tc16_array)].equalp)
  184. return scm_array_equal_p (x, y);
  185. #endif
  186. }
  187. if (SCM_UNPACK (g_scm_equal_p))
  188. return scm_call_generic_2 (g_scm_equal_p, x, y);
  189. else
  190. return SCM_BOOL_F;
  191. }
  192. #undef FUNC_NAME
  193. void
  194. scm_init_eq ()
  195. {
  196. #include "libguile/eq.x"
  197. }
  198. /*
  199. Local Variables:
  200. c-file-style: "gnu"
  201. End:
  202. */