Export <slot> from GOOPS
[bpt/guile.git] / libguile / list.c
1 /* Copyright (C) 1995-1997, 2000, 2001, 2003, 2004, 2008-2011,
2 * 2014 Free Software Foundation, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 3 of
7 * the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
18 */
19
20
21 \f
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include "libguile/_scm.h"
27 #include "libguile/eq.h"
28
29 #include "libguile/validate.h"
30 #include "libguile/list.h"
31 #include "libguile/eval.h"
32
33 #include <stdarg.h>
34
35 \f
36 /* creating lists */
37
38 #define SCM_I_CONS(cell, x, y) \
39 do { \
40 cell = scm_cell (SCM_UNPACK (x), SCM_UNPACK (y)); \
41 } while (0)
42
43 SCM
44 scm_list_1 (SCM e1)
45 {
46 SCM c1;
47 SCM_I_CONS (c1, e1, SCM_EOL);
48 return c1;
49 }
50
51 SCM
52 scm_list_2 (SCM e1, SCM e2)
53 {
54 SCM c1, c2;
55 SCM_I_CONS (c2, e2, SCM_EOL);
56 SCM_I_CONS (c1, e1, c2);
57 return c1;
58 }
59
60 SCM
61 scm_list_3 (SCM e1, SCM e2, SCM e3)
62 {
63 SCM c1, c2, c3;
64 SCM_I_CONS (c3, e3, SCM_EOL);
65 SCM_I_CONS (c2, e2, c3);
66 SCM_I_CONS (c1, e1, c2);
67 return c1;
68 }
69
70 SCM
71 scm_list_4 (SCM e1, SCM e2, SCM e3, SCM e4)
72 {
73 return scm_cons2 (e1, e2, scm_list_2 (e3, e4));
74 }
75
76 SCM
77 scm_list_5 (SCM e1, SCM e2, SCM e3, SCM e4, SCM e5)
78 {
79 return scm_cons2 (e1, e2, scm_list_3 (e3, e4, e5));
80 }
81
82 SCM
83 scm_list_n (SCM elt, ...)
84 {
85 va_list foo;
86 SCM answer = SCM_EOL;
87 SCM *pos = &answer;
88
89 va_start (foo, elt);
90 while (! SCM_UNBNDP (elt))
91 {
92 #if (SCM_DEBUG_CELL_ACCESSES == 1)
93 if (SCM_HEAP_OBJECT_P (elt))
94 SCM_VALIDATE_CELL(elt, 0);
95 #endif
96 *pos = scm_cons (elt, SCM_EOL);
97 pos = SCM_CDRLOC (*pos);
98 elt = va_arg (foo, SCM);
99 }
100 va_end (foo);
101 return answer;
102 }
103
104
105 SCM_DEFINE (scm_make_list, "make-list", 1, 1, 0,
106 (SCM n, SCM init),
107 "Create a list containing of @var{n} elements, where each\n"
108 "element is initialized to @var{init}. @var{init} defaults to\n"
109 "the empty list @code{()} if not given.")
110 #define FUNC_NAME s_scm_make_list
111 {
112 unsigned nn = scm_to_uint (n);
113 unsigned i;
114 SCM ret = SCM_EOL;
115
116 if (SCM_UNBNDP (init))
117 init = SCM_EOL;
118
119 for (i = 0; i < nn; i++)
120 ret = scm_cons (init, ret);
121 return ret;
122 }
123 #undef FUNC_NAME
124
125
126 SCM_DEFINE (scm_cons_star, "cons*", 1, 0, 1,
127 (SCM arg, SCM rest),
128 "Like @code{list}, but the last arg provides the tail of the\n"
129 "constructed list, returning @code{(cons @var{arg1} (cons\n"
130 "@var{arg2} (cons @dots{} @var{argn})))}. Requires at least one\n"
131 "argument. If given one argument, that argument is returned as\n"
132 "result. This function is called @code{list*} in some other\n"
133 "Schemes and in Common LISP.")
134 #define FUNC_NAME s_scm_cons_star
135 {
136 SCM ret = SCM_EOL;
137 SCM *p = &ret;
138
139 SCM_VALIDATE_REST_ARGUMENT (rest);
140
141 for ( ; scm_is_pair (rest); rest = SCM_CDR (rest))
142 {
143 *p = scm_cons (arg, SCM_EOL);
144 p = SCM_CDRLOC (*p);
145 arg = SCM_CAR (rest);
146 }
147
148 *p = arg;
149 return ret;
150 }
151 #undef FUNC_NAME
152
153
154 \f
155 /* general questions about lists --- null?, list?, length, etc. */
156
157 SCM_DEFINE (scm_null_p, "null?", 1, 0, 0,
158 (SCM x),
159 "Return @code{#t} iff @var{x} is the empty list, else @code{#f}.")
160 #define FUNC_NAME s_scm_null_p
161 {
162 return scm_from_bool (SCM_NULL_OR_NIL_P (x));
163 }
164 #undef FUNC_NAME
165
166
167 SCM_DEFINE (scm_list_p, "list?", 1, 0, 0,
168 (SCM x),
169 "Return @code{#t} iff @var{x} is a proper list, else @code{#f}.")
170 #define FUNC_NAME s_scm_list_p
171 {
172 return scm_from_bool (scm_ilength (x) >= 0);
173 }
174 #undef FUNC_NAME
175
176
177 /* Return the length of SX, or -1 if it's not a proper list.
178 This uses the "tortoise and hare" algorithm to detect "infinitely
179 long" lists (i.e. lists with cycles in their cdrs), and returns -1
180 if it does find one. */
181 long
182 scm_ilength (SCM sx)
183 {
184 long i = 0;
185 SCM tortoise = sx;
186 SCM hare = sx;
187
188 do
189 {
190 if (!scm_is_pair (hare))
191 return SCM_NULL_OR_NIL_P (hare) ? i : -1;
192 hare = SCM_CDR (hare);
193 i++;
194 if (!scm_is_pair (hare))
195 return SCM_NULL_OR_NIL_P (hare) ? i : -1;
196 hare = SCM_CDR (hare);
197 i++;
198 /* For every two steps the hare takes, the tortoise takes one. */
199 tortoise = SCM_CDR (tortoise);
200 }
201 while (!scm_is_eq (hare, tortoise));
202
203 /* If the tortoise ever catches the hare, then the list must contain
204 a cycle. */
205 return -1;
206 }
207
208
209 SCM_DEFINE (scm_length, "length", 1, 0, 0,
210 (SCM lst),
211 "Return the number of elements in list @var{lst}.")
212 #define FUNC_NAME s_scm_length
213 {
214 long i;
215 SCM_VALIDATE_LIST_COPYLEN (1, lst, i);
216 return scm_from_long (i);
217 }
218 #undef FUNC_NAME
219
220
221 \f
222 /* appending lists */
223
224 SCM_DEFINE (scm_append, "append", 0, 0, 1,
225 (SCM args),
226 "Return a list consisting of the elements the lists passed as\n"
227 "arguments.\n"
228 "@lisp\n"
229 "(append '(x) '(y)) @result{} (x y)\n"
230 "(append '(a) '(b c d)) @result{} (a b c d)\n"
231 "(append '(a (b)) '((c))) @result{} (a (b) (c))\n"
232 "@end lisp\n"
233 "The resulting list is always newly allocated, except that it\n"
234 "shares structure with the last list argument. The last\n"
235 "argument may actually be any object; an improper list results\n"
236 "if the last argument is not a proper list.\n"
237 "@lisp\n"
238 "(append '(a b) '(c . d)) @result{} (a b c . d)\n"
239 "(append '() 'a) @result{} a\n"
240 "@end lisp")
241 #define FUNC_NAME s_scm_append
242 {
243 SCM_VALIDATE_REST_ARGUMENT (args);
244 if (scm_is_null (args)) {
245 return SCM_EOL;
246 } else {
247 SCM res = SCM_EOL;
248 SCM *lloc = &res;
249 SCM arg = SCM_CAR (args);
250 int argnum = 1;
251 args = SCM_CDR (args);
252 while (!scm_is_null (args)) {
253 while (scm_is_pair (arg)) {
254 *lloc = scm_cons (SCM_CAR (arg), SCM_EOL);
255 lloc = SCM_CDRLOC (*lloc);
256 arg = SCM_CDR (arg);
257 }
258 SCM_VALIDATE_NULL_OR_NIL (argnum, arg);
259 arg = SCM_CAR (args);
260 args = SCM_CDR (args);
261 argnum++;
262 };
263 *lloc = arg;
264 return res;
265 }
266 }
267 #undef FUNC_NAME
268
269
270 SCM_DEFINE (scm_append_x, "append!", 0, 0, 1,
271 (SCM args),
272 "A destructive version of @code{append} (@pxref{Pairs and\n"
273 "Lists,,,r5rs, The Revised^5 Report on Scheme}). The cdr field\n"
274 "of each list's final pair is changed to point to the head of\n"
275 "the next list, so no consing is performed. Return\n"
276 "the mutated list.")
277 #define FUNC_NAME s_scm_append_x
278 {
279 SCM ret, *loc;
280 int argnum = 1;
281 SCM_VALIDATE_REST_ARGUMENT (args);
282
283 if (scm_is_null (args))
284 return SCM_EOL;
285
286 loc = &ret;
287 for (;;)
288 {
289 SCM arg = SCM_CAR (args);
290 *loc = arg;
291
292 args = SCM_CDR (args);
293 if (scm_is_null (args))
294 return ret;
295
296 if (!SCM_NULL_OR_NIL_P (arg))
297 {
298 SCM_VALIDATE_CONS (argnum, arg);
299 loc = SCM_CDRLOC (scm_last_pair (arg));
300 SCM_VALIDATE_NULL_OR_NIL (argnum, *loc);
301 }
302 argnum++;
303 }
304 }
305 #undef FUNC_NAME
306
307
308 SCM_DEFINE (scm_last_pair, "last-pair", 1, 0, 0,
309 (SCM lst),
310 "Return the last pair in @var{lst}, signalling an error if\n"
311 "@var{lst} is circular.")
312 #define FUNC_NAME s_scm_last_pair
313 {
314 SCM tortoise = lst;
315 SCM hare = lst;
316
317 if (SCM_NULL_OR_NIL_P (lst))
318 return lst;
319
320 SCM_VALIDATE_CONS (SCM_ARG1, lst);
321 do {
322 SCM ahead = SCM_CDR(hare);
323 if (!scm_is_pair (ahead)) return hare;
324 hare = ahead;
325 ahead = SCM_CDR(hare);
326 if (!scm_is_pair (ahead)) return hare;
327 hare = ahead;
328 tortoise = SCM_CDR(tortoise);
329 }
330 while (!scm_is_eq (hare, tortoise));
331 SCM_MISC_ERROR ("Circular structure in position 1: ~S", scm_list_1 (lst));
332 }
333 #undef FUNC_NAME
334
335 \f
336 /* reversing lists */
337
338 SCM_DEFINE (scm_reverse, "reverse", 1, 0, 0,
339 (SCM lst),
340 "Return a new list that contains the elements of @var{lst} but\n"
341 "in reverse order.")
342 #define FUNC_NAME s_scm_reverse
343 {
344 SCM result = SCM_EOL;
345 SCM tortoise = lst;
346 SCM hare = lst;
347
348 do {
349 if (SCM_NULL_OR_NIL_P(hare)) return result;
350 SCM_ASSERT(scm_is_pair(hare), lst, 1, FUNC_NAME);
351 result = scm_cons (SCM_CAR (hare), result);
352 hare = SCM_CDR (hare);
353 if (SCM_NULL_OR_NIL_P(hare)) return result;
354 SCM_ASSERT(scm_is_pair(hare), lst, 1, FUNC_NAME);
355 result = scm_cons (SCM_CAR (hare), result);
356 hare = SCM_CDR (hare);
357 tortoise = SCM_CDR (tortoise);
358 }
359 while (!scm_is_eq (hare, tortoise));
360 SCM_MISC_ERROR ("Circular structure in position 1: ~S", scm_list_1 (lst));
361 }
362 #undef FUNC_NAME
363
364 SCM_DEFINE (scm_reverse_x, "reverse!", 1, 1, 0,
365 (SCM lst, SCM new_tail),
366 "A destructive version of @code{reverse} (@pxref{Pairs and Lists,,,r5rs,\n"
367 "The Revised^5 Report on Scheme}). The cdr of each cell in @var{lst} is\n"
368 "modified to point to the previous list element. Return the\n"
369 "reversed list.\n\n"
370 "Caveat: because the list is modified in place, the tail of the original\n"
371 "list now becomes its head, and the head of the original list now becomes\n"
372 "the tail. Therefore, the @var{lst} symbol to which the head of the\n"
373 "original list was bound now points to the tail. To ensure that the head\n"
374 "of the modified list is not lost, it is wise to save the return value of\n"
375 "@code{reverse!}")
376 #define FUNC_NAME s_scm_reverse_x
377 {
378 SCM old_lst = lst;
379 SCM tail = SCM_BOOL_F;
380
381 if (SCM_UNBNDP (new_tail))
382 new_tail = SCM_EOL;
383
384 if (SCM_NULL_OR_NIL_P (lst))
385 return new_tail;
386
387 /* SCM_VALIDATE_LIST would run through the whole list to make sure it
388 is not eventually circular. In contrast to most list operations,
389 reverse! cannot get stuck in an infinite loop but arrives back at
390 the start when given an eventually or fully circular list. Because
391 of that, we can save the cost of an upfront proper list check at
392 the price of having to do a double reversal in the error case.
393 */
394
395 while (scm_is_pair (lst))
396 {
397 SCM old_tail = SCM_CDR (lst);
398 SCM_SETCDR (lst, tail);
399 tail = lst;
400 lst = old_tail;
401 }
402
403 if (SCM_LIKELY (SCM_NULL_OR_NIL_P (lst)))
404 {
405 SCM_SETCDR (old_lst, new_tail);
406 return tail;
407 }
408
409 /* We did not start with a proper list. Undo the reversal. */
410
411 while (scm_is_pair (tail))
412 {
413 SCM old_tail = SCM_CDR (tail);
414 SCM_SETCDR (tail, lst);
415 lst = tail;
416 tail = old_tail;
417 }
418
419 SCM_WRONG_TYPE_ARG (1, lst);
420 return lst;
421 }
422 #undef FUNC_NAME
423
424 \f
425
426 /* indexing lists by element number */
427
428 SCM_DEFINE (scm_list_ref, "list-ref", 2, 0, 0,
429 (SCM list, SCM k),
430 "Return the @var{k}th element from @var{list}.")
431 #define FUNC_NAME s_scm_list_ref
432 {
433 SCM lst = list;
434 unsigned long int i;
435 i = scm_to_ulong (k);
436 while (scm_is_pair (lst)) {
437 if (i == 0)
438 return SCM_CAR (lst);
439 else {
440 --i;
441 lst = SCM_CDR (lst);
442 }
443 };
444 if (SCM_NULL_OR_NIL_P (lst))
445 SCM_OUT_OF_RANGE (2, k);
446 else
447 SCM_WRONG_TYPE_ARG (1, list);
448 }
449 #undef FUNC_NAME
450
451
452 SCM_DEFINE (scm_list_set_x, "list-set!", 3, 0, 0,
453 (SCM list, SCM k, SCM val),
454 "Set the @var{k}th element of @var{list} to @var{val}.")
455 #define FUNC_NAME s_scm_list_set_x
456 {
457 SCM lst = list;
458 unsigned long int i = scm_to_ulong (k);
459 while (scm_is_pair (lst)) {
460 if (i == 0) {
461 SCM_SETCAR (lst, val);
462 return val;
463 } else {
464 --i;
465 lst = SCM_CDR (lst);
466 }
467 };
468 if (SCM_NULL_OR_NIL_P (lst))
469 SCM_OUT_OF_RANGE (2, k);
470 else
471 SCM_WRONG_TYPE_ARG (1, list);
472 }
473 #undef FUNC_NAME
474
475
476 SCM_REGISTER_PROC(s_list_cdr_ref, "list-cdr-ref", 2, 0, 0, scm_list_tail);
477
478 SCM_DEFINE (scm_list_tail, "list-tail", 2, 0, 0,
479 (SCM lst, SCM k),
480 "@deffnx {Scheme Procedure} list-cdr-ref lst k\n"
481 "Return the \"tail\" of @var{lst} beginning with its @var{k}th element.\n"
482 "The first element of the list is considered to be element 0.\n\n"
483 "@code{list-tail} and @code{list-cdr-ref} are identical. It may help to\n"
484 "think of @code{list-cdr-ref} as accessing the @var{k}th cdr of the list,\n"
485 "or returning the results of cdring @var{k} times down @var{lst}.")
486 #define FUNC_NAME s_scm_list_tail
487 {
488 size_t i = scm_to_size_t (k);
489 while (i-- > 0) {
490 SCM_VALIDATE_CONS (1, lst);
491 lst = SCM_CDR(lst);
492 }
493 return lst;
494 }
495 #undef FUNC_NAME
496
497
498 SCM_DEFINE (scm_list_cdr_set_x, "list-cdr-set!", 3, 0, 0,
499 (SCM list, SCM k, SCM val),
500 "Set the @var{k}th cdr of @var{list} to @var{val}.")
501 #define FUNC_NAME s_scm_list_cdr_set_x
502 {
503 SCM lst = list;
504 size_t i = scm_to_size_t (k);
505 while (scm_is_pair (lst)) {
506 if (i == 0) {
507 SCM_SETCDR (lst, val);
508 return val;
509 } else {
510 --i;
511 lst = SCM_CDR (lst);
512 }
513 };
514 if (SCM_NULL_OR_NIL_P (lst))
515 SCM_OUT_OF_RANGE (2, k);
516 else
517 SCM_WRONG_TYPE_ARG (1, list);
518 }
519 #undef FUNC_NAME
520
521
522 \f
523 /* copying lists, perhaps partially */
524
525 SCM_DEFINE (scm_list_head, "list-head", 2, 0, 0,
526 (SCM lst, SCM k),
527 "Copy the first @var{k} elements from @var{lst} into a new list, and\n"
528 "return it.")
529 #define FUNC_NAME s_scm_list_head
530 {
531 SCM answer;
532 SCM * pos;
533 size_t i = scm_to_size_t (k);
534
535 answer = SCM_EOL;
536 pos = &answer;
537 while (i-- > 0)
538 {
539 SCM_VALIDATE_CONS (1, lst);
540 *pos = scm_cons (SCM_CAR (lst), SCM_EOL);
541 pos = SCM_CDRLOC (*pos);
542 lst = SCM_CDR(lst);
543 }
544 return answer;
545 }
546 #undef FUNC_NAME
547
548
549 /* Copy a list which is known to be finite. The last pair may or may not have
550 * a '() in its cdr. That is, improper lists are accepted. */
551 SCM
552 scm_i_finite_list_copy (SCM list)
553 {
554 if (!scm_is_pair (list))
555 {
556 return list;
557 }
558 else
559 {
560 SCM tail;
561 const SCM result = tail = scm_list_1 (SCM_CAR (list));
562 list = SCM_CDR (list);
563 while (scm_is_pair (list))
564 {
565 const SCM new_tail = scm_list_1 (SCM_CAR (list));
566 SCM_SETCDR (tail, new_tail);
567 tail = new_tail;
568 list = SCM_CDR (list);
569 }
570 SCM_SETCDR (tail, list);
571
572 return result;
573 }
574 }
575
576
577 SCM_DEFINE (scm_list_copy, "list-copy", 1, 0, 0,
578 (SCM lst),
579 "Return a (newly-created) copy of @var{lst}.")
580 #define FUNC_NAME s_scm_list_copy
581 {
582 SCM newlst;
583 SCM * fill_here;
584 SCM from_here;
585
586 SCM_VALIDATE_LIST (1, lst);
587
588 newlst = SCM_EOL;
589 fill_here = &newlst;
590 from_here = lst;
591
592 while (scm_is_pair (from_here))
593 {
594 SCM c;
595 c = scm_cons (SCM_CAR (from_here), SCM_CDR (from_here));
596 *fill_here = c;
597 fill_here = SCM_CDRLOC (c);
598 from_here = SCM_CDR (from_here);
599 }
600 return newlst;
601 }
602 #undef FUNC_NAME
603
604
605 SCM_PROC (s_list, "list", 0, 0, 1, scm_list_copy);
606 SCM_SNARF_DOCS (primitive, scm_list_copy, "list", (SCM objs), 0, 0, 1,
607 "Return a list containing @var{objs}, the arguments to\n"
608 "@code{list}.")
609
610 /* This used to be the code for "list", but it's wrong when used via apply
611 (it should copy the list). It seems pretty unlikely anyone would have
612 been using this from C code, since it's a no-op, but keep it for strict
613 binary compatibility. */
614 SCM
615 scm_list (SCM objs)
616 {
617 return objs;
618 }
619
620
621 \f
622 /* membership tests (memq, memv, etc.) */
623
624 /* The function scm_c_memq returns the first sublist of list whose car is
625 * 'eq?' obj, where the sublists of list are the non-empty lists returned by
626 * (list-tail list k) for k less than the length of list. If obj does not
627 * occur in list, then #f (not the empty list) is returned.
628 * List must be a proper list, otherwise scm_c_memq may crash or loop
629 * endlessly.
630 */
631 SCM
632 scm_c_memq (SCM obj, SCM list)
633 {
634 for (; !SCM_NULL_OR_NIL_P (list); list = SCM_CDR (list))
635 {
636 if (scm_is_eq (SCM_CAR (list), obj))
637 return list;
638 }
639 return SCM_BOOL_F;
640 }
641
642
643 SCM_DEFINE (scm_memq, "memq", 2, 0, 0,
644 (SCM x, SCM lst),
645 "Return the first sublist of @var{lst} whose car is @code{eq?}\n"
646 "to @var{x} where the sublists of @var{lst} are the non-empty\n"
647 "lists returned by @code{(list-tail @var{lst} @var{k})} for\n"
648 "@var{k} less than the length of @var{lst}. If @var{x} does not\n"
649 "occur in @var{lst}, then @code{#f} (not the empty list) is\n"
650 "returned.")
651 #define FUNC_NAME s_scm_memq
652 {
653 SCM hare = lst, tortoise = lst;
654
655 while (scm_is_pair (hare))
656 {
657 if (scm_is_eq (SCM_CAR (hare), x))
658 return hare;
659 else
660 hare = SCM_CDR (hare);
661
662 if (!scm_is_pair (hare))
663 break;
664
665 if (scm_is_eq (SCM_CAR (hare), x))
666 return hare;
667 else
668 hare = SCM_CDR (hare);
669
670 tortoise = SCM_CDR (tortoise);
671 if (SCM_UNLIKELY (scm_is_eq (hare, tortoise)))
672 break;
673 }
674
675 if (SCM_LIKELY (scm_is_null (hare)))
676 return SCM_BOOL_F;
677 else
678 scm_wrong_type_arg_msg (FUNC_NAME, 2, lst, "list");
679 }
680 #undef FUNC_NAME
681
682
683 SCM_DEFINE (scm_memv, "memv", 2, 0, 0,
684 (SCM x, SCM lst),
685 "Return the first sublist of @var{lst} whose car is @code{eqv?}\n"
686 "to @var{x} where the sublists of @var{lst} are the non-empty\n"
687 "lists returned by @code{(list-tail @var{lst} @var{k})} for\n"
688 "@var{k} less than the length of @var{lst}. If @var{x} does not\n"
689 "occur in @var{lst}, then @code{#f} (not the empty list) is\n"
690 "returned.")
691 #define FUNC_NAME s_scm_memv
692 {
693 SCM hare = lst, tortoise = lst;
694
695 while (scm_is_pair (hare))
696 {
697 if (scm_is_true (scm_eqv_p (SCM_CAR (hare), x)))
698 return hare;
699 else
700 hare = SCM_CDR (hare);
701
702 if (!scm_is_pair (hare))
703 break;
704
705 if (scm_is_true (scm_eqv_p (SCM_CAR (hare), x)))
706 return hare;
707 else
708 hare = SCM_CDR (hare);
709
710 tortoise = SCM_CDR (tortoise);
711 if (SCM_UNLIKELY (scm_is_eq (hare, tortoise)))
712 break;
713 }
714
715 if (SCM_LIKELY (scm_is_null (hare)))
716 return SCM_BOOL_F;
717 else
718 scm_wrong_type_arg_msg (FUNC_NAME, 2, lst, "list");
719 }
720 #undef FUNC_NAME
721
722
723 SCM_DEFINE (scm_member, "member", 2, 0, 0,
724 (SCM x, SCM lst),
725 "Return the first sublist of @var{lst} whose car is\n"
726 "@code{equal?} to @var{x} where the sublists of @var{lst} are\n"
727 "the non-empty lists returned by @code{(list-tail @var{lst}\n"
728 "@var{k})} for @var{k} less than the length of @var{lst}. If\n"
729 "@var{x} does not occur in @var{lst}, then @code{#f} (not the\n"
730 "empty list) is returned.")
731 #define FUNC_NAME s_scm_member
732 {
733 SCM_VALIDATE_LIST (2, lst);
734 for (; !SCM_NULL_OR_NIL_P (lst); lst = SCM_CDR (lst))
735 {
736 if (! scm_is_false (scm_equal_p (SCM_CAR (lst), x)))
737 return lst;
738 }
739 return SCM_BOOL_F;
740 }
741 #undef FUNC_NAME
742
743 \f
744 /* deleting elements from a list (delq, etc.) */
745
746 SCM_DEFINE (scm_delq_x, "delq!", 2, 0, 0,
747 (SCM item, SCM lst),
748 "@deffnx {Scheme Procedure} delv! item lst\n"
749 "@deffnx {Scheme Procedure} delete! item lst\n"
750 "These procedures are destructive versions of @code{delq}, @code{delv}\n"
751 "and @code{delete}: they modify the existing @var{lst}\n"
752 "rather than creating a new list. Caveat evaluator: Like other\n"
753 "destructive list functions, these functions cannot modify the binding of\n"
754 "@var{lst}, and so cannot be used to delete the first element of\n"
755 "@var{lst} destructively.")
756 #define FUNC_NAME s_scm_delq_x
757 {
758 SCM walk;
759 SCM *prev;
760
761 for (prev = &lst, walk = lst;
762 scm_is_pair (walk);
763 walk = SCM_CDR (walk))
764 {
765 if (scm_is_eq (SCM_CAR (walk), item))
766 *prev = SCM_CDR (walk);
767 else
768 prev = SCM_CDRLOC (walk);
769 }
770
771 return lst;
772 }
773 #undef FUNC_NAME
774
775
776 SCM_DEFINE (scm_delv_x, "delv!", 2, 0, 0,
777 (SCM item, SCM lst),
778 "Destructively remove all elements from @var{lst} that are\n"
779 "@code{eqv?} to @var{item}.")
780 #define FUNC_NAME s_scm_delv_x
781 {
782 SCM walk;
783 SCM *prev;
784
785 for (prev = &lst, walk = lst;
786 scm_is_pair (walk);
787 walk = SCM_CDR (walk))
788 {
789 if (! scm_is_false (scm_eqv_p (SCM_CAR (walk), item)))
790 *prev = SCM_CDR (walk);
791 else
792 prev = SCM_CDRLOC (walk);
793 }
794
795 return lst;
796 }
797 #undef FUNC_NAME
798
799
800
801 SCM_DEFINE (scm_delete_x, "delete!", 2, 0, 0,
802 (SCM item, SCM lst),
803 "Destructively remove all elements from @var{lst} that are\n"
804 "@code{equal?} to @var{item}.")
805 #define FUNC_NAME s_scm_delete_x
806 {
807 SCM walk;
808 SCM *prev;
809
810 for (prev = &lst, walk = lst;
811 scm_is_pair (walk);
812 walk = SCM_CDR (walk))
813 {
814 if (! scm_is_false (scm_equal_p (SCM_CAR (walk), item)))
815 *prev = SCM_CDR (walk);
816 else
817 prev = SCM_CDRLOC (walk);
818 }
819
820 return lst;
821 }
822 #undef FUNC_NAME
823
824
825 \f
826
827
828 SCM_DEFINE (scm_delq, "delq", 2, 0, 0,
829 (SCM item, SCM lst),
830 "Return a newly-created copy of @var{lst} with elements\n"
831 "@code{eq?} to @var{item} removed. This procedure mirrors\n"
832 "@code{memq}: @code{delq} compares elements of @var{lst} against\n"
833 "@var{item} with @code{eq?}.")
834 #define FUNC_NAME s_scm_delq
835 {
836 SCM copy = scm_list_copy (lst);
837 return scm_delq_x (item, copy);
838 }
839 #undef FUNC_NAME
840
841 SCM_DEFINE (scm_delv, "delv", 2, 0, 0,
842 (SCM item, SCM lst),
843 "Return a newly-created copy of @var{lst} with elements\n"
844 "@code{eqv?} to @var{item} removed. This procedure mirrors\n"
845 "@code{memv}: @code{delv} compares elements of @var{lst} against\n"
846 "@var{item} with @code{eqv?}.")
847 #define FUNC_NAME s_scm_delv
848 {
849 SCM copy = scm_list_copy (lst);
850 return scm_delv_x (item, copy);
851 }
852 #undef FUNC_NAME
853
854 SCM_DEFINE (scm_delete, "delete", 2, 0, 0,
855 (SCM item, SCM lst),
856 "Return a newly-created copy of @var{lst} with elements\n"
857 "@code{equal?} to @var{item} removed. This procedure mirrors\n"
858 "@code{member}: @code{delete} compares elements of @var{lst}\n"
859 "against @var{item} with @code{equal?}.")
860 #define FUNC_NAME s_scm_delete
861 {
862 SCM copy = scm_list_copy (lst);
863 return scm_delete_x (item, copy);
864 }
865 #undef FUNC_NAME
866
867
868 SCM_DEFINE (scm_delq1_x, "delq1!", 2, 0, 0,
869 (SCM item, SCM lst),
870 "Like @code{delq!}, but only deletes the first occurrence of\n"
871 "@var{item} from @var{lst}. Tests for equality using\n"
872 "@code{eq?}. See also @code{delv1!} and @code{delete1!}.")
873 #define FUNC_NAME s_scm_delq1_x
874 {
875 SCM walk;
876 SCM *prev;
877
878 for (prev = &lst, walk = lst;
879 scm_is_pair (walk);
880 walk = SCM_CDR (walk))
881 {
882 if (scm_is_eq (SCM_CAR (walk), item))
883 {
884 *prev = SCM_CDR (walk);
885 break;
886 }
887 else
888 prev = SCM_CDRLOC (walk);
889 }
890
891 return lst;
892 }
893 #undef FUNC_NAME
894
895
896 SCM_DEFINE (scm_delv1_x, "delv1!", 2, 0, 0,
897 (SCM item, SCM lst),
898 "Like @code{delv!}, but only deletes the first occurrence of\n"
899 "@var{item} from @var{lst}. Tests for equality using\n"
900 "@code{eqv?}. See also @code{delq1!} and @code{delete1!}.")
901 #define FUNC_NAME s_scm_delv1_x
902 {
903 SCM walk;
904 SCM *prev;
905
906 for (prev = &lst, walk = lst;
907 scm_is_pair (walk);
908 walk = SCM_CDR (walk))
909 {
910 if (! scm_is_false (scm_eqv_p (SCM_CAR (walk), item)))
911 {
912 *prev = SCM_CDR (walk);
913 break;
914 }
915 else
916 prev = SCM_CDRLOC (walk);
917 }
918
919 return lst;
920 }
921 #undef FUNC_NAME
922
923
924 SCM_DEFINE (scm_delete1_x, "delete1!", 2, 0, 0,
925 (SCM item, SCM lst),
926 "Like @code{delete!}, but only deletes the first occurrence of\n"
927 "@var{item} from @var{lst}. Tests for equality using\n"
928 "@code{equal?}. See also @code{delq1!} and @code{delv1!}.")
929 #define FUNC_NAME s_scm_delete1_x
930 {
931 SCM walk;
932 SCM *prev;
933
934 for (prev = &lst, walk = lst;
935 scm_is_pair (walk);
936 walk = SCM_CDR (walk))
937 {
938 if (! scm_is_false (scm_equal_p (SCM_CAR (walk), item)))
939 {
940 *prev = SCM_CDR (walk);
941 break;
942 }
943 else
944 prev = SCM_CDRLOC (walk);
945 }
946
947 return lst;
948 }
949 #undef FUNC_NAME
950
951 SCM_DEFINE (scm_filter, "filter", 2, 0, 0,
952 (SCM pred, SCM list),
953 "Return all the elements of 2nd arg @var{list} that satisfy predicate @var{pred}.\n"
954 "The list is not disordered -- elements that appear in the result list occur\n"
955 "in the same order as they occur in the argument list. The returned list may\n"
956 "share a common tail with the argument list. The dynamic order in which the\n"
957 "various applications of pred are made is not specified.\n\n"
958 "@lisp\n"
959 "(filter even? '(0 7 8 8 43 -4)) => (0 8 8 -4)\n"
960 "@end lisp")
961 #define FUNC_NAME s_scm_filter
962 {
963 SCM walk;
964 SCM *prev;
965 SCM res = SCM_EOL;
966 SCM_ASSERT (scm_is_true (scm_procedure_p (pred)), pred, 1, FUNC_NAME);
967 SCM_VALIDATE_LIST (2, list);
968
969 for (prev = &res, walk = list;
970 scm_is_pair (walk);
971 walk = SCM_CDR (walk))
972 {
973 if (scm_is_true (scm_call_1 (pred, SCM_CAR (walk))))
974 {
975 *prev = scm_cons (SCM_CAR (walk), SCM_EOL);
976 prev = SCM_CDRLOC (*prev);
977 }
978 }
979
980 return res;
981 }
982 #undef FUNC_NAME
983
984 SCM_DEFINE (scm_filter_x, "filter!", 2, 0, 0,
985 (SCM pred, SCM list),
986 "Linear-update variant of @code{filter}.")
987 #define FUNC_NAME s_scm_filter_x
988 {
989 SCM walk;
990 SCM *prev;
991 SCM_ASSERT (scm_is_true (scm_procedure_p (pred)), pred, 1, FUNC_NAME);
992 SCM_VALIDATE_LIST (2, list);
993
994 for (prev = &list, walk = list;
995 scm_is_pair (walk);
996 walk = SCM_CDR (walk))
997 {
998 if (scm_is_true (scm_call_1 (pred, SCM_CAR (walk))))
999 prev = SCM_CDRLOC (walk);
1000 else
1001 *prev = SCM_CDR (walk);
1002 }
1003
1004 return list;
1005 }
1006 #undef FUNC_NAME
1007
1008 \f
1009 void
1010 scm_init_list ()
1011 {
1012 #include "libguile/list.x"
1013 }
1014
1015 /*
1016 Local Variables:
1017 c-file-style: "gnu"
1018 End:
1019 */