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