~ chicken-core (chicken-5) 4d923a24c807c2a28a8f7569dbf4d77e5ec9c8f4
commit 4d923a24c807c2a28a8f7569dbf4d77e5ec9c8f4
Author: felix <felix@call-with-current-continuation.org>
AuthorDate: Fri Nov 19 06:04:33 2010 -0500
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Fri Nov 19 06:04:33 2010 -0500
added equal=?
diff --git a/chicken.h b/chicken.h
index eb271468..0167fd16 100644
--- a/chicken.h
+++ b/chicken.h
@@ -1041,6 +1041,7 @@ extern double trunc(double);
#define C_specialp(x) C_mk_bool(C_header_bits(x) & C_SPECIALBLOCK_BIT)
#define C_byteblockp(x) C_mk_bool(C_header_bits(x) & C_BYTEBLOCK_BIT)
#define C_anyp(x) C_SCHEME_TRUE
+#define C_sametypep(x, y) C_mk_bool(C_header_bits(x) == C_header_bits(y))
#define C_eqp(x, y) C_mk_bool((x) == (y))
#define C_vemptyp(x) C_mk_bool(C_header_size(x) == 0)
#define C_notvemptyp(x) C_mk_bool(C_header_size(x) > 0)
diff --git a/library.scm b/library.scm
index 764c6fc0..85aa1a50 100644
--- a/library.scm
+++ b/library.scm
@@ -1071,6 +1071,44 @@ EOF
(##core#inline "C_set_print_precision" prec) )
prev ) )
+(define (equal=? x y)
+ (define (compare-slots x y start)
+ (let ((l1 (##sys#size x))
+ (l2 (##sys#size y)))
+ (and (eq? l1 l2)
+ (or (fx<= l1 start)
+ (let ((l1n (fx- l1 1)))
+ (let loop ((i start))
+ (if (fx= i l1n)
+ (walk (##sys#slot x i) (##sys#slot y i)) ; tailcall
+ (and (walk (##sys#slot x i) (##sys#slot y i))
+ (loop (fx+ i 1))))))))))
+ (define (walk x y)
+ (cond ((eq? x y))
+ ((fixnum? x)
+ (if (flonum? y)
+ (= x y)
+ (eq? x y)))
+ ((flonum? x)
+ (and (or (fixnum? y) (flonum? y))
+ (= x y)))
+ ((not (##core#inline "C_blockp" x)) #f)
+ ((not (##core#inline "C_blockp" y)) #f)
+ ((not (##core#inline "C_sametypep" x y)) #f)
+ ((##core#inline "C_specialp" x)
+ (and (##core#inline "C_specialp" y)
+ (compare-slots x y 1)))
+ ((##core#inline "C_byteblockp" x)
+ (and (##core#inline "C_byteblockp" y)
+ (let ((s1 (##sys#size x)))
+ (and (eq? s1 (##sys#size y))
+ (##core#inline "C_substring_compare" x y 0 0 s1)))))
+ (else
+ (let ((s1 (##sys#size x)))
+ (and (eq? s1 (##sys#size y))
+ (compare-slots x y 0))))))
+ (walk x y))
+
;;; Symbols:
diff --git a/manual/Unit library b/manual/Unit library
index dabf11cc..e807986d 100644
--- a/manual/Unit library
+++ b/manual/Unit library
@@ -3,9 +3,13 @@
== Unit library
-This unit contains basic Scheme definitions. This unit is used by default,
+This unit contains basic library definitions. This unit is used by default,
unless the program is compiled with the {{-explicit-use}} option.
+In addition to standard Scheme functions, this unit provides quite
+a number of additional operations.
+
+
=== Arithmetic
@@ -568,6 +572,8 @@ On a UNIX system, that value is the raw return value of waitpid(2), which contai
#t
42
</enscript>
+
+
=== Execution time
@@ -690,13 +696,6 @@ Displays a warning message (if warnings are enabled with {{enable-warnings}}) an
continues execution.
-==== singlestep
-
-<procedure>(singlestep THUNK)</procedure>
-
-Executes the code in the zero-procedure {{THUNK}} in single-stepping mode.
-
-
=== Garbage collection
@@ -749,7 +748,7 @@ switches statistics off.
-=== Other control structures
+=== Other predicates and comparison operations
@@ -761,6 +760,15 @@ Returns {{#t}} if {{X}} is a promise returned by {{delay}}, or
{{#f}} otherwise.
+==== equal=?
+
+<procedure>(equal=? X y)</procedure>
+
+Similar to the standard parocedure {{equal?}}, but compares numbers
+using the {{=}} operator, so {{equal=?}} allows structural comparison
+in combination with comparison of numerical data by value.
+
+
=== String utilities
diff --git a/tests/library-tests.scm b/tests/library-tests.scm
index a41dc61f..01974bac 100644
--- a/tests/library-tests.scm
+++ b/tests/library-tests.scm
@@ -170,3 +170,20 @@
(assert (= 12 (bar 3)))
(assert (= 100 (set! (bar) 1)))
(assert (= 12 (foo 3)))
+
+
+;;; equal=?
+
+(assert (not (equal=? 1 2)))
+(assert (equal=? 1 1))
+(assert (equal=? 1 1.0))
+(assert (not (equal=? 1 1.2)))
+(assert (equal=? 1.0 1))
+(assert (equal=? '#(1) '#(1.0)))
+(assert (not (equal=? 'a "a")))
+(assert (equal=? "abc" "abc"))
+(assert (equal=? '(1 2.0 3) '(1 2 3)))
+(assert (equal=? '#(1 2.0 3) '#(1 2 3)))
+(assert (equal=? '#(1 2 (3)) '#(1 2 (3))))
+(assert (not (equal=? '#(1 2 (4)) '#(1 2 (3)))))
+(assert (not (equal=? 123 '(123))))
Trap