[uim-commit] r2807 - in branches/r5rs/sigscheme: . test

yamaken at freedesktop.org yamaken at freedesktop.org
Fri Jan 6 07:43:17 PST 2006


Author: yamaken
Date: 2006-01-06 07:43:13 -0800 (Fri, 06 Jan 2006)
New Revision: 2807

Modified:
   branches/r5rs/sigscheme/operations-nonstd.c
   branches/r5rs/sigscheme/operations.c
   branches/r5rs/sigscheme/sigscheme.h
   branches/r5rs/sigscheme/sigschemeinternal.h
   branches/r5rs/sigscheme/test/test-list.scm
Log:
* sigscheme/sigschemeinternal.h
  - (SCM_LISTLEN_PROPERP, SCM_LISTLEN_DOT): New macro
* sigscheme/operations.c
  - (LISTLEN_ENCODE_DOT): Revert r2802
  - (scm_length):
    * Return -1 for non-list, as zero length improper list, as
      originally intended
    * Fix the bug fixed in r2802, but as originally intended
* sigscheme/sigscheme.h
  - (scm_p_lengthstar): New function decl
* sigscheme/operations-nonstd.c
  - (scm_p_lengthstar): New function
* sigscheme/test/test-list.scm
  - Add tests for length*


Modified: branches/r5rs/sigscheme/operations-nonstd.c
===================================================================
--- branches/r5rs/sigscheme/operations-nonstd.c	2006-01-06 13:55:30 UTC (rev 2806)
+++ branches/r5rs/sigscheme/operations-nonstd.c	2006-01-06 15:43:13 UTC (rev 2807)
@@ -241,3 +241,22 @@
 
     return SCM_TRUE;
 }
+
+/* to avoid being typo of length+, this procedure did not name as length++ */
+/* FIXME: replace with a SRFI or de facto standard equivalent if exist */
+ScmObj
+scm_p_lengthstar(ScmObj lst)
+{
+    int len;
+    DECLARE_FUNCTION("length*", procedure_fixed_1);
+
+    len = scm_length(lst);
+    if (!SCM_LISTLEN_PROPERP(len)) { /* make fast path for proper list */
+        if (SCM_LISTLEN_DOTP(len))
+            len = -SCM_LISTLEN_DOT(len);
+        else if (SCM_LISTLEN_CIRCULARP(len))
+            return SCM_FALSE;
+    }
+
+    return MAKE_INT(len);
+}

Modified: branches/r5rs/sigscheme/operations.c
===================================================================
--- branches/r5rs/sigscheme/operations.c	2006-01-06 13:55:30 UTC (rev 2806)
+++ branches/r5rs/sigscheme/operations.c	2006-01-06 15:43:13 UTC (rev 2807)
@@ -808,13 +808,14 @@
  * 2006-01-05 YamaKen  Return dot list length and circular indication.
  *
  */
+/* Returns -1 for non-list, as zero length improper list. */
 int
 scm_length(ScmObj lst)
 {
     ScmObj slow;
     int len;
 
-#define LISTLEN_ENCODE_DOT(len)      (-(len)-1)
+#define LISTLEN_ENCODE_DOT(len)      (-(len))
 #define LISTLEN_ENCODE_CIRCULAR(len) (INT_MIN)
 
     slow = lst;
@@ -822,13 +823,13 @@
 
     for (;;) {
         if (NULLP(lst)) break;
-        if (!CONSP(lst)) return LISTLEN_ENCODE_DOT(len);
+        if (!CONSP(lst)) return LISTLEN_ENCODE_DOT(len + 1);
         if (len != 0 && lst == slow) return LISTLEN_ENCODE_CIRCULAR(len);
 
         lst = CDR(lst);
         len++;
         if (NULLP(lst)) break;
-        if (!CONSP(lst)) return LISTLEN_ENCODE_DOT(len);
+        if (!CONSP(lst)) return LISTLEN_ENCODE_DOT(len + 1);
         if (lst == slow) return LISTLEN_ENCODE_CIRCULAR(len);
 
         lst = CDR(lst);

Modified: branches/r5rs/sigscheme/sigscheme.h
===================================================================
--- branches/r5rs/sigscheme/sigscheme.h	2006-01-06 13:55:30 UTC (rev 2806)
+++ branches/r5rs/sigscheme/sigscheme.h	2006-01-06 15:43:13 UTC (rev 2807)
@@ -928,6 +928,7 @@
 ScmObj scm_p_providedp(ScmObj feature);
 ScmObj scm_p_file_existsp(ScmObj filepath);
 ScmObj scm_p_delete_file(ScmObj filepath);
+ScmObj scm_p_lengthstar(ScmObj lst);
 #endif
 
 /* io.c */

Modified: branches/r5rs/sigscheme/sigschemeinternal.h
===================================================================
--- branches/r5rs/sigscheme/sigschemeinternal.h	2006-01-06 13:55:30 UTC (rev 2806)
+++ branches/r5rs/sigscheme/sigschemeinternal.h	2006-01-06 15:43:13 UTC (rev 2807)
@@ -38,6 +38,7 @@
    System Include
 =======================================*/
 #include <limits.h>
+#include <stdlib.h>
 #include <stdarg.h>
 
 /*=======================================
@@ -348,9 +349,11 @@
 #define SCM_ERR_HEADER "Error: "
 
 /* result decoders for scm_length() */
+#define SCM_LISTLEN_PROPERP(len)     (0 <= (len))
 #define SCM_LISTLEN_CIRCULARP(len)   ((len) == INT_MIN)
 #define SCM_LISTLEN_DOTP(len)        ((len) < 0                              \
                                       && !SCM_LISTLEN_CIRCULARP(len))
+#define SCM_LISTLEN_DOT(len)         (abs(len))
 #define SCM_LISTLEN_BEFORE_DOT(len)  (~(len))  /* abs(len) - 1 */
 
 /*=======================================

Modified: branches/r5rs/sigscheme/test/test-list.scm
===================================================================
--- branches/r5rs/sigscheme/test/test-list.scm	2006-01-06 13:55:30 UTC (rev 2806)
+++ branches/r5rs/sigscheme/test/test-list.scm	2006-01-06 15:43:13 UTC (rev 2807)
@@ -32,6 +32,7 @@
 
 (load "test/unittest.scm")
 
+(define tn test-name)
 
 (define elm0 (lambda () #f))
 (define elm1 (lambda () #f))
@@ -146,4 +147,33 @@
 ; assoc
 (assert-equal? "assoc test1" '((a)) (assoc (list 'a) '(((a)) ((b)) ((c)))))
 
+(if (provided? "sigscheme")
+    (begin
+      (use sscm)
+      (tn "length* proper list")
+      (assert-equal? (tn) 0 (length* '()))
+      (assert-equal? (tn) 1 (length* '(1)))
+      (assert-equal? (tn) 2 (length* '(1 2)))
+      (assert-equal? (tn) 3 (length* '(1 2 3)))
+      (assert-equal? (tn) 4 (length* '(1 2 3 4)))
+      (tn "length* improper list")
+      (assert-equal? (tn) -1 (length* 1))
+      (assert-equal? (tn) -2 (length* '(1 . 2)))
+      (assert-equal? (tn) -3 (length* '(1 2 . 3)))
+      (assert-equal? (tn) -4 (length* '(1 2 3 . 4)))
+      (assert-equal? (tn) -5 (length* '(1 2 3 4 . 5)))
+      (tn "length* circular list")
+      (define lst1 '(1))
+      (set-cdr! lst1 lst1)
+      (define lst2 '(1 2))
+      (set-cdr! (list-tail lst2 1) lst2)
+      (define lst3 '(1 2 3))
+      (set-cdr! (list-tail lst3 2) lst3)
+      (define lst4 '(1 2 3 4))
+      (set-cdr! (list-tail lst4 3) lst4)
+      (assert-false (tn) (length* lst1))
+      (assert-false (tn) (length* lst2))
+      (assert-false (tn) (length* lst3))
+      (assert-false (tn) (length* lst4))))
+
 (total-report)



More information about the uim-commit mailing list