0.8.5.28:
authorChristophe Rhodes <csr21@cam.ac.uk>
Sun, 9 Nov 2003 13:35:30 +0000 (13:35 +0000)
committerChristophe Rhodes <csr21@cam.ac.uk>
Sun, 9 Nov 2003 13:35:30 +0000 (13:35 +0000)
Fix some loop badness (as reported by John Klein sbcl-devel
2003-11-09)
... step variable guessed initializers should be 1, not 0,
because the step type explicitly excludes 0.
... log some more loop badness in BUGS

BUGS
src/code/loop.lisp
tests/loop.pure.lisp
version.lisp-expr

diff --git a/BUGS b/BUGS
index b2198f0..fed7fc3 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -1190,3 +1190,12 @@ WORKAROUND:
   argument.  As a result, files with Lisp pathname pattern characters
   (#\* or #\?, for instance) or quotation marks can cause the system
   to perform arbitrary behaviour.
+
+297:
+  LOOP with non-constant arithmetic step clauses suffers from overzealous
+  type constraint: code of the form 
+    (loop for d of-type double-float from 0d0 to 10d0 by x collect d)
+  compiles to a type restriction on X of (AND DOUBLE-FLOAT (REAL
+  (0))).  However, an integral value of X should be legal, because
+  successive adds of integers to double-floats produces double-floats,
+  so none of the type restrictions in the code is violated.
index 2a5eba4..acabbf6 100644 (file)
@@ -928,12 +928,12 @@ code to be loaded.
 \f
 ;;;; loop types
 
-(defun loop-typed-init (data-type)
+(defun loop-typed-init (data-type &optional step-var-p)
   (when (and data-type (sb!xc:subtypep data-type 'number))
     (if (or (sb!xc:subtypep data-type 'float)
            (sb!xc:subtypep data-type '(complex float)))
-       (coerce 0 data-type)
-       0)))
+       (coerce (if step-var-p 1 0) data-type)
+       (if step-var-p 1 0))))
 
 (defun loop-optional-type (&optional variable)
   ;; No variable specified implies that no destructuring is permissible.
@@ -1024,7 +1024,7 @@ code to be loaded.
       ((null entry) (return nil))
       ((assoc name (caar entry) :test #'eq) (return t)))))
 
-(defun loop-make-var (name initialization dtype &optional iteration-var-p)
+(defun loop-make-var (name initialization dtype &optional iteration-var-p step-var-p)
   (cond ((null name)
         (setq name (gensym "LOOP-IGNORE-"))
         (push (list name initialization) *loop-vars*)
@@ -1041,10 +1041,10 @@ code to be loaded.
                            name)))
         (unless (symbolp name)
           (loop-error "bad variable ~S somewhere in LOOP" name))
-        (loop-declare-var name dtype)
+        (loop-declare-var name dtype step-var-p)
         ;; We use ASSOC on this list to check for duplications (above),
         ;; so don't optimize out this list:
-        (push (list name (or initialization (loop-typed-init dtype)))
+        (push (list name (or initialization (loop-typed-init dtype step-var-p)))
               *loop-vars*))
        (initialization
         (let ((newvar (gensym "LOOP-DESTRUCTURE-")))
@@ -1063,11 +1063,11 @@ code to be loaded.
 (defun loop-make-iteration-var (name initialization dtype)
   (loop-make-var name initialization dtype t))
 
-(defun loop-declare-var (name dtype)
+(defun loop-declare-var (name dtype &optional step-var-p)
   (cond ((or (null name) (null dtype) (eq dtype t)) nil)
        ((symbolp name)
         (unless (sb!xc:subtypep t dtype)
-          (let ((dtype (let ((init (loop-typed-init dtype)))
+          (let ((dtype (let ((init (loop-typed-init dtype step-var-p)))
                          (if (sb!xc:typep init dtype)
                              dtype
                              `(or (member ,init) ,dtype)))))
@@ -1700,7 +1700,7 @@ code to be loaded.
         (limit-value nil)
         )
      (flet ((assert-index-for-arithmetic (index)
-             (unless (atom indexv)
+             (unless (atom index)
                (loop-error "Arithmetic index must be an atom."))))
        (when variable (loop-make-iteration-var variable nil variable-type))
        (do ((l prep-phrases (cdr l)) (prep) (form) (odir)) ((null l))
@@ -1742,7 +1742,8 @@ code to be loaded.
            (unless stepby-constantp
              (loop-make-var (setq stepby (gensym "LOOP-STEP-BY-"))
                 form
-                `(and ,indexv-type (real (0))))))
+                `(and ,indexv-type (real (0)))
+                nil t)))
           (t (loop-error
                 "~S invalid preposition in sequencing or sequence path;~@
              maybe invalid prepositions were specified in iteration path descriptor?"
index 8d4146e..febf5a7 100644 (file)
             `(lambda ()
                (loop for (i j) to 6 collect nil)))
   (assert failure-p))
+
+(assert
+ (equal
+  (let ((x 2d0))
+    (loop for d of-type double-float from 0d0 to 10d0 by x collect d))
+  '(0d0 2d0 4d0 6d0 8d0 10d0)))
+(assert
+ (equal
+  (let ((x 2d0))
+    (loop for d of-type double-float downfrom 10d0 to 0d0 by x collect d))
+  '(10d0 8d0 6d0 4d0 2d0 0d0)))
index c306c27..a681f34 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.5.27"
+"0.8.5.28"