3 ;; JSCL is free software: you can redistribute it and/or
4 ;; modify it under the terms of the GNU General Public License as
5 ;; published by the Free Software Foundation, either version 3 of the
6 ;; License, or (at your option) any later version.
8 ;; JSCL is distributed in the hope that it will be useful, but
9 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
10 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 ;; General Public License for more details.
13 ;; You should have received a copy of the GNU General Public License
14 ;; along with JSCL. If not, see <http://www.gnu.org/licenses/>.
16 ;;;; Various list functions
18 (defun cons (x y ) (cons x y))
19 (defun consp (x) (consp x))
22 (or (consp x) (null x)))
32 (error "The value `~S' is not a type list." x))))
35 "Return the CAR part of a cons, or NIL if X is null."
38 (defun cdr (x) (cdr x))
40 (defun first (x) (car x))
41 (defun second (x) (cadr x))
42 (defun third (x) (caddr x))
43 (defun fourth (x) (cadddr x))
44 (defun rest (x) (cdr x))
46 (defun list (&rest args)
49 (defun list* (arg &rest others)
50 (cond ((null others) arg)
51 ((null (cdr others)) (cons arg (car others)))
52 (t (do ((x others (cdr x)))
53 ((null (cddr x)) (rplacd x (cadr x))))
56 (defun nthcdr (n list)
57 (while (and (plusp n) list)
59 (setq list (cdr list)))
63 (car (nthcdr n list)))
65 (defun caar (x) (car (car x)))
66 (defun cadr (x) (car (cdr x)))
67 (defun cdar (x) (cdr (car x)))
68 (defun cddr (x) (cdr (cdr x)))
69 (defun cadar (x) (car (cdr (car x))))
70 (defun caddr (x) (car (cdr (cdr x))))
71 (defun cdddr (x) (cdr (cdr (cdr x))))
72 (defun cadddr (x) (car (cdr (cdr (cdr x)))))
74 (defun cadar (x) (car (cdar x)))
75 (defun caaar (x) (car (caar x)))
76 (defun caadr (x) (car (cadr x)))
77 (defun cdaar (x) (cdr (caar x)))
78 (defun cdadr (x) (cdr (cadr x)))
79 (defun cddar (x) (cdr (cdar x)))
80 (defun caaaar (x) (car (caaar x)))
81 (defun caaadr (x) (car (caadr x)))
82 (defun caadar (x) (car (cadar x)))
83 (defun caaddr (x) (car (caddr x)))
84 (defun cadaar (x) (car (cdaar x)))
85 (defun cadadr (x) (car (cdadr x)))
86 (defun caddar (x) (car (cddar x)))
87 (defun cdaaar (x) (cdr (caaar x)))
88 (defun cdaadr (x) (cdr (caadr x)))
89 (defun cdadar (x) (cdr (cadar x)))
90 (defun cdaddr (x) (cdr (caddr x)))
91 (defun cddaar (x) (cdr (cdaar x)))
92 (defun cddadr (x) (cdr (cdadr x)))
93 (defun cdddar (x) (cdr (cddar x)))
94 (defun cddddr (x) (cdr (cdddr x)))
98 (mapcar #'identity x))
100 (defun copy-tree (tree)
102 (cons (copy-tree (car tree))
103 (copy-tree (cdr tree)))
106 (defun subst (new old tree &key (key #'identity) (test #'eql))
108 ((funcall test (funcall key tree) (funcall key old))
111 (cons (subst new old (car tree) :key key :test test)
112 (subst new old (cdr tree) :key key :test test)))
115 (defmacro pop (place)
116 (multiple-value-bind (dummies vals newval setter getter)
117 (get-setf-expansion place)
118 (let ((head (gensym)))
119 `(let* (,@(mapcar #'list dummies vals)
121 (,(car newval) (cdr ,head))
127 (defun map1 (func list)
130 (collect (funcall func (car list)))
131 (setq list (cdr list)))))
133 (defun mapcar (func list &rest lists)
134 (let ((lists (cons list lists)))
138 (let ((elems (map1 #'car lists)))
139 (do ((tail lists (cdr tail)))
141 (when (null (car tail)) (return-from loop))
142 (rplaca tail (cdar tail)))
143 (collect (apply func elems))))))))
146 (while (consp (cdr x))
152 (cons (car x) (butlast (cdr x)))))
154 (defun member (x list)
156 (when (eql x (car list))
158 (setq list (cdr list))))
161 (defun assoc (x alist &key (test #'eql))
163 (if (funcall test x (caar alist))
165 (setq alist (cdr alist))))
170 (define-setf-expander car (x)
171 (let ((cons (gensym))
172 (new-value (gensym)))
176 `(progn (rplaca ,cons ,new-value) ,new-value)
179 (define-setf-expander cdr (x)
180 (let ((cons (gensym))
181 (new-value (gensym)))
185 `(progn (rplacd ,cons ,new-value) ,new-value)
189 ;; The NCONC function is based on the SBCL's one.
190 (defun nconc (&rest lists)
191 (flet ((fail (object)
192 (error "type-error in nconc")))
193 (do ((top lists (cdr top)))
195 (let ((top-of-top (car top)))
198 (let* ((result top-of-top)
200 (do ((elements (cdr top) (cdr elements)))
202 (let ((ele (car elements)))
204 (cons (rplacd (last splice) ele)
206 (null (rplacd (last splice) nil))
207 (atom (if (cdr elements)
209 (rplacd (last splice) ele))))))
215 (return top-of-top))))))))
219 (do ((1st (cdr x) (if (endp 1st) 1st (cdr 1st)))
220 (2nd x 1st) ; 2nd follows first down the list.
221 (3rd y 2nd)) ;3rd follows 2nd down the list.