X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/lisp/blobdiff_plain/2af61873236491d221b3cbd8bbab4320a2beb7f4..28a5e53109f67f9ed97af095baa95fd360ed9e68:/collect.lisp diff --git a/collect.lisp b/collect.lisp index 359780c..cab2808 100644 --- a/collect.lisp +++ b/collect.lisp @@ -25,15 +25,26 @@ (defpackage #:collect (:use #:common-lisp #:mdw.base) - (:export #:collecting #:with-collection #:collect #:collect-tail)) + (:export #:make-collector #:collected + #:collecting #:with-collection + #:collect #:collect-tail + #:collect-append #:collect-nconc)) (in-package collect) (eval-when (:compile-toplevel :load-toplevel) (defvar *collecting-anon-list-name* (gensym) - "The default name for anonymous `collecting' lists.") - (defun make-collector () - (let ((head (cons nil nil))) - (setf (car head) head)))) + "The default name for anonymous `collecting' lists.")) + +(defun make-collector (&optional list) + "Return a new collector object whose initial contents is LIST. Note that + LIST will be destroyed if anything else is collected." + (let ((head (cons nil list))) + (setf (car head) (if list (last list) head)))) + +(defmacro collected (&optional (name *collecting-anon-list-name*)) + "Return the current list collected into the collector NAME (or + *collecting-anon-list-name* by default)." + `(the list (cdr ,name))) (defmacro collecting (vars &body body) "Collect items into lists. The VARS are a list of collection variables -- @@ -45,7 +56,7 @@ (defmacro collecting (vars &body body) ((atom vars) (setf vars (list vars)))) `(let ,(mapcar (lambda (v) `(,v (make-collector))) vars) ,@body - (values ,@(mapcar (lambda (v) `(the list (cdr ,v))) vars)))) + (values ,@(mapcar (lambda (v) `(collected ,v)) vars)))) (defmacro with-collection (vars collection &body body) "Collect items into lists VARS according to the form COLLECTION; then