2018-06-20 19:17:06 +02:00
|
|
|
|
/* Copyright 1995-1998,2000-2001,2003-2004,2006,2009-2011,2017-2018
|
2018-06-20 20:01:49 +02:00
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
|
|
|
|
This file is part of Guile.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is free software: you can redistribute it and/or modify it
|
|
|
|
|
|
under the terms of the GNU Lesser General Public License as published
|
|
|
|
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
|
|
|
|
License for more details.
|
|
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
License along with Guile. If not, see
|
|
|
|
|
|
<https://www.gnu.org/licenses/>. */
|
1999-12-12 02:36:16 +00:00
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2008-09-13 15:35:27 +02:00
|
|
|
|
#ifdef HAVE_CONFIG_H
|
2003-03-25 23:54:15 +00:00
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
2002-07-10 22:25:55 +00:00
|
|
|
|
|
`equal?' and `eqv?' are now equivalent for numbers
Change `equal?' to work like `eqv?' for numbers.
Previously they worked differently in some cases, e.g.
when comparing signed zeroes or NaNs. For example,
(equal? 0.0 -0.0) returned #t but (eqv? 0.0 -0.0)
returned #f, and (equal? +nan.0 +nan.0) returned #f
but (eqv? +nan.0 +nan.0) returned #t.
* libguile/numbers.c (scm_real_equalp, scm_bigequal,
scm_complex_equalp, scm_i_fraction_equalp): Move to eq.c.
* libguile/eq.c (scm_real_equalp): Compare flonums using
real_eqv instead of ==, so that NaNs are now considered
equal, and to distinguish signed zeroes.
(scm_complex_equalp): Compare real and imaginary
components using real_eqv instead of ==, so that NaNs are
now considered equal, and to distinguish signed zeroes.
(scm_bigequal): Use scm_i_bigcmp instead of duplicating it.
(real_eqv): Test for NaNs using isnan(x) instead of
(x != x), and use SCM_UNLIKELY for optimization.
(scm_eqv_p): Use scm_bigequal, scm_real_equalp,
scm_complex_equalp, and scm_i_fraction_equalp to compare
numbers, instead of inline code. Those predicates now do
what scm_eqv_p formerly did internally. Replace if
statements with switch statements, as is done in
scm_equal_p. Remove useless code to check equality of
fractions with different SCM_CELL_TYPEs; this was for a
tentative "lazy reduction bit" which was never developed.
(scm_eqv_p, scm_equal_p): Remove useless code to check
equality between inexact reals and non-real complex numbers
with zero imaginary part. Such numbers do not exist,
because the current code is careful to never create them.
* test-suite/tests/numbers.test: Add test cases for
`eqv?' and `equal?'. Change existing test case for
`(equal? +nan.0 +nan.0)' to expect #t instead of #f.
* NEWS: Add NEWS entries.
2011-01-28 19:57:41 -05:00
|
|
|
|
#include <math.h>
|
2018-06-14 22:16:01 +02:00
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "array-map.h"
|
|
|
|
|
|
#include "async.h"
|
|
|
|
|
|
#include "bitvectors.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "boolean.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "bytevectors.h"
|
|
|
|
|
|
#include "eval.h"
|
|
|
|
|
|
#include "foreign.h"
|
|
|
|
|
|
#include "generalized-arrays.h"
|
|
|
|
|
|
#include "goops.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "gsubr.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "hashtab.h"
|
|
|
|
|
|
#include "pairs.h"
|
|
|
|
|
|
#include "private-options.h"
|
|
|
|
|
|
#include "smob.h"
|
|
|
|
|
|
#include "stackchk.h"
|
|
|
|
|
|
#include "strorder.h"
|
|
|
|
|
|
#include "struct.h"
|
|
|
|
|
|
#include "syntax.h"
|
|
|
|
|
|
#include "vectors.h"
|
* backtrace.c, debug.c, debug.h, deprecation.c, eq.c, eval.c
eval.h, gsubr.c, init.c, macros.c, print.c, print.h, read.c,
read.h, stacks.c, symbols.c, throw.c: use private-options.h
* private-options.h: new file: contain hardcoded option
definitions.
2007-01-22 15:14:40 +00:00
|
|
|
|
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "eq.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2002-07-10 22:25:55 +00:00
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_eq_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_eq_p, "eq?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
2004-12-09 23:49:46 +00:00
|
|
|
|
"Return @code{#t} if @var{x} and @var{y} are the same object,\n"
|
|
|
|
|
|
"except for numbers and characters. For example,\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"@example\n"
|
|
|
|
|
|
"(define x (vector 1 2 3))\n"
|
|
|
|
|
|
"(define y (vector 1 2 3))\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"(eq? x x) @result{} #t\n"
|
|
|
|
|
|
"(eq? x y) @result{} #f\n"
|
|
|
|
|
|
"@end example\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"Numbers and characters are not equal to any other object, but\n"
|
|
|
|
|
|
"the problem is they're not necessarily @code{eq?} to themselves\n"
|
|
|
|
|
|
"either. This is even so when the number comes directly from a\n"
|
|
|
|
|
|
"variable,\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"@example\n"
|
|
|
|
|
|
"(let ((n (+ 2 3)))\n"
|
|
|
|
|
|
" (eq? n n)) @result{} *unspecified*\n"
|
|
|
|
|
|
"@end example\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"Generally @code{eqv?} should be used when comparing numbers or\n"
|
|
|
|
|
|
"characters. @code{=} or @code{char=?} can be used too.\n"
|
|
|
|
|
|
"\n"
|
2004-12-10 00:49:51 +00:00
|
|
|
|
"It's worth noting that end-of-list @code{()}, @code{#t},\n"
|
|
|
|
|
|
"@code{#f}, a symbol of a given name, and a keyword of a given\n"
|
|
|
|
|
|
"name, are unique objects. There's just one of each, so for\n"
|
|
|
|
|
|
"instance no matter how @code{()} arises in a program, it's the\n"
|
|
|
|
|
|
"same object and can be compared with @code{eq?},\n"
|
2004-12-09 23:49:46 +00:00
|
|
|
|
"\n"
|
|
|
|
|
|
"@example\n"
|
|
|
|
|
|
"(define x (cdr '(123)))\n"
|
|
|
|
|
|
"(define y (cdr '(456)))\n"
|
|
|
|
|
|
"(eq? x y) @result{} #t\n"
|
|
|
|
|
|
"\n"
|
2004-12-10 00:49:51 +00:00
|
|
|
|
"(define x (string->symbol \"foo\"))\n"
|
2004-12-09 23:49:46 +00:00
|
|
|
|
"(eq? x 'foo) @result{} #t\n"
|
|
|
|
|
|
"@end example")
|
2009-12-04 13:05:00 +01:00
|
|
|
|
#define FUNC_NAME s_scm_i_eq_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2009-12-04 13:05:00 +01:00
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (scm_is_pair (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!scm_is_eq (x, y))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
2004-07-27 15:41:49 +00:00
|
|
|
|
return scm_from_bool (scm_is_eq (x, y));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_eq_p (SCM x, SCM y)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_bool (scm_is_eq (x, y));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2002-05-08 20:11:27 +00:00
|
|
|
|
/* We compare doubles in a special way for 'eqv?' to be able to
|
|
|
|
|
|
distinguish plus and minus zero and to identify NaNs.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
|
real_eqv (double x, double y)
|
|
|
|
|
|
{
|
`equal?' and `eqv?' are now equivalent for numbers
Change `equal?' to work like `eqv?' for numbers.
Previously they worked differently in some cases, e.g.
when comparing signed zeroes or NaNs. For example,
(equal? 0.0 -0.0) returned #t but (eqv? 0.0 -0.0)
returned #f, and (equal? +nan.0 +nan.0) returned #f
but (eqv? +nan.0 +nan.0) returned #t.
* libguile/numbers.c (scm_real_equalp, scm_bigequal,
scm_complex_equalp, scm_i_fraction_equalp): Move to eq.c.
* libguile/eq.c (scm_real_equalp): Compare flonums using
real_eqv instead of ==, so that NaNs are now considered
equal, and to distinguish signed zeroes.
(scm_complex_equalp): Compare real and imaginary
components using real_eqv instead of ==, so that NaNs are
now considered equal, and to distinguish signed zeroes.
(scm_bigequal): Use scm_i_bigcmp instead of duplicating it.
(real_eqv): Test for NaNs using isnan(x) instead of
(x != x), and use SCM_UNLIKELY for optimization.
(scm_eqv_p): Use scm_bigequal, scm_real_equalp,
scm_complex_equalp, and scm_i_fraction_equalp to compare
numbers, instead of inline code. Those predicates now do
what scm_eqv_p formerly did internally. Replace if
statements with switch statements, as is done in
scm_equal_p. Remove useless code to check equality of
fractions with different SCM_CELL_TYPEs; this was for a
tentative "lazy reduction bit" which was never developed.
(scm_eqv_p, scm_equal_p): Remove useless code to check
equality between inexact reals and non-real complex numbers
with zero imaginary part. Such numbers do not exist,
because the current code is careful to never create them.
* test-suite/tests/numbers.test: Add test cases for
`eqv?' and `equal?'. Change existing test case for
`(equal? +nan.0 +nan.0)' to expect #t instead of #f.
* NEWS: Add NEWS entries.
2011-01-28 19:57:41 -05:00
|
|
|
|
return !memcmp (&x, &y, sizeof(double))
|
|
|
|
|
|
|| (SCM_UNLIKELY (isnan (x)) && SCM_UNLIKELY (isnan (y)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_real_equalp (SCM x, SCM y)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_bool (real_eqv (SCM_REAL_VALUE (x),
|
|
|
|
|
|
SCM_REAL_VALUE (y)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_bigequal (SCM x, SCM y)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_bool (scm_i_bigcmp (x, y) == 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_complex_equalp (SCM x, SCM y)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_bool (real_eqv (SCM_COMPLEX_REAL (x),
|
|
|
|
|
|
SCM_COMPLEX_REAL (y))
|
|
|
|
|
|
&& real_eqv (SCM_COMPLEX_IMAG (x),
|
|
|
|
|
|
SCM_COMPLEX_IMAG (y)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_i_fraction_equalp (SCM x, SCM y)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_bool
|
|
|
|
|
|
(scm_is_true (scm_equal_p (SCM_FRACTION_NUMERATOR (x),
|
|
|
|
|
|
SCM_FRACTION_NUMERATOR (y)))
|
|
|
|
|
|
&& scm_is_true (scm_equal_p (SCM_FRACTION_DENOMINATOR (x),
|
|
|
|
|
|
SCM_FRACTION_DENOMINATOR (y))));
|
2002-05-08 20:11:27 +00:00
|
|
|
|
}
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2018-05-08 11:49:46 +02:00
|
|
|
|
int
|
2017-10-29 15:44:25 +01:00
|
|
|
|
scm_i_heap_numbers_equal_p (SCM x, SCM y)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_IMP (x)) abort();
|
|
|
|
|
|
switch (SCM_TYP16 (x))
|
|
|
|
|
|
{
|
|
|
|
|
|
case scm_tc16_big:
|
2018-05-08 11:49:46 +02:00
|
|
|
|
return scm_is_true (scm_bigequal (x, y));
|
2017-10-29 15:44:25 +01:00
|
|
|
|
case scm_tc16_real:
|
2018-05-08 11:49:46 +02:00
|
|
|
|
return scm_is_true (scm_real_equalp (x, y));
|
2017-10-29 15:44:25 +01:00
|
|
|
|
case scm_tc16_complex:
|
2018-05-08 11:49:46 +02:00
|
|
|
|
return scm_is_true (scm_complex_equalp (x, y));
|
2017-10-29 15:44:25 +01:00
|
|
|
|
case scm_tc16_fraction:
|
2018-05-08 11:49:46 +02:00
|
|
|
|
return scm_is_true (scm_i_fraction_equalp (x, y));
|
2017-10-29 15:44:25 +01:00
|
|
|
|
default:
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_eqv_p (SCM x, SCM y, SCM rest);
|
* print.c (scm_iprin1): Handle fractions.
* objects.h (scm_class_fraction): New.
* objects.c (scm_class_fraction): New.
(scm_class_of): Handle fractions.
* hash.c (scm_hasher): Handle fractions.
* numbers.c: New code for handling fraction all over the place.
(scm_odd_p, scm_even_p): Handle inexact integers.
(scm_rational_p): New function, same as scm_real_p.
(scm_round_number, scm_truncate_number, scm_ceiling, scm_floor):
New exact functions that replace the inexact 'dsubr'
implementations.
(scm_numerator, scm_denominator): New.
* numbers.h (SCM_NUMP): Recognize fractions.
(SCM_FRACTIONP, SCM_SLOPPY_FRACTIONP, SCM_FRACTION_NUMERATOR,
SCM_FRACTION_DENOMINATOR, SCM_FRACTION_SET_NUMERATOR,
SCM_FRACTION_SET_DENOMINATOR, SCM_FRACTION_REDUCED_BIT,
SCM_FRACTION_REDUCED_SET, SCM_FRACTION_REDUCED_CLEAR,
SCM_FRACTION_REDUCED): New.
(scm_floor, scm_ceiling, scm_truncate_number, scm_round_number):
New prototypes.
(scm_make_ratio, scm_rationalize, scm_numerator, scm_denominator,
scm_rational_p): New prototypes.
(scm_i_dbl2num, scm_i_fraction2double, scm_i_fraction_equalp,
scm_i_print_fraction): New prototypes.
* goops.c (create_standard_classes): Create "<fraction>" class.
* gc-mark.c (scm_gc_mark_dependencies): Handle fractions.
* gc-card.c (scm_i_sweep_card): Include scm_tc16_fraction as a
case in the switch, but do nothing for now.
* eval.c (SCM_CEVAL, SCM_APPLY, call_dsubr_1): Convert fractions
to doubles when calling 'dsubr' functions.
* eq.c (scm_eqv_p, scm_equal_p): Handle fractions.
2003-11-18 19:59:53 +00:00
|
|
|
|
#include <stdio.h>
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_eqv_p, "eqv?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
2004-12-09 23:49:46 +00:00
|
|
|
|
"Return @code{#t} if @var{x} and @var{y} are the same object, or\n"
|
|
|
|
|
|
"for characters and numbers the same value.\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"On objects except characters and numbers, @code{eqv?} is the\n"
|
|
|
|
|
|
"same as @code{eq?}, it's true if @var{x} and @var{y} are the\n"
|
|
|
|
|
|
"same object.\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"If @var{x} and @var{y} are numbers or characters, @code{eqv?}\n"
|
|
|
|
|
|
"compares their type and value. An exact number is not\n"
|
|
|
|
|
|
"@code{eqv?} to an inexact number (even if their value is the\n"
|
|
|
|
|
|
"same).\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"@example\n"
|
|
|
|
|
|
"(eqv? 3 (+ 1 2)) @result{} #t\n"
|
|
|
|
|
|
"(eqv? 1 1.0) @result{} #f\n"
|
|
|
|
|
|
"@end example")
|
2009-12-04 13:05:00 +01:00
|
|
|
|
#define FUNC_NAME s_scm_i_eqv_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!scm_is_true (scm_eqv_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_eqv_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_eqv_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_eqv_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2004-07-27 15:41:49 +00:00
|
|
|
|
if (scm_is_eq (x, y))
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
if (SCM_IMP (x))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
if (SCM_IMP (y))
|
|
|
|
|
|
return SCM_BOOL_F;
|
* print.c (scm_iprin1): Handle fractions.
* objects.h (scm_class_fraction): New.
* objects.c (scm_class_fraction): New.
(scm_class_of): Handle fractions.
* hash.c (scm_hasher): Handle fractions.
* numbers.c: New code for handling fraction all over the place.
(scm_odd_p, scm_even_p): Handle inexact integers.
(scm_rational_p): New function, same as scm_real_p.
(scm_round_number, scm_truncate_number, scm_ceiling, scm_floor):
New exact functions that replace the inexact 'dsubr'
implementations.
(scm_numerator, scm_denominator): New.
* numbers.h (SCM_NUMP): Recognize fractions.
(SCM_FRACTIONP, SCM_SLOPPY_FRACTIONP, SCM_FRACTION_NUMERATOR,
SCM_FRACTION_DENOMINATOR, SCM_FRACTION_SET_NUMERATOR,
SCM_FRACTION_SET_DENOMINATOR, SCM_FRACTION_REDUCED_BIT,
SCM_FRACTION_REDUCED_SET, SCM_FRACTION_REDUCED_CLEAR,
SCM_FRACTION_REDUCED): New.
(scm_floor, scm_ceiling, scm_truncate_number, scm_round_number):
New prototypes.
(scm_make_ratio, scm_rationalize, scm_numerator, scm_denominator,
scm_rational_p): New prototypes.
(scm_i_dbl2num, scm_i_fraction2double, scm_i_fraction_equalp,
scm_i_print_fraction): New prototypes.
* goops.c (create_standard_classes): Create "<fraction>" class.
* gc-mark.c (scm_gc_mark_dependencies): Handle fractions.
* gc-card.c (scm_i_sweep_card): Include scm_tc16_fraction as a
case in the switch, but do nothing for now.
* eval.c (SCM_CEVAL, SCM_APPLY, call_dsubr_1): Convert fractions
to doubles when calling 'dsubr' functions.
* eq.c (scm_eqv_p, scm_equal_p): Handle fractions.
2003-11-18 19:59:53 +00:00
|
|
|
|
|
`equal?' and `eqv?' are now equivalent for numbers
Change `equal?' to work like `eqv?' for numbers.
Previously they worked differently in some cases, e.g.
when comparing signed zeroes or NaNs. For example,
(equal? 0.0 -0.0) returned #t but (eqv? 0.0 -0.0)
returned #f, and (equal? +nan.0 +nan.0) returned #f
but (eqv? +nan.0 +nan.0) returned #t.
* libguile/numbers.c (scm_real_equalp, scm_bigequal,
scm_complex_equalp, scm_i_fraction_equalp): Move to eq.c.
* libguile/eq.c (scm_real_equalp): Compare flonums using
real_eqv instead of ==, so that NaNs are now considered
equal, and to distinguish signed zeroes.
(scm_complex_equalp): Compare real and imaginary
components using real_eqv instead of ==, so that NaNs are
now considered equal, and to distinguish signed zeroes.
(scm_bigequal): Use scm_i_bigcmp instead of duplicating it.
(real_eqv): Test for NaNs using isnan(x) instead of
(x != x), and use SCM_UNLIKELY for optimization.
(scm_eqv_p): Use scm_bigequal, scm_real_equalp,
scm_complex_equalp, and scm_i_fraction_equalp to compare
numbers, instead of inline code. Those predicates now do
what scm_eqv_p formerly did internally. Replace if
statements with switch statements, as is done in
scm_equal_p. Remove useless code to check equality of
fractions with different SCM_CELL_TYPEs; this was for a
tentative "lazy reduction bit" which was never developed.
(scm_eqv_p, scm_equal_p): Remove useless code to check
equality between inexact reals and non-real complex numbers
with zero imaginary part. Such numbers do not exist,
because the current code is careful to never create them.
* test-suite/tests/numbers.test: Add test cases for
`eqv?' and `equal?'. Change existing test case for
`(equal? +nan.0 +nan.0)' to expect #t instead of #f.
* NEWS: Add NEWS entries.
2011-01-28 19:57:41 -05:00
|
|
|
|
/* this ensures that types and scm_length are the same. */
|
2000-03-29 16:22:57 +00:00
|
|
|
|
if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
|
`equal?' and `eqv?' are now equivalent for numbers
Change `equal?' to work like `eqv?' for numbers.
Previously they worked differently in some cases, e.g.
when comparing signed zeroes or NaNs. For example,
(equal? 0.0 -0.0) returned #t but (eqv? 0.0 -0.0)
returned #f, and (equal? +nan.0 +nan.0) returned #f
but (eqv? +nan.0 +nan.0) returned #t.
* libguile/numbers.c (scm_real_equalp, scm_bigequal,
scm_complex_equalp, scm_i_fraction_equalp): Move to eq.c.
* libguile/eq.c (scm_real_equalp): Compare flonums using
real_eqv instead of ==, so that NaNs are now considered
equal, and to distinguish signed zeroes.
(scm_complex_equalp): Compare real and imaginary
components using real_eqv instead of ==, so that NaNs are
now considered equal, and to distinguish signed zeroes.
(scm_bigequal): Use scm_i_bigcmp instead of duplicating it.
(real_eqv): Test for NaNs using isnan(x) instead of
(x != x), and use SCM_UNLIKELY for optimization.
(scm_eqv_p): Use scm_bigequal, scm_real_equalp,
scm_complex_equalp, and scm_i_fraction_equalp to compare
numbers, instead of inline code. Those predicates now do
what scm_eqv_p formerly did internally. Replace if
statements with switch statements, as is done in
scm_equal_p. Remove useless code to check equality of
fractions with different SCM_CELL_TYPEs; this was for a
tentative "lazy reduction bit" which was never developed.
(scm_eqv_p, scm_equal_p): Remove useless code to check
equality between inexact reals and non-real complex numbers
with zero imaginary part. Such numbers do not exist,
because the current code is careful to never create them.
* test-suite/tests/numbers.test: Add test cases for
`eqv?' and `equal?'. Change existing test case for
`(equal? +nan.0 +nan.0)' to expect #t instead of #f.
* NEWS: Add NEWS entries.
2011-01-28 19:57:41 -05:00
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
switch (SCM_TYP7 (x))
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
{
|
`equal?' and `eqv?' are now equivalent for numbers
Change `equal?' to work like `eqv?' for numbers.
Previously they worked differently in some cases, e.g.
when comparing signed zeroes or NaNs. For example,
(equal? 0.0 -0.0) returned #t but (eqv? 0.0 -0.0)
returned #f, and (equal? +nan.0 +nan.0) returned #f
but (eqv? +nan.0 +nan.0) returned #t.
* libguile/numbers.c (scm_real_equalp, scm_bigequal,
scm_complex_equalp, scm_i_fraction_equalp): Move to eq.c.
* libguile/eq.c (scm_real_equalp): Compare flonums using
real_eqv instead of ==, so that NaNs are now considered
equal, and to distinguish signed zeroes.
(scm_complex_equalp): Compare real and imaginary
components using real_eqv instead of ==, so that NaNs are
now considered equal, and to distinguish signed zeroes.
(scm_bigequal): Use scm_i_bigcmp instead of duplicating it.
(real_eqv): Test for NaNs using isnan(x) instead of
(x != x), and use SCM_UNLIKELY for optimization.
(scm_eqv_p): Use scm_bigequal, scm_real_equalp,
scm_complex_equalp, and scm_i_fraction_equalp to compare
numbers, instead of inline code. Those predicates now do
what scm_eqv_p formerly did internally. Replace if
statements with switch statements, as is done in
scm_equal_p. Remove useless code to check equality of
fractions with different SCM_CELL_TYPEs; this was for a
tentative "lazy reduction bit" which was never developed.
(scm_eqv_p, scm_equal_p): Remove useless code to check
equality between inexact reals and non-real complex numbers
with zero imaginary part. Such numbers do not exist,
because the current code is careful to never create them.
* test-suite/tests/numbers.test: Add test cases for
`eqv?' and `equal?'. Change existing test case for
`(equal? +nan.0 +nan.0)' to expect #t instead of #f.
* NEWS: Add NEWS entries.
2011-01-28 19:57:41 -05:00
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case scm_tc7_number:
|
2018-05-08 11:49:46 +02:00
|
|
|
|
return scm_from_bool (scm_i_heap_numbers_equal_p (x, y));
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
}
|
2009-11-06 10:27:19 +01:00
|
|
|
|
return SCM_BOOL_F;
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_equal_p (SCM, SCM, SCM);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_PRIMITIVE_GENERIC (scm_i_equal_p, "equal?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
|
|
|
|
|
"Return @code{#t} if @var{x} and @var{y} are the same type, and\n"
|
|
|
|
|
|
"their contents or value are equal.\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"For a pair, string, vector or array, @code{equal?} compares the\n"
|
|
|
|
|
|
"contents, and does so using using the same @code{equal?}\n"
|
|
|
|
|
|
"recursively, so a deep structure can be traversed.\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"@example\n"
|
|
|
|
|
|
"(equal? (list 1 2 3) (list 1 2 3)) @result{} #t\n"
|
|
|
|
|
|
"(equal? (list 1 2 3) (vector 1 2 3)) @result{} #f\n"
|
|
|
|
|
|
"@end example\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"For other objects, @code{equal?} compares as per @code{eqv?},\n"
|
|
|
|
|
|
"which means characters and numbers are compared by type and\n"
|
|
|
|
|
|
"value (and like @code{eqv?}, exact and inexact numbers are not\n"
|
|
|
|
|
|
"@code{equal?}, even if their value is the same).\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"@example\n"
|
|
|
|
|
|
"(equal? 3 (+ 1 2)) @result{} #t\n"
|
|
|
|
|
|
"(equal? 1 1.0) @result{} #f\n"
|
|
|
|
|
|
"@end example\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"Hash tables are currently only compared as per @code{eq?}, so\n"
|
|
|
|
|
|
"two different tables are not @code{equal?}, even if their\n"
|
|
|
|
|
|
"contents are the same.\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"@code{equal?} does not support circular data structures, it may\n"
|
|
|
|
|
|
"go into an infinite loop if asked to compare two circular lists\n"
|
|
|
|
|
|
"or similar.\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"New application-defined object types (Smobs) have an\n"
|
|
|
|
|
|
"@code{equalp} handler which is called by @code{equal?}. This\n"
|
|
|
|
|
|
"lets an application traverse the contents or control what is\n"
|
|
|
|
|
|
"considered @code{equal?} for two such objects. If there's no\n"
|
|
|
|
|
|
"handler, the default is to just compare as per @code{eq?}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_equal_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!scm_is_true (scm_equal_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = SCM_CDR (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_equal_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_equal_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_equal_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
|
|
|
|
|
SCM_CHECK_STACK;
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
tailrecurse:
|
|
|
|
|
|
SCM_TICK;
|
2004-07-27 15:41:49 +00:00
|
|
|
|
if (scm_is_eq (x, y))
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
if (SCM_IMP (x))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
if (SCM_IMP (y))
|
|
|
|
|
|
return SCM_BOOL_F;
|
2004-09-22 17:41:37 +00:00
|
|
|
|
if (scm_is_pair (x) && scm_is_pair (y))
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
|
if (scm_is_false (scm_equal_p (SCM_CAR (x), SCM_CAR (y))))
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = SCM_CDR(x);
|
|
|
|
|
|
y = SCM_CDR(y);
|
|
|
|
|
|
goto tailrecurse;
|
|
|
|
|
|
}
|
2004-09-21 22:05:11 +00:00
|
|
|
|
if (SCM_TYP7 (x) == scm_tc7_smob && SCM_TYP16 (x) == SCM_TYP16 (y))
|
|
|
|
|
|
{
|
|
|
|
|
|
int i = SCM_SMOBNUM (x);
|
|
|
|
|
|
if (!(i < scm_numsmob))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
if (scm_smobs[i].equalp)
|
|
|
|
|
|
return (scm_smobs[i].equalp) (x, y);
|
|
|
|
|
|
else
|
|
|
|
|
|
goto generic_equal;
|
|
|
|
|
|
}
|
2010-09-23 10:55:24 +02:00
|
|
|
|
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
/* This ensures that types and scm_length are the same. */
|
2000-03-29 16:22:57 +00:00
|
|
|
|
if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
{
|
2006-05-29 21:54:13 +00:00
|
|
|
|
/* Vectors can be equal to one-dimensional arrays.
|
|
|
|
|
|
*/
|
2010-04-01 00:18:44 +02:00
|
|
|
|
if (scm_is_array (x) && scm_is_array (y))
|
2006-05-29 21:54:13 +00:00
|
|
|
|
return scm_array_equal_p (x, y);
|
|
|
|
|
|
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
switch (SCM_TYP7 (x))
|
|
|
|
|
|
{
|
|
|
|
|
|
default:
|
2011-02-10 19:38:49 -05:00
|
|
|
|
/* Check equality between structs of equal type (see cell-type test above). */
|
|
|
|
|
|
if (SCM_STRUCTP (x))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_INSTANCEP (x))
|
|
|
|
|
|
goto generic_equal;
|
|
|
|
|
|
else
|
|
|
|
|
|
return scm_i_struct_equalp (x, y);
|
|
|
|
|
|
}
|
2003-03-06 12:51:57 +00:00
|
|
|
|
break;
|
This set of patches introduces a new tc7 code scm_tc7_number for
numbers. Bignums, reals and complex numbers are turned from smobs
into subtypes of scm_tc7_number.
* tags.h (scm_tc7_number): New.
* eq.c (scm_equal_p), eval.c (SCM_CEVAL), evalext.c
(scm_self_evaluating_p), gc-card.c (scm_i_sweep_card), gc-mark.c
(scm_gc_mark_dependencies), goops.c (create_smob_classes), hash.c
(scm_hasher), numbers.c, numbers.h (SCM_NUMP), objects.c
(scm_class_of), print.c (scm_iprin1), smob.c
(scm_smob_prehistory): Don't handle bignums, reals and complex
numbers as subtypes of scm_tc7_smob any more.
* numbers.h, tags.h (scm_tc16_big, scm_tc16_real,
scm_tc16_complex): Moved definitions from tags.h to numbers.h.
2003-09-18 20:55:40 +00:00
|
|
|
|
case scm_tc7_number:
|
|
|
|
|
|
switch SCM_TYP16 (x)
|
|
|
|
|
|
{
|
|
|
|
|
|
case scm_tc16_big:
|
|
|
|
|
|
return scm_bigequal (x, y);
|
|
|
|
|
|
case scm_tc16_real:
|
|
|
|
|
|
return scm_real_equalp (x, y);
|
|
|
|
|
|
case scm_tc16_complex:
|
|
|
|
|
|
return scm_complex_equalp (x, y);
|
* print.c (scm_iprin1): Handle fractions.
* objects.h (scm_class_fraction): New.
* objects.c (scm_class_fraction): New.
(scm_class_of): Handle fractions.
* hash.c (scm_hasher): Handle fractions.
* numbers.c: New code for handling fraction all over the place.
(scm_odd_p, scm_even_p): Handle inexact integers.
(scm_rational_p): New function, same as scm_real_p.
(scm_round_number, scm_truncate_number, scm_ceiling, scm_floor):
New exact functions that replace the inexact 'dsubr'
implementations.
(scm_numerator, scm_denominator): New.
* numbers.h (SCM_NUMP): Recognize fractions.
(SCM_FRACTIONP, SCM_SLOPPY_FRACTIONP, SCM_FRACTION_NUMERATOR,
SCM_FRACTION_DENOMINATOR, SCM_FRACTION_SET_NUMERATOR,
SCM_FRACTION_SET_DENOMINATOR, SCM_FRACTION_REDUCED_BIT,
SCM_FRACTION_REDUCED_SET, SCM_FRACTION_REDUCED_CLEAR,
SCM_FRACTION_REDUCED): New.
(scm_floor, scm_ceiling, scm_truncate_number, scm_round_number):
New prototypes.
(scm_make_ratio, scm_rationalize, scm_numerator, scm_denominator,
scm_rational_p): New prototypes.
(scm_i_dbl2num, scm_i_fraction2double, scm_i_fraction_equalp,
scm_i_print_fraction): New prototypes.
* goops.c (create_standard_classes): Create "<fraction>" class.
* gc-mark.c (scm_gc_mark_dependencies): Handle fractions.
* gc-card.c (scm_i_sweep_card): Include scm_tc16_fraction as a
case in the switch, but do nothing for now.
* eval.c (SCM_CEVAL, SCM_APPLY, call_dsubr_1): Convert fractions
to doubles when calling 'dsubr' functions.
* eq.c (scm_eqv_p, scm_equal_p): Handle fractions.
2003-11-18 19:59:53 +00:00
|
|
|
|
case scm_tc16_fraction:
|
|
|
|
|
|
return scm_i_fraction_equalp (x, y);
|
2012-01-09 17:24:57 +01:00
|
|
|
|
default:
|
|
|
|
|
|
/* assert not reached? */
|
|
|
|
|
|
return SCM_BOOL_F;
|
This set of patches introduces a new tc7 code scm_tc7_number for
numbers. Bignums, reals and complex numbers are turned from smobs
into subtypes of scm_tc7_number.
* tags.h (scm_tc7_number): New.
* eq.c (scm_equal_p), eval.c (SCM_CEVAL), evalext.c
(scm_self_evaluating_p), gc-card.c (scm_i_sweep_card), gc-mark.c
(scm_gc_mark_dependencies), goops.c (create_smob_classes), hash.c
(scm_hasher), numbers.c, numbers.h (SCM_NUMP), objects.c
(scm_class_of), print.c (scm_iprin1), smob.c
(scm_smob_prehistory): Don't handle bignums, reals and complex
numbers as subtypes of scm_tc7_smob any more.
* numbers.h, tags.h (scm_tc16_big, scm_tc16_real,
scm_tc16_complex): Moved definitions from tags.h to numbers.h.
2003-09-18 20:55:40 +00:00
|
|
|
|
}
|
2012-01-09 17:24:57 +01:00
|
|
|
|
case scm_tc7_pointer:
|
|
|
|
|
|
return scm_from_bool (SCM_POINTER_VALUE (x) == SCM_POINTER_VALUE (y));
|
|
|
|
|
|
case scm_tc7_string:
|
|
|
|
|
|
return scm_string_equal_p (x, y);
|
|
|
|
|
|
case scm_tc7_bytevector:
|
|
|
|
|
|
return scm_bytevector_eq_p (x, y);
|
|
|
|
|
|
case scm_tc7_array:
|
|
|
|
|
|
return scm_array_equal_p (x, y);
|
2012-01-09 17:52:46 +01:00
|
|
|
|
case scm_tc7_bitvector:
|
|
|
|
|
|
return scm_i_bitvector_equal_p (x, y);
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
case scm_tc7_vector:
|
|
|
|
|
|
case scm_tc7_wvect:
|
(SCM_BITVEC_REF, SCM_BITVEC_SET, SCM_BITVEC_CLR): Removed.
(scm_vector_elements, scm_vector_writable_elements,
scm_generalized_vector_get_handle): Moved to vectors.[hc] from
unif.[hc].
(SCM_SIMPLE_VECTOR_LOC): Removed.
(SCM_VECTOR_MAX_LENGTH, SCM_VECTOR_LENGTH, SCM_VELTS,
SCM_WRITABLE_VELTS, SCM_VECTOR_REF, SCM_VECTOR_SET,
scm_vector_equal_p): Moved from vectors.[hc] to deprecated.[hc].
(scm_vector_equal_p, scm_i_vector_equal_p): Renamed former to
latter. Changed use in eq.c.
2005-01-07 15:44:09 +00:00
|
|
|
|
return scm_i_vector_equal_p (x, y);
|
2017-04-21 11:04:08 +02:00
|
|
|
|
case scm_tc7_syntax:
|
|
|
|
|
|
if (scm_is_false (scm_equal_p (scm_syntax_wrap (x),
|
|
|
|
|
|
scm_syntax_wrap (y))))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
if (scm_is_false (scm_equal_p (scm_syntax_module (x),
|
|
|
|
|
|
scm_syntax_module (y))))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = scm_syntax_expression (x);
|
|
|
|
|
|
y = scm_syntax_expression (y);
|
|
|
|
|
|
goto tailrecurse;
|
* __scm.h eq.c, eval.c, gc.c, hc.h, gh_data, hash.c, numbers.c,
numbers.h, objects.c, ramap.c, random.c, unif.c, unif.h: Extensive
rewrite of handling of real and complex numbers.
(SCM_FLOATS, SCM_SINGLES): These #ifdef conditionals have been
removed along with the support for floats. (Float vectors are
still supported.)
2000-03-14 06:43:03 +00:00
|
|
|
|
}
|
2006-06-13 07:48:42 +00:00
|
|
|
|
|
2009-11-06 10:27:19 +01:00
|
|
|
|
/* Otherwise just return false. Dispatching to the generic is the wrong thing
|
|
|
|
|
|
here, as we can hit this case for any two objects of the same type that we
|
|
|
|
|
|
think are distinct, like different symbols. */
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
|
2004-09-21 22:05:11 +00:00
|
|
|
|
generic_equal:
|
2009-12-04 13:05:00 +01:00
|
|
|
|
if (SCM_UNPACK (g_scm_i_equal_p))
|
scm_wta_* procedures replace SCM_WTA_* macros
* libguile/__scm.h: Move all the SCM_WTA and SCM_GASSERT macros out of
here. Also remove the scm_call_generic declarations.
* libguile/deprecated.h (SCM_WTA_DISPATCH_0, SCM_WTA_DISPATCH_1):
(SCM_WTA_DISPATCH_2, SCM_WTA_DISPATCH_N): Deprecate. See below for
their replacements.
(SCM_GASSERT0, SCM_GASSERT1, SCM_GASSERT2, SCM_GASSERTn): Deprecate
these too.
(SCM_WTA_DISPATCH_1_SUBR): Deprecate this strange thing.
(scm_call_generic_0, scm_call_generic_1, scm_call_generic_2):
(scm_call_generic_3, scm_apply_generic): Remove, indicating their
replacements.
* libguile/print.c (iprin1):
* libguile/eq.c (scm_equal_p): Use scm_call_2 instead of
scm_call_generic_2.
* libguile/goops.h:
* libguile/goops.c: Remove scm_{call,apply}_generic definitions.
(scm_wta_dispatch_0, scm_wta_dispatch_1, scm_wta_dispatch_2):
(scm_wta_dispatch_n): New procedures, replacing the SCM_WTA macros.
* libguile/numbers.c (scm_lcm):
* libguile/procs.c (scm_setter): Remove uses of SCM_GASSERT.
* libguile/numbers.c (scm_lcm):
* libguile/procs.c (scm_setter):
* libguile/vectors.c: Use the procedural scm_wta routines instead of the
SCM_WTA macros.
2011-05-15 15:18:18 +02:00
|
|
|
|
return scm_call_2 (g_scm_i_equal_p, x, y);
|
2003-03-06 12:51:57 +00:00
|
|
|
|
else
|
|
|
|
|
|
return SCM_BOOL_F;
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* __scm.h, alist.c, alist.h, append.c, append.h, appinit.c,
arbiters.c, arbiters.h, async.c, async.h, boolean.c, boolean.h,
chars.c, chars.h, continuations.c, continuations.h, debug.c,
debug.h, dynwind.c, dynwind.h, eq.c, eq.h, error.c, eval.c,
eval.h, extchrs.c, extchrs.h, fdsocket.c, fdsocket.h, filesys.c,
filesys.h, fports.c, fports.h, gc.c, gdb_interface.h, gdbint.c,
gdbint.h, genio.c, genio.h, gscm.c, gscm.h, gsubr.c, gsubr.h,
hash.c, hash.h, hashtab.c, hashtab.h, init.c, ioext.c, ioext.h,
kw.c, kw.h, libguile.h, mallocs.c, mallocs.h, markers.c,
markers.h, mbstrings.c, mbstrings.h, numbers.c, numbers.h,
objprop.c, objprop.h, options.c, options.h, pairs.c, pairs.h,
ports.c, ports.h, posix.c, posix.h, print.c, print.h, procprop.c,
procprop.h, procs.c, procs.h, ramap.c, ramap.h, read.c, read.h,
root.c, scmsigs.c, scmsigs.h, sequences.c, sequences.h, simpos.c,
simpos.h, smob.c, socket.c, socket.h, srcprop.c, srcprop.h,
stackchk.c, stackchk.h, stime.c, stime.h, strings.c, strings.h,
strop.c, strop.h, strorder.c, strorder.h, strports.c, strports.h,
struct.c, struct.h, symbols.c, symbols.h, tag.c, tag.h, unif.c,
unif.h, variable.c, variable.h, vectors.c, vectors.h, version.c,
version.h, vports.c, vports.h, weaks.c, weaks.h: Use SCM_P to
declare functions with prototypes. (Patch thanks to Marius
Vollmer.)
1996-10-14 01:33:50 +00:00
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
void
|
|
|
|
|
|
scm_init_eq ()
|
|
|
|
|
|
{
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "eq.x"
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|