* scheme-modules.texi (Compiled Code Modules): Removed description
[bpt/guile.git] / libguile / eq.c
CommitLineData
22a52da1 1/* Copyright (C) 1995,1996,1997,1998,2000,2001 Free Software Foundation, Inc.
0f2d19dd
JB
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
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
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.
82892bed 40 * If you do not wish that, delete this exception notice. */
1bbd0b84 41
1bbd0b84 42
0f2d19dd 43\f
a0599745
MD
44#include "libguile/_scm.h"
45#include "libguile/ramap.h"
46#include "libguile/stackchk.h"
47#include "libguile/strorder.h"
48#include "libguile/async.h"
49#include "libguile/root.h"
50#include "libguile/smob.h"
51#include "libguile/unif.h"
52#include "libguile/vectors.h"
0f2d19dd 53
a0599745
MD
54#include "libguile/validate.h"
55#include "libguile/eq.h"
0f2d19dd 56\f
c3ee7520 57SCM_DEFINE1 (scm_eq_p, "eq?", scm_tc7_rpsubr,
1bbd0b84 58 (SCM x, SCM y),
cdbc7418
NJ
59 "Return @code{#t} iff @var{x} references the same object as @var{y}.\n"
60 "@code{eq?} is similar to @code{eqv?} except that in some cases it is\n"
61 "capable of discerning distinctions finer than those detectable by\n"
62 "@code{eqv?}.")
1bbd0b84 63#define FUNC_NAME s_scm_eq_p
0f2d19dd 64{
fbd485ba 65 return SCM_BOOL (SCM_EQ_P (x, y));
0f2d19dd 66}
1bbd0b84 67#undef FUNC_NAME
0f2d19dd 68
96d00047
MV
69/* We compare doubles in a special way for 'eqv?' to be able to
70 distinguish plus and minus zero and to identify NaNs.
71*/
72
73static int
74real_eqv (double x, double y)
75{
76 return !memcmp (&x, &y, sizeof(double));
77}
0f2d19dd 78
c3ee7520 79SCM_DEFINE1 (scm_eqv_p, "eqv?", scm_tc7_rpsubr,
1bbd0b84 80 (SCM x, SCM y),
cdbc7418
NJ
81 "The @code{eqv?} procedure defines a useful equivalence relation on objects.\n"
82 "Briefly, it returns @code{#t} if @var{x} and @var{y} should normally be\n"
83 "regarded as the same object. This relation is left slightly open to\n"
84 "interpretation, but works for comparing immediate integers, characters,\n"
85 "and inexact numbers.")
1bbd0b84 86#define FUNC_NAME s_scm_eqv_p
0f2d19dd 87{
fbd485ba 88 if (SCM_EQ_P (x, y))
950cc72b
MD
89 return SCM_BOOL_T;
90 if (SCM_IMP (x))
91 return SCM_BOOL_F;
92 if (SCM_IMP (y))
93 return SCM_BOOL_F;
0f2d19dd 94 /* this ensures that types and scm_length are the same. */
fbd485ba 95 if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
950cc72b
MD
96 {
97 /* treat mixes of real and complex types specially */
98 if (SCM_SLOPPY_INEXACTP (x))
99 {
100 if (SCM_SLOPPY_REALP (x))
101 return SCM_BOOL (SCM_SLOPPY_COMPLEXP (y)
96d00047
MV
102 && real_eqv (SCM_REAL_VALUE (x),
103 SCM_COMPLEX_REAL (y))
950cc72b
MD
104 && 0.0 == SCM_COMPLEX_IMAG (y));
105 else
106 return SCM_BOOL (SCM_SLOPPY_REALP (y)
96d00047
MV
107 && real_eqv (SCM_COMPLEX_REAL (x),
108 SCM_REAL_VALUE (y))
950cc72b
MD
109 && SCM_COMPLEX_IMAG (x) == 0.0);
110 }
111 return SCM_BOOL_F;
112 }
113 if (SCM_NUMP (x))
114 {
eb42e2f0 115 if (SCM_BIGP (x)) {
950cc72b 116 return SCM_BOOL (0 == scm_bigcomp (x, y));
eb42e2f0 117 } else if (SCM_SLOPPY_REALP (x)) {
96d00047 118 return SCM_BOOL (real_eqv (SCM_REAL_VALUE (x), SCM_REAL_VALUE (y)));
eb42e2f0 119 } else { /* complex */
96d00047
MV
120 return SCM_BOOL (real_eqv (SCM_COMPLEX_REAL (x),
121 SCM_COMPLEX_REAL (y))
122 && real_eqv (SCM_COMPLEX_IMAG (x),
123 SCM_COMPLEX_IMAG (y)));
eb42e2f0 124 }
950cc72b 125 }
0f2d19dd
JB
126 return SCM_BOOL_F;
127}
1bbd0b84 128#undef FUNC_NAME
0f2d19dd
JB
129
130
c3ee7520 131SCM_DEFINE1 (scm_equal_p, "equal?", scm_tc7_rpsubr,
1bbd0b84 132 (SCM x, SCM y),
cdbc7418
NJ
133 "Return @code{#t} iff @var{x} and @var{y} are recursively @code{eqv?} equivalent.\n"
134 "@code{equal?} recursively compares the contents of pairs,\n"
135 "vectors, and strings, applying @code{eqv?} on other objects such as\n"
136 "numbers and symbols. A rule of thumb is that objects are generally\n"
137 "@code{equal?} if they print the same. @code{equal?} may fail to\n"
138 "terminate if its arguments are circular data structures.")
1bbd0b84 139#define FUNC_NAME s_scm_equal_p
0f2d19dd
JB
140{
141 SCM_CHECK_STACK;
950cc72b
MD
142 tailrecurse:
143 SCM_TICK;
fbd485ba 144 if (SCM_EQ_P (x, y))
950cc72b
MD
145 return SCM_BOOL_T;
146 if (SCM_IMP (x))
147 return SCM_BOOL_F;
148 if (SCM_IMP (y))
149 return SCM_BOOL_F;
22a52da1 150 if (SCM_CONSP (x) && SCM_CONSP (y))
950cc72b
MD
151 {
152 if (SCM_FALSEP (scm_equal_p (SCM_CAR (x), SCM_CAR (y))))
153 return SCM_BOOL_F;
154 x = SCM_CDR(x);
155 y = SCM_CDR(y);
156 goto tailrecurse;
157 }
158 if (SCM_TYP7S (x) == scm_tc7_string && SCM_TYP7S (y) == scm_tc7_string)
159 return scm_string_equal_p (x, y);
160 /* This ensures that types and scm_length are the same. */
fbd485ba 161 if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
950cc72b
MD
162 {
163 /* treat mixes of real and complex types specially */
164 if (SCM_SLOPPY_INEXACTP (x))
165 {
166 if (SCM_SLOPPY_REALP (x))
167 return SCM_BOOL (SCM_SLOPPY_COMPLEXP (y)
168 && SCM_REAL_VALUE (x) == SCM_COMPLEX_REAL (y)
169 && 0.0 == SCM_COMPLEX_IMAG (y));
170 else
171 return SCM_BOOL (SCM_SLOPPY_REALP (y)
172 && SCM_COMPLEX_REAL (x) == SCM_REAL_VALUE (y)
173 && SCM_COMPLEX_IMAG (x) == 0.0);
0f2d19dd 174 }
950cc72b
MD
175 return SCM_BOOL_F;
176 }
177 switch (SCM_TYP7 (x))
178 {
179 default:
180 return SCM_BOOL_F;
181 case scm_tc7_vector:
182 case scm_tc7_wvect:
183 return scm_vector_equal_p (x, y);
184 case scm_tc7_smob:
185 {
186 int i = SCM_SMOBNUM (x);
187 if (!(i < scm_numsmob))
188 return SCM_BOOL_F;
189 if (scm_smobs[i].equalp)
190 return (scm_smobs[i].equalp) (x, y);
191 else
192 return SCM_BOOL_F;
193 }
afe5177e 194#ifdef HAVE_ARRAYS
950cc72b
MD
195 case scm_tc7_bvect: case scm_tc7_uvect: case scm_tc7_ivect:
196 case scm_tc7_fvect: case scm_tc7_cvect: case scm_tc7_dvect:
197 case scm_tc7_svect:
5c11cc9d 198#ifdef HAVE_LONG_LONGS
950cc72b 199 case scm_tc7_llvect:
0f2d19dd 200#endif
950cc72b 201 case scm_tc7_byvect:
7a7f7c53 202 if (scm_tc16_array && scm_smobs[SCM_TC2SMOBNUM (scm_tc16_array)].equalp)
950cc72b 203 return scm_array_equal_p (x, y);
afe5177e 204#endif
950cc72b
MD
205 }
206 return SCM_BOOL_F;
0f2d19dd 207}
1bbd0b84 208#undef FUNC_NAME
0f2d19dd
JB
209
210
211\f
212
213
1cc91f1b 214
0f2d19dd
JB
215void
216scm_init_eq ()
0f2d19dd 217{
a0599745 218#include "libguile/eq.x"
0f2d19dd
JB
219}
220
89e00824
ML
221
222/*
223 Local Variables:
224 c-file-style: "gnu"
225 End:
226*/