From 7f321020769583880612fe291367b0141a88ab2a Mon Sep 17 00:00:00 2001 From: Christophe Rhodes Date: Sun, 9 Nov 2003 13:35:30 +0000 Subject: [PATCH] 0.8.5.28: 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 | 9 +++++++++ src/code/loop.lisp | 21 +++++++++++---------- tests/loop.pure.lisp | 11 +++++++++++ version.lisp-expr | 2 +- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/BUGS b/BUGS index b2198f0..fed7fc3 100644 --- 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. diff --git a/src/code/loop.lisp b/src/code/loop.lisp index 2a5eba4..acabbf6 100644 --- a/src/code/loop.lisp +++ b/src/code/loop.lisp @@ -928,12 +928,12 @@ code to be loaded. ;;;; 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?" diff --git a/tests/loop.pure.lisp b/tests/loop.pure.lisp index 8d4146e..febf5a7 100644 --- a/tests/loop.pure.lisp +++ b/tests/loop.pure.lisp @@ -203,3 +203,14 @@ `(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))) diff --git a/version.lisp-expr b/version.lisp-expr index c306c27..a681f34 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -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" -- 1.7.10.4