[movitz-cvs] CVS movitz/losp/muerte
ffjeld
ffjeld at common-lisp.net
Tue Mar 21 20:23:44 UTC 2006
Update of /project/movitz/cvsroot/movitz/losp/muerte
In directory clnet:/tmp/cvs-serv3459
Modified Files:
sequences.lisp
Log Message:
Wrote substitute and nsubstitute.
--- /project/movitz/cvsroot/movitz/losp/muerte/sequences.lisp 2005/08/24 07:28:59 1.27
+++ /project/movitz/cvsroot/movitz/losp/muerte/sequences.lisp 2006/03/21 20:23:42 1.28
@@ -10,7 +10,7 @@
;;;; Author: Frode Vatvedt Fjeld <frodef at acm.org>
;;;; Created at: Tue Sep 11 14:19:23 2001
;;;;
-;;;; $Id: sequences.lisp,v 1.27 2005/08/24 07:28:59 ffjeld Exp $
+;;;; $Id: sequences.lisp,v 1.28 2006/03/21 20:23:42 ffjeld Exp $
;;;;
;;;;------------------------------------------------------------------
@@ -1736,4 +1736,135 @@
r))
(t (error "Can't concatenate ~S yet: ~:S" result-type sequences))))
-
+(defun substitute (newitem olditem sequence &rest args
+ &key (test 'eql) test-not (start 0) end count (key 'identity) from-end)
+ (declare (dynamic-extent args))
+ "=> result-sequence"
+ (when test-not
+ (setf test (complement test-not)))
+ (with-funcallable (test)
+ (with-funcallable (key)
+ (sequence-dispatch sequence
+ (vector
+ (apply #'nsubstitute newitem olditem (copy-seq sequence) args))
+ (list
+ (if from-end
+ (nreverse (nsubstitute newitem olditem (reverse sequence)
+ :test test :test-not test-not
+ :start start :end end
+ :count count :key key))
+ (let ((sequence (nthcdr start sequence)))
+ (if (or (null sequence)
+ (and end (<= end start)))
+ nil
+ (let ((new-list (list #0=(let ((x (pop sequence)))
+ (if (test olditem (key x))
+ newitem
+ x)))))
+ (cond
+ ((and (not end) (not count))
+ (do ((new-tail new-list (cdr new-tail)))
+ ((endp sequence) new-list)
+ (setf (cdr new-tail) (list #0#))))
+ ((and end (not count))
+ (do ((i (- end start) (1- i))
+ (new-tail new-list (cdr new-tail)))
+ ((or (endp sequence) (<= i 0)) new-list)
+ (setf (cdr new-tail) (list #0#))))
+ ((and (not end) count)
+ (do ((c 0)
+ (new-tail new-list (cdr new-tail)))
+ ((or (endp sequence) (>= c count))
+ (setf (cdr new-tail)
+ (copy-list sequence))
+ new-list)
+ (setf (cdr new-tail) #1=(list (let ((x (pop sequence)))
+ (if (test olditem (key x))
+ (progn (incf c) newitem)
+ x))))))
+ ((and end count)
+ (do ((i (- end start) (1- i))
+ (c 0)
+ (new-tail new-list (cdr new-tail)))
+ ((or (endp sequence) (<= i 0) (>= c count))
+ (setf (cdr new-tail)
+ (copy-list sequence))
+ new-list)
+ (setf (cdr new-tail) #1#)))
+ ((error 'program-error))))))))))))
+
+(defun nsubstitute (newitem olditem sequence &key (test 'eql) test-not (start 0) end count (key 'identity) from-end)
+ "=> sequence"
+ (when test-not
+ (setf test (complement test-not)))
+ (with-funcallable (test)
+ (with-funcallable (key)
+ (sequence-dispatch sequence
+ (vector
+ (let ((end (or end (length sequence))))
+ (with-subvector-accessor (ref sequence start end)
+ (cond
+ ((and (not count) (not from-end))
+ (do ((i start (1+ i)))
+ ((>= i end) sequence)
+ (when (test olditem (key (ref i)))
+ (setf (ref i) newitem))))
+ ((and count (not from-end))
+ (do ((c 0)
+ (i start (1+ i)))
+ ((>= i end) sequence)
+ (when (test olditem (key (ref i)))
+ (setf (ref i) newitem)
+ (when (>= (incf c) count)
+ (return sequence)))))
+ ((and (not count) from-end)
+ (do ((i (1- end) (1- i)))
+ ((< i start) sequence)
+ (when (test olditem (key (ref i)))
+ (setf (ref i) newitem))))
+ ((and count from-end)
+ (do ((c 0)
+ (i (1- end) (1- i)))
+ ((< i start) sequence)
+ (when (test olditem (key (ref i)))
+ (setf (ref i) newitem)
+ (when (>= (incf c) count)
+ (return sequence)))))
+ ((error 'program-error))))))
+ (list
+ (if from-end
+ (nreverse (nsubstitute newitem olditem (nreverse sequence)
+ :test test :test-not test-not
+ :start start :end end
+ :count count :key key))
+ (let ((p (nthcdr start sequence)))
+ (cond
+ ((and (not end) (not count))
+ (do ((p p (cdr p)))
+ ((endp p) sequence)
+ (when (test olditem (key (car p)))
+ (setf (car p) newitem))))
+ ((and end (not count))
+ (do ((i start (1+ i))
+ (p p (cdr p)))
+ ((or (endp p) (>= i end)) sequence)
+ (when (test olditem (key (car p)))
+ (setf (car p) newitem))))
+ ((and (not end) count)
+ (do ((c 0)
+ (p p (cdr p)))
+ ((endp p) sequence)
+ (when (test olditem (key (car p)))
+ (setf (car p) newitem)
+ (when (>= (incf c) count)
+ (return sequence)))))
+ ((and end count)
+ (do ((c 0)
+ (i start (1+ i))
+ (p p (cdr p)))
+ ((or (endp p) (>= i end)) sequence)
+ (when (test olditem (key (car p)))
+ (setf (car p) newitem)
+ (when (>= (incf c) count)
+ (return sequence)))))
+ ((error 'program-error))))))))))
More information about the Movitz-cvs
mailing list