From 958dcc76c1aa5b0a602e4107821677a8ad75eb5e Mon Sep 17 00:00:00 2001 From: Jorge Tavares Date: Mon, 8 Mar 2010 00:17:46 +0100 Subject: [PATCH] bug fix: FIND / POSITION on lists signal bounding-indices-bad-error (bug #452008) --- src/compiler/seqtran.lisp | 69 +++++++++++++++++++++++---------------------- 1 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/compiler/seqtran.lisp b/src/compiler/seqtran.lisp index a960a16..2a53bf0 100644 --- a/src/compiler/seqtran.lisp +++ b/src/compiler/seqtran.lisp @@ -1195,41 +1195,42 @@ * :policy (> speed space)) "expand inline" - `(let ((index 0) - (find nil) + `(let ((find nil) (position nil)) - (declare (type index index)) - (if (and end (or (> start end) - (> end (length sequence)))) - (sequence-bounding-indices-bad-error - sequence start end) - (dolist (i sequence (values find position)) - (when (and end (>= index end)) - (return (values find position))) - (when (>= index start) - (let ((key-i (funcall key i))) - (,',condition (funcall predicate key-i) - ;; This hack of dealing with non-NIL - ;; FROM-END for list data by iterating - ;; forward through the list and keeping - ;; track of the last time we found a - ;; match might be more screwy than what - ;; the user expects, but it seems to be - ;; allowed by the ANSI standard. (And - ;; if the user is screwy enough to ask - ;; for FROM-END behavior on list data, - ;; turnabout is fair play.) - ;; - ;; It's also not enormously efficient, - ;; calling PREDICATE and KEY more often - ;; than necessary; but all the - ;; alternatives seem to have their own - ;; efficiency problems. - (if from-end - (setf find i - position index) - (return (values i index)))))) - (incf index))))))) + (if (and end (> start end)) + (sequence-bounding-indices-bad-error sequence start end) + (do ((list sequence (rest list)) + (index 0 (+ index 1))) + ((or (null list) (and end (> index end))) + (if (and end (> end index)) + (sequence-bounding-indices-bad-error sequence start end) + (return (values find position)))) + (let ((element (first list))) + (when (>= index start) + (let ((key-i (funcall key element))) + (,',condition (funcall predicate key-i) + ;; This hack of dealing with non-NIL + ;; FROM-END for list data by iterating + ;; forward through the list and keeping + ;; track of the last time we found a + ;; match might be more screwy than what + ;; the user expects, but it seems to be + ;; allowed by the ANSI standard. (And + ;; if the user is screwy enough to ask + ;; for FROM-END behavior on list data, + ;; turnabout is fair play.) + ;; + ;; It's also not enormously efficient, + ;; calling PREDICATE and KEY more often + ;; than necessary; but all the + ;; alternatives seem to have their own + ;; efficiency problems. + (if from-end + (setf find element + position index) + (unless find + (setf find element + position index))))))))))))) (def %find-position-if when) (def %find-position-if-not unless)) -- 1.6.5.7