Corrected "Brat" to "Brad". Sorry.
[bpt/guile.git] / libguile / alist.c
CommitLineData
e282f286 1/* Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
0f2d19dd
JB
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
1bbd0b84
GB
41
42/* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
44
0f2d19dd
JB
45\f
46#include <stdio.h>
a0599745
MD
47#include "libguile/_scm.h"
48#include "libguile/eq.h"
49#include "libguile/list.h"
20e6290e 50
a0599745
MD
51#include "libguile/validate.h"
52#include "libguile/alist.h"
0f2d19dd
JB
53
54\f
55
3b3b36dd 56SCM_DEFINE (scm_acons, "acons", 3, 0, 0,
0b5f3f34 57 (SCM key, SCM value, SCM alist),
b380b885
MD
58 "Adds a new key-value pair to @var{alist}. A new pair is\n"
59 "created whose car is @var{key} and whose cdr is @var{value}, and the\n"
60 "pair is consed onto @var{alist}, and the new list is returned. This\n"
61 "function is @emph{not} destructive; @var{alist} is not modified.")
1bbd0b84 62#define FUNC_NAME s_scm_acons
0f2d19dd 63{
0b5f3f34
GB
64 SCM pair;
65 SCM head;
66
67 SCM_NEWCELL (pair);
665aeda3
DH
68 SCM_SET_CELL_OBJECT_0 (pair, key);
69 SCM_SET_CELL_OBJECT_1 (pair, value);
0b5f3f34
GB
70
71 SCM_NEWCELL (head);
665aeda3
DH
72 SCM_SET_CELL_OBJECT_0 (head, pair);
73 SCM_SET_CELL_OBJECT_1 (head, alist);
0b5f3f34
GB
74
75 return head;
0f2d19dd 76}
1bbd0b84 77#undef FUNC_NAME
0f2d19dd
JB
78
79\f
80
a1ec6916 81SCM_DEFINE (scm_sloppy_assq, "sloppy-assq", 2, 0, 0,
0b5f3f34 82 (SCM key, SCM alist),
b380b885
MD
83 "Behaves like @code{assq} but does not do any error checking.\n"
84 "Recommended only for use in Guile internals.")
1bbd0b84 85#define FUNC_NAME s_scm_sloppy_assq
0f2d19dd 86{
0c95b57d 87 for (; SCM_CONSP (alist); alist = SCM_CDR (alist))
0f2d19dd 88 {
2de257bd 89 SCM tmp = SCM_CAR (alist);
fbd485ba 90 if (SCM_CONSP (tmp) && SCM_EQ_P (SCM_CAR (tmp), key))
cf18adf0 91 return tmp;
0f2d19dd
JB
92 }
93 return SCM_BOOL_F;
94}
1bbd0b84 95#undef FUNC_NAME
0f2d19dd
JB
96
97
98
a1ec6916 99SCM_DEFINE (scm_sloppy_assv, "sloppy-assv", 2, 0, 0,
0b5f3f34 100 (SCM key, SCM alist),
b380b885
MD
101 "Behaves like @code{assv} but does not do any error checking.\n"
102 "Recommended only for use in Guile internals.")
1bbd0b84 103#define FUNC_NAME s_scm_sloppy_assv
0f2d19dd 104{
0c95b57d 105 for (; SCM_CONSP (alist); alist = SCM_CDR (alist))
0f2d19dd 106 {
2de257bd 107 SCM tmp = SCM_CAR (alist);
0b5f3f34
GB
108 if (SCM_CONSP (tmp)
109 && SCM_NFALSEP (scm_eqv_p (SCM_CAR (tmp), key)))
cf18adf0 110 return tmp;
0f2d19dd
JB
111 }
112 return SCM_BOOL_F;
113}
1bbd0b84 114#undef FUNC_NAME
0f2d19dd
JB
115
116
a1ec6916 117SCM_DEFINE (scm_sloppy_assoc, "sloppy-assoc", 2, 0, 0,
0b5f3f34 118 (SCM key, SCM alist),
b380b885
MD
119 "Behaves like @code{assoc} but does not do any error checking.\n"
120 "Recommended only for use in Guile internals.")
1bbd0b84 121#define FUNC_NAME s_scm_sloppy_assoc
0f2d19dd 122{
0c95b57d 123 for (; SCM_CONSP (alist); alist = SCM_CDR (alist))
0f2d19dd 124 {
2de257bd 125 SCM tmp = SCM_CAR (alist);
0b5f3f34
GB
126 if (SCM_CONSP (tmp)
127 && SCM_NFALSEP (scm_equal_p (SCM_CAR (tmp), key)))
cf18adf0 128 return tmp;
0f2d19dd
JB
129 }
130 return SCM_BOOL_F;
131}
1bbd0b84 132#undef FUNC_NAME
0f2d19dd
JB
133
134
135\f
136
3b3b36dd 137SCM_DEFINE (scm_assq, "assq", 2, 0, 0,
0b5f3f34 138 (SCM key, SCM alist),
b380b885
MD
139 "@deffnx primitive assv key alist\n"
140 "@deffnx primitive assoc key alist\n"
141 "Fetches the entry in @var{alist} that is associated with @var{key}. To\n"
142 "decide whether the argument @var{key} matches a particular entry in\n"
143 "@var{alist}, @code{assq} compares keys with @code{eq?}, @code{assv}\n"
144 "uses @code{eqv?} and @code{assoc} uses @code{equal?}. If @var{key}\n"
145 "cannot be found in @var{alist} (according to whichever equality\n"
146 "predicate is in use), then @code{#f} is returned. These functions\n"
147 "return the entire alist entry found (i.e. both the key and the value).")
1bbd0b84 148#define FUNC_NAME s_scm_assq
0f2d19dd 149{
1aa621a3
MD
150 SCM ls = alist;
151 for (; SCM_CONSP (ls); ls = SCM_CDR (ls))
e1385ffc 152 {
1aa621a3
MD
153 SCM tmp = SCM_CAR (ls);
154 SCM_ASSERT_TYPE (SCM_CONSP (tmp), alist, SCM_ARG2, FUNC_NAME,
155 "association list");
fbd485ba 156 if (SCM_EQ_P (SCM_CAR (tmp), key))
2de257bd 157 return tmp;
e1385ffc 158 }
1aa621a3
MD
159 SCM_ASSERT_TYPE (SCM_NULLP (ls), alist, SCM_ARG2, FUNC_NAME,
160 "association list");
1bbd0b84 161 return SCM_BOOL_F;
0f2d19dd 162}
1bbd0b84 163#undef FUNC_NAME
0f2d19dd
JB
164
165
3b3b36dd 166SCM_DEFINE (scm_assv, "assv", 2, 0, 0,
0b5f3f34 167 (SCM key, SCM alist),
b380b885 168 "Behaves like @code{assq} but uses @code{eqv?} for key comparison.")
1bbd0b84 169#define FUNC_NAME s_scm_assv
0f2d19dd 170{
1aa621a3
MD
171 SCM ls = alist;
172 for(; SCM_CONSP (ls); ls = SCM_CDR (ls))
e1385ffc 173 {
1aa621a3
MD
174 SCM tmp = SCM_CAR (ls);
175 SCM_ASSERT_TYPE (SCM_CONSP (tmp), alist, SCM_ARG2, FUNC_NAME,
176 "association list");
2de257bd
MD
177 if (SCM_NFALSEP (scm_eqv_p (SCM_CAR (tmp), key)))
178 return tmp;
e1385ffc 179 }
1aa621a3
MD
180 SCM_ASSERT_TYPE (SCM_NULLP (ls), alist, SCM_ARG2, FUNC_NAME,
181 "association list");
0f2d19dd
JB
182 return SCM_BOOL_F;
183}
1bbd0b84 184#undef FUNC_NAME
0f2d19dd
JB
185
186
3b3b36dd 187SCM_DEFINE (scm_assoc, "assoc", 2, 0, 0,
0b5f3f34 188 (SCM key, SCM alist),
b380b885 189 "Behaves like @code{assq} but uses @code{equal?} for key comparison.")
1bbd0b84 190#define FUNC_NAME s_scm_assoc
0f2d19dd 191{
1aa621a3
MD
192 SCM ls = alist;
193 for(; SCM_CONSP (ls); ls = SCM_CDR (ls))
e1385ffc 194 {
1aa621a3
MD
195 SCM tmp = SCM_CAR (ls);
196 SCM_ASSERT_TYPE (SCM_CONSP (tmp), alist, SCM_ARG2, FUNC_NAME,
197 "association list");
2de257bd
MD
198 if (SCM_NFALSEP (scm_equal_p (SCM_CAR (tmp), key)))
199 return tmp;
e1385ffc 200 }
1aa621a3
MD
201 SCM_ASSERT_TYPE (SCM_NULLP (ls), alist, SCM_ARG2, FUNC_NAME,
202 "association list");
1bbd0b84 203 return SCM_BOOL_F;
0f2d19dd 204}
1bbd0b84 205#undef FUNC_NAME
0f2d19dd
JB
206
207
208\f
209
a1ec6916 210SCM_DEFINE (scm_assq_ref, "assq-ref", 2, 0, 0,
1bbd0b84 211 (SCM alist, SCM key),
b380b885
MD
212 "@deffnx primitive assv-ref alist key\n"
213 "@deffnx primitive assoc-ref alist key\n"
214 "Like @code{assq}, @code{assv} and @code{assoc}, except that only the\n"
215 "value associated with @var{key} in @var{alist} is returned. These\n"
216 "functions are equivalent to\n\n"
217 "@lisp\n"
218 "(let ((ent (@var{associator} @var{key} @var{alist})))\n"
219 " (and ent (cdr ent)))\n"
220 "@end lisp\n\n"
221 "where @var{associator} is one of @code{assq}, @code{assv} or @code{assoc}.")
1bbd0b84 222#define FUNC_NAME s_scm_assq_ref
0f2d19dd
JB
223{
224 SCM handle;
225
226 handle = scm_sloppy_assq (key, alist);
0c95b57d 227 if (SCM_CONSP (handle))
0f2d19dd
JB
228 {
229 return SCM_CDR (handle);
230 }
231 return SCM_BOOL_F;
232}
1bbd0b84 233#undef FUNC_NAME
0f2d19dd
JB
234
235
a1ec6916 236SCM_DEFINE (scm_assv_ref, "assv-ref", 2, 0, 0,
1bbd0b84 237 (SCM alist, SCM key),
b380b885 238 "Behaves like @code{assq-ref} but uses @code{eqv?} for key comparison.")
1bbd0b84 239#define FUNC_NAME s_scm_assv_ref
0f2d19dd
JB
240{
241 SCM handle;
242
243 handle = scm_sloppy_assv (key, alist);
0c95b57d 244 if (SCM_CONSP (handle))
0f2d19dd
JB
245 {
246 return SCM_CDR (handle);
247 }
248 return SCM_BOOL_F;
249}
1bbd0b84 250#undef FUNC_NAME
0f2d19dd
JB
251
252
a1ec6916 253SCM_DEFINE (scm_assoc_ref, "assoc-ref", 2, 0, 0,
1bbd0b84 254 (SCM alist, SCM key),
b380b885 255 "Behaves like @code{assq-ref} but uses @code{equal?} for key comparison.")
1bbd0b84 256#define FUNC_NAME s_scm_assoc_ref
0f2d19dd
JB
257{
258 SCM handle;
259
260 handle = scm_sloppy_assoc (key, alist);
0c95b57d 261 if (SCM_CONSP (handle))
0f2d19dd
JB
262 {
263 return SCM_CDR (handle);
264 }
265 return SCM_BOOL_F;
266}
1bbd0b84 267#undef FUNC_NAME
0f2d19dd
JB
268
269
270
271\f
272
273
a1ec6916 274SCM_DEFINE (scm_assq_set_x, "assq-set!", 3, 0, 0,
1bbd0b84 275 (SCM alist, SCM key, SCM val),
b380b885
MD
276 "@deffnx primitive assv-set! alist key value\n"
277 "@deffnx primitive assoc-set! alist key value\n"
278 "Reassociate @var{key} in @var{alist} with @var{value}: find any existing\n"
279 "@var{alist} entry for @var{key} and associate it with the new\n"
280 "@var{value}. If @var{alist} does not contain an entry for @var{key},\n"
281 "add a new one. Return the (possibly new) alist.\n\n"
282 "These functions do not attempt to verify the structure of @var{alist},\n"
283 "and so may cause unusual results if passed an object that is not an\n"
284 "association list.")
1bbd0b84 285#define FUNC_NAME s_scm_assq_set_x
0f2d19dd
JB
286{
287 SCM handle;
288
289 handle = scm_sloppy_assq (key, alist);
0c95b57d 290 if (SCM_CONSP (handle))
0f2d19dd
JB
291 {
292 SCM_SETCDR (handle, val);
293 return alist;
294 }
295 else
296 return scm_acons (key, val, alist);
297}
1bbd0b84 298#undef FUNC_NAME
0f2d19dd 299
a1ec6916 300SCM_DEFINE (scm_assv_set_x, "assv-set!", 3, 0, 0,
1bbd0b84 301 (SCM alist, SCM key, SCM val),
b380b885 302 "Behaves like @code{assq-set!} but uses @code{eqv?} for key comparison.")
1bbd0b84 303#define FUNC_NAME s_scm_assv_set_x
0f2d19dd
JB
304{
305 SCM handle;
306
307 handle = scm_sloppy_assv (key, alist);
0c95b57d 308 if (SCM_CONSP (handle))
0f2d19dd
JB
309 {
310 SCM_SETCDR (handle, val);
311 return alist;
312 }
313 else
314 return scm_acons (key, val, alist);
315}
1bbd0b84 316#undef FUNC_NAME
0f2d19dd 317
a1ec6916 318SCM_DEFINE (scm_assoc_set_x, "assoc-set!", 3, 0, 0,
1bbd0b84 319 (SCM alist, SCM key, SCM val),
b380b885 320 "Behaves like @code{assq-set!} but uses @code{equal?} for key comparison.")
1bbd0b84 321#define FUNC_NAME s_scm_assoc_set_x
0f2d19dd
JB
322{
323 SCM handle;
324
325 handle = scm_sloppy_assoc (key, alist);
0c95b57d 326 if (SCM_CONSP (handle))
0f2d19dd
JB
327 {
328 SCM_SETCDR (handle, val);
329 return alist;
330 }
331 else
332 return scm_acons (key, val, alist);
333}
1bbd0b84 334#undef FUNC_NAME
0f2d19dd
JB
335
336
337\f
338
a1ec6916 339SCM_DEFINE (scm_assq_remove_x, "assq-remove!", 2, 0, 0,
1bbd0b84 340 (SCM alist, SCM key),
b380b885
MD
341 "@deffnx primitive assv-remove! alist key\n"
342 "@deffnx primitive assoc-remove! alist key\n"
623ada63 343 "Delete the first entry in @var{alist} associated with @var{key}, and return\n"
b380b885 344 "the resulting alist.")
1bbd0b84 345#define FUNC_NAME s_scm_assq_remove_x
0f2d19dd
JB
346{
347 SCM handle;
348
349 handle = scm_sloppy_assq (key, alist);
623ada63 350 if (SCM_CONSP (handle))
60e61f0a 351 alist = scm_delq1_x (handle, alist);
623ada63 352
5d253852 353 return alist;
0f2d19dd 354}
1bbd0b84 355#undef FUNC_NAME
0f2d19dd
JB
356
357
a1ec6916 358SCM_DEFINE (scm_assv_remove_x, "assv-remove!", 2, 0, 0,
1bbd0b84 359 (SCM alist, SCM key),
b380b885 360 "Behaves like @code{assq-remove!} but uses @code{eqv?} for key comparison.")
1bbd0b84 361#define FUNC_NAME s_scm_assv_remove_x
0f2d19dd
JB
362{
363 SCM handle;
364
365 handle = scm_sloppy_assv (key, alist);
623ada63 366 if (SCM_CONSP (handle))
60e61f0a 367 alist = scm_delq1_x (handle, alist);
623ada63 368
5d253852 369 return alist;
0f2d19dd 370}
1bbd0b84 371#undef FUNC_NAME
0f2d19dd
JB
372
373
a1ec6916 374SCM_DEFINE (scm_assoc_remove_x, "assoc-remove!", 2, 0, 0,
1bbd0b84 375 (SCM alist, SCM key),
b380b885 376 "Behaves like @code{assq-remove!} but uses @code{equal?} for key comparison.")
1bbd0b84 377#define FUNC_NAME s_scm_assoc_remove_x
0f2d19dd
JB
378{
379 SCM handle;
380
381 handle = scm_sloppy_assoc (key, alist);
623ada63 382 if (SCM_CONSP (handle))
60e61f0a 383 alist = scm_delq1_x (handle, alist);
623ada63 384
5d253852 385 return alist;
0f2d19dd 386}
1bbd0b84 387#undef FUNC_NAME
0f2d19dd
JB
388
389
390\f
391
392
1cc91f1b 393
0f2d19dd
JB
394void
395scm_init_alist ()
0f2d19dd 396{
a0599745 397#include "libguile/alist.x"
0f2d19dd
JB
398}
399
89e00824
ML
400
401/*
402 Local Variables:
403 c-file-style: "gnu"
404 End:
405*/