Include <string.h>, for strncmp.
[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
JB
68
69
c3ee7520 70SCM_DEFINE1 (scm_eqv_p, "eqv?", scm_tc7_rpsubr,
1bbd0b84 71 (SCM x, SCM y),
cdbc7418
NJ
72 "The @code{eqv?} procedure defines a useful equivalence relation on objects.\n"
73 "Briefly, it returns @code{#t} if @var{x} and @var{y} should normally be\n"
74 "regarded as the same object. This relation is left slightly open to\n"
75 "interpretation, but works for comparing immediate integers, characters,\n"
76 "and inexact numbers.")
1bbd0b84 77#define FUNC_NAME s_scm_eqv_p
0f2d19dd 78{
fbd485ba 79 if (SCM_EQ_P (x, y))
950cc72b
MD
80 return SCM_BOOL_T;
81 if (SCM_IMP (x))
82 return SCM_BOOL_F;
83 if (SCM_IMP (y))
84 return SCM_BOOL_F;
0f2d19dd 85 /* this ensures that types and scm_length are the same. */
fbd485ba 86 if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
950cc72b
MD
87 {
88 /* treat mixes of real and complex types specially */
89 if (SCM_SLOPPY_INEXACTP (x))
90 {
91 if (SCM_SLOPPY_REALP (x))
92 return SCM_BOOL (SCM_SLOPPY_COMPLEXP (y)
93 && SCM_REAL_VALUE (x) == SCM_COMPLEX_REAL (y)
94 && 0.0 == SCM_COMPLEX_IMAG (y));
95 else
96 return SCM_BOOL (SCM_SLOPPY_REALP (y)
97 && SCM_COMPLEX_REAL (x) == SCM_REAL_VALUE (y)
98 && SCM_COMPLEX_IMAG (x) == 0.0);
99 }
100 return SCM_BOOL_F;
101 }
102 if (SCM_NUMP (x))
103 {
eb42e2f0 104 if (SCM_BIGP (x)) {
950cc72b 105 return SCM_BOOL (0 == scm_bigcomp (x, y));
eb42e2f0
DH
106 } else if (SCM_SLOPPY_REALP (x)) {
107 return SCM_BOOL (SCM_REAL_VALUE (x) == SCM_REAL_VALUE (y));
108 } else { /* complex */
109 return SCM_BOOL (SCM_COMPLEX_REAL (x) == SCM_COMPLEX_REAL (y)
110 && SCM_COMPLEX_IMAG (x) == SCM_COMPLEX_IMAG (y));
111 }
950cc72b 112 }
0f2d19dd
JB
113 return SCM_BOOL_F;
114}
1bbd0b84 115#undef FUNC_NAME
0f2d19dd
JB
116
117
c3ee7520 118SCM_DEFINE1 (scm_equal_p, "equal?", scm_tc7_rpsubr,
1bbd0b84 119 (SCM x, SCM y),
cdbc7418
NJ
120 "Return @code{#t} iff @var{x} and @var{y} are recursively @code{eqv?} equivalent.\n"
121 "@code{equal?} recursively compares the contents of pairs,\n"
122 "vectors, and strings, applying @code{eqv?} on other objects such as\n"
123 "numbers and symbols. A rule of thumb is that objects are generally\n"
124 "@code{equal?} if they print the same. @code{equal?} may fail to\n"
125 "terminate if its arguments are circular data structures.")
1bbd0b84 126#define FUNC_NAME s_scm_equal_p
0f2d19dd
JB
127{
128 SCM_CHECK_STACK;
950cc72b
MD
129 tailrecurse:
130 SCM_TICK;
fbd485ba 131 if (SCM_EQ_P (x, y))
950cc72b
MD
132 return SCM_BOOL_T;
133 if (SCM_IMP (x))
134 return SCM_BOOL_F;
135 if (SCM_IMP (y))
136 return SCM_BOOL_F;
22a52da1 137 if (SCM_CONSP (x) && SCM_CONSP (y))
950cc72b
MD
138 {
139 if (SCM_FALSEP (scm_equal_p (SCM_CAR (x), SCM_CAR (y))))
140 return SCM_BOOL_F;
141 x = SCM_CDR(x);
142 y = SCM_CDR(y);
143 goto tailrecurse;
144 }
145 if (SCM_TYP7S (x) == scm_tc7_string && SCM_TYP7S (y) == scm_tc7_string)
146 return scm_string_equal_p (x, y);
147 /* This ensures that types and scm_length are the same. */
fbd485ba 148 if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
950cc72b
MD
149 {
150 /* treat mixes of real and complex types specially */
151 if (SCM_SLOPPY_INEXACTP (x))
152 {
153 if (SCM_SLOPPY_REALP (x))
154 return SCM_BOOL (SCM_SLOPPY_COMPLEXP (y)
155 && SCM_REAL_VALUE (x) == SCM_COMPLEX_REAL (y)
156 && 0.0 == SCM_COMPLEX_IMAG (y));
157 else
158 return SCM_BOOL (SCM_SLOPPY_REALP (y)
159 && SCM_COMPLEX_REAL (x) == SCM_REAL_VALUE (y)
160 && SCM_COMPLEX_IMAG (x) == 0.0);
0f2d19dd 161 }
950cc72b
MD
162 return SCM_BOOL_F;
163 }
164 switch (SCM_TYP7 (x))
165 {
166 default:
167 return SCM_BOOL_F;
168 case scm_tc7_vector:
169 case scm_tc7_wvect:
170 return scm_vector_equal_p (x, y);
171 case scm_tc7_smob:
172 {
173 int i = SCM_SMOBNUM (x);
174 if (!(i < scm_numsmob))
175 return SCM_BOOL_F;
176 if (scm_smobs[i].equalp)
177 return (scm_smobs[i].equalp) (x, y);
178 else
179 return SCM_BOOL_F;
180 }
afe5177e 181#ifdef HAVE_ARRAYS
950cc72b
MD
182 case scm_tc7_bvect: case scm_tc7_uvect: case scm_tc7_ivect:
183 case scm_tc7_fvect: case scm_tc7_cvect: case scm_tc7_dvect:
184 case scm_tc7_svect:
5c11cc9d 185#ifdef HAVE_LONG_LONGS
950cc72b 186 case scm_tc7_llvect:
0f2d19dd 187#endif
950cc72b 188 case scm_tc7_byvect:
7a7f7c53 189 if (scm_tc16_array && scm_smobs[SCM_TC2SMOBNUM (scm_tc16_array)].equalp)
950cc72b 190 return scm_array_equal_p (x, y);
afe5177e 191#endif
950cc72b
MD
192 }
193 return SCM_BOOL_F;
0f2d19dd 194}
1bbd0b84 195#undef FUNC_NAME
0f2d19dd
JB
196
197
198\f
199
200
1cc91f1b 201
0f2d19dd
JB
202void
203scm_init_eq ()
0f2d19dd 204{
a0599745 205#include "libguile/eq.x"
0f2d19dd
JB
206}
207
89e00824
ML
208
209/*
210 Local Variables:
211 c-file-style: "gnu"
212 End:
213*/