* *.c: Finish replacing K&R style prototypes with ANSI C
[bpt/guile.git] / libguile / unif.c
1 /* Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
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
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
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.
40 * If you do not wish that, delete this exception notice. */
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
45 \f
46
47 #include <stdio.h>
48 #include "_scm.h"
49 #include "chars.h"
50 #include "eval.h"
51 #include "fports.h"
52 #include "smob.h"
53 #include "strop.h"
54 #include "feature.h"
55
56 #include "scm_validate.h"
57 #include "unif.h"
58 #include "ramap.h"
59
60 #ifdef HAVE_UNISTD_H
61 #include <unistd.h>
62 #endif
63
64 \f
65 /* The set of uniform scm_vector types is:
66 * Vector of: Called:
67 * unsigned char string
68 * char byvect
69 * boolean bvect
70 * signed long ivect
71 * unsigned long uvect
72 * float fvect
73 * double dvect
74 * complex double cvect
75 * short svect
76 * long long llvect
77 */
78
79 long scm_tc16_array;
80
81 /* return the size of an element in a uniform array or 0 if type not
82 found. */
83 scm_sizet
84 scm_uniform_element_size (SCM obj)
85 {
86 scm_sizet result;
87
88 switch (SCM_TYP7 (obj))
89 {
90 case scm_tc7_bvect:
91 case scm_tc7_uvect:
92 case scm_tc7_ivect:
93 result = sizeof (long);
94 break;
95
96 case scm_tc7_byvect:
97 result = sizeof (char);
98 break;
99
100 case scm_tc7_svect:
101 result = sizeof (short);
102 break;
103
104 #ifdef HAVE_LONG_LONGS
105 case scm_tc7_llvect:
106 result = sizeof (long_long);
107 break;
108 #endif
109
110 #ifdef SCM_FLOATS
111 #ifdef SCM_SINGLES
112 case scm_tc7_fvect:
113 result = sizeof (float);
114 break;
115 #endif
116
117 case scm_tc7_dvect:
118 result = sizeof (double);
119 break;
120
121 case scm_tc7_cvect:
122 result = 2 * sizeof (double);
123 break;
124 #endif
125
126 default:
127 result = 0;
128 }
129 return result;
130 }
131
132
133 #ifdef SCM_FLOATS
134 #ifdef SCM_SINGLES
135
136
137 SCM
138 scm_makflo (float x)
139 {
140 SCM z;
141 if (x == 0.0)
142 return scm_flo0;
143 SCM_NEWCELL (z);
144 SCM_DEFER_INTS;
145 SCM_SETCAR (z, scm_tc_flo);
146 SCM_FLO (z) = x;
147 SCM_ALLOW_INTS;
148 return z;
149 }
150 #endif
151 #endif
152
153
154 SCM
155 scm_make_uve (long k, SCM prot)
156 {
157 SCM v;
158 long i, type;
159 if (SCM_BOOL_T == prot)
160 {
161 i = sizeof (long) * ((k + SCM_LONG_BIT - 1) / SCM_LONG_BIT);
162 type = scm_tc7_bvect;
163 }
164 else if (SCM_ICHRP (prot) && (prot == SCM_MAKICHR ('\0')))
165 {
166 i = sizeof (char) * k;
167 type = scm_tc7_byvect;
168 }
169 else if (SCM_ICHRP (prot))
170 {
171 i = sizeof (char) * k;
172 type = scm_tc7_string;
173 }
174 else if (SCM_INUMP (prot))
175 {
176 i = sizeof (long) * k;
177 if (SCM_INUM (prot) > 0)
178 type = scm_tc7_uvect;
179 else
180 type = scm_tc7_ivect;
181 }
182 else if (SCM_NIMP (prot) && SCM_SYMBOLP (prot) && (1 == SCM_LENGTH (prot)))
183 {
184 char s;
185
186 s = SCM_CHARS (prot)[0];
187 if (s == 's')
188 {
189 i = sizeof (short) * k;
190 type = scm_tc7_svect;
191 }
192 #ifdef HAVE_LONG_LONGS
193 else if (s == 'l')
194 {
195 i = sizeof (long_long) * k;
196 type = scm_tc7_llvect;
197 }
198 #endif
199 else
200 {
201 return scm_make_vector (SCM_MAKINUM (k), SCM_UNDEFINED);
202 }
203 }
204 else
205 #ifdef SCM_FLOATS
206 if (SCM_IMP (prot) || !SCM_INEXP (prot))
207 #endif
208 /* Huge non-unif vectors are NOT supported. */
209 /* no special scm_vector */
210 return scm_make_vector (SCM_MAKINUM (k), SCM_UNDEFINED);
211 #ifdef SCM_FLOATS
212 #ifdef SCM_SINGLES
213 else if (SCM_SINGP (prot))
214
215 {
216 i = sizeof (float) * k;
217 type = scm_tc7_fvect;
218 }
219 #endif
220 else if (SCM_CPLXP (prot))
221 {
222 i = 2 * sizeof (double) * k;
223 type = scm_tc7_cvect;
224 }
225 else
226 {
227 i = sizeof (double) * k;
228 type = scm_tc7_dvect;
229 }
230 #endif
231
232 SCM_NEWCELL (v);
233 SCM_DEFER_INTS;
234 SCM_SETCHARS (v, (char *) scm_must_malloc (i ? i : 1, "vector"));
235 SCM_SETLENGTH (v, (k < SCM_LENGTH_MAX ? k : SCM_LENGTH_MAX), type);
236 SCM_ALLOW_INTS;
237 return v;
238 }
239
240 GUILE_PROC(scm_uniform_vector_length, "uniform-vector-length", 1, 0, 0,
241 (SCM v),
242 "")
243 #define FUNC_NAME s_scm_uniform_vector_length
244 {
245 SCM_ASRTGO (SCM_NIMP (v), badarg1);
246 switch SCM_TYP7
247 (v)
248 {
249 default:
250 badarg1:SCM_WTA(1,v);
251 case scm_tc7_bvect:
252 case scm_tc7_string:
253 case scm_tc7_byvect:
254 case scm_tc7_uvect:
255 case scm_tc7_ivect:
256 case scm_tc7_fvect:
257 case scm_tc7_dvect:
258 case scm_tc7_cvect:
259 case scm_tc7_vector:
260 case scm_tc7_wvect:
261 case scm_tc7_svect:
262 #ifdef HAVE_LONG_LONGS
263 case scm_tc7_llvect:
264 #endif
265 return SCM_MAKINUM (SCM_LENGTH (v));
266 }
267 }
268 #undef FUNC_NAME
269
270 GUILE_PROC(scm_array_p, "array?", 1, 1, 0,
271 (SCM v, SCM prot),
272 "")
273 #define FUNC_NAME s_scm_array_p
274 {
275 int nprot;
276 int enclosed;
277 nprot = SCM_UNBNDP (prot);
278 enclosed = 0;
279 if (SCM_IMP (v))
280 return SCM_BOOL_F;
281 loop:
282 switch (SCM_TYP7 (v))
283 {
284 case scm_tc7_smob:
285 if (!SCM_ARRAYP (v))
286 return SCM_BOOL_F;
287 if (nprot)
288 return SCM_BOOL_T;
289 if (enclosed++)
290 return SCM_BOOL_F;
291 v = SCM_ARRAY_V (v);
292 goto loop;
293 case scm_tc7_bvect:
294 return nprot || SCM_BOOL(SCM_BOOL_T==prot);
295 case scm_tc7_string:
296 return nprot || SCM_BOOL(SCM_ICHRP(prot) && (prot != SCM_MAKICHR('\0')));
297 case scm_tc7_byvect:
298 return nprot || SCM_BOOL(prot == SCM_MAKICHR('\0'));
299 case scm_tc7_uvect:
300 return nprot || SCM_BOOL(SCM_INUMP(prot) && SCM_INUM(prot)>0);
301 case scm_tc7_ivect:
302 return nprot || SCM_BOOL(SCM_INUMP(prot) && SCM_INUM(prot)<=0);
303 case scm_tc7_svect:
304 return ( nprot
305 || (SCM_NIMP (prot)
306 && SCM_SYMBOLP (prot)
307 && (1 == SCM_LENGTH (prot))
308 && ('s' == SCM_CHARS (prot)[0])));
309 #ifdef HAVE_LONG_LONGS
310 case scm_tc7_llvect:
311 return ( nprot
312 || (SCM_NIMP (prot)
313 && SCM_SYMBOLP (prot)
314 && (1 == SCM_LENGTH (prot))
315 && ('s' == SCM_CHARS (prot)[0])));
316 #endif
317 # ifdef SCM_FLOATS
318 # ifdef SCM_SINGLES
319 case scm_tc7_fvect:
320 return nprot || SCM_BOOL(SCM_NIMP(prot) && SCM_SINGP(prot));
321 # endif
322 case scm_tc7_dvect:
323 return nprot || SCM_BOOL(SCM_NIMP(prot) && SCM_REALP(prot));
324 case scm_tc7_cvect:
325 return nprot || SCM_BOOL(SCM_NIMP(prot) && SCM_CPLXP(prot));
326 # endif
327 case scm_tc7_vector:
328 case scm_tc7_wvect:
329 return nprot || SCM_BOOL(SCM_NULLP(prot));
330 default:;
331 }
332 return SCM_BOOL_F;
333 }
334 #undef FUNC_NAME
335
336
337 GUILE_PROC(scm_array_rank, "array-rank", 1, 0, 0,
338 (SCM ra),
339 "")
340 #define FUNC_NAME s_scm_array_rank
341 {
342 if (SCM_IMP (ra))
343 return SCM_INUM0;
344 switch (SCM_TYP7 (ra))
345 {
346 default:
347 return SCM_INUM0;
348 case scm_tc7_string:
349 case scm_tc7_vector:
350 case scm_tc7_wvect:
351 case scm_tc7_byvect:
352 case scm_tc7_uvect:
353 case scm_tc7_ivect:
354 case scm_tc7_fvect:
355 case scm_tc7_cvect:
356 case scm_tc7_dvect:
357 #ifdef HAVE_LONG_LONGS
358 case scm_tc7_llvect:
359 #endif
360 case scm_tc7_svect:
361 return SCM_MAKINUM (1L);
362 case scm_tc7_smob:
363 if (SCM_ARRAYP (ra))
364 return SCM_MAKINUM (SCM_ARRAY_NDIM (ra));
365 return SCM_INUM0;
366 }
367 }
368 #undef FUNC_NAME
369
370
371 GUILE_PROC(scm_array_dimensions, "array-dimensions", 1, 0, 0,
372 (SCM ra),
373 "")
374 #define FUNC_NAME s_scm_array_dimensions
375 {
376 SCM res = SCM_EOL;
377 scm_sizet k;
378 scm_array_dim *s;
379 if (SCM_IMP (ra))
380 return SCM_BOOL_F;
381 switch (SCM_TYP7 (ra))
382 {
383 default:
384 return SCM_BOOL_F;
385 case scm_tc7_string:
386 case scm_tc7_vector:
387 case scm_tc7_wvect:
388 case scm_tc7_bvect:
389 case scm_tc7_byvect:
390 case scm_tc7_uvect:
391 case scm_tc7_ivect:
392 case scm_tc7_fvect:
393 case scm_tc7_cvect:
394 case scm_tc7_dvect:
395 case scm_tc7_svect:
396 #ifdef HAVE_LONG_LONGS
397 case scm_tc7_llvect:
398 #endif
399 return scm_cons (SCM_MAKINUM (SCM_LENGTH (ra)), SCM_EOL);
400 case scm_tc7_smob:
401 if (!SCM_ARRAYP (ra))
402 return SCM_BOOL_F;
403 k = SCM_ARRAY_NDIM (ra);
404 s = SCM_ARRAY_DIMS (ra);
405 while (k--)
406 res = scm_cons (s[k].lbnd ? scm_cons2 (SCM_MAKINUM (s[k].lbnd), SCM_MAKINUM (s[k].ubnd), SCM_EOL) :
407 SCM_MAKINUM (1 + (s[k].ubnd))
408 , res);
409 return res;
410 }
411 }
412 #undef FUNC_NAME
413
414
415 static char s_bad_ind[] = "Bad scm_array index";
416
417
418 long
419 scm_aind (SCM ra, SCM args, const char *what)
420 {
421 SCM ind;
422 register long j;
423 register scm_sizet pos = SCM_ARRAY_BASE (ra);
424 register scm_sizet k = SCM_ARRAY_NDIM (ra);
425 scm_array_dim *s = SCM_ARRAY_DIMS (ra);
426 if (SCM_INUMP (args))
427 {
428 SCM_ASSERT (1 == k, scm_makfrom0str (what), SCM_WNA, NULL);
429 return pos + (SCM_INUM (args) - s->lbnd) * (s->inc);
430 }
431 while (k && SCM_NIMP (args))
432 {
433 ind = SCM_CAR (args);
434 args = SCM_CDR (args);
435 SCM_ASSERT (SCM_INUMP (ind), ind, s_bad_ind, what);
436 j = SCM_INUM (ind);
437 SCM_ASSERT (j >= (s->lbnd) && j <= (s->ubnd), ind, SCM_OUTOFRANGE, what);
438 pos += (j - s->lbnd) * (s->inc);
439 k--;
440 s++;
441 }
442 SCM_ASSERT (0 == k && SCM_NULLP (args), scm_makfrom0str (what), SCM_WNA,
443 NULL);
444 return pos;
445 }
446
447
448
449 SCM
450 scm_make_ra (int ndim)
451 {
452 SCM ra;
453 SCM_NEWCELL (ra);
454 SCM_DEFER_INTS;
455 SCM_NEWSMOB(ra, ((long) ndim << 17) + scm_tc16_array,
456 scm_must_malloc ((long) (sizeof (scm_array) + ndim * sizeof (scm_array_dim)),
457 "array"));
458 SCM_ARRAY_V (ra) = scm_nullvect;
459 SCM_ALLOW_INTS;
460 return ra;
461 }
462
463 static char s_bad_spec[] = "Bad scm_array dimension";
464 /* Increments will still need to be set. */
465
466
467 SCM
468 scm_shap2ra (SCM args, const char *what)
469 {
470 scm_array_dim *s;
471 SCM ra, spec, sp;
472 int ndim = scm_ilength (args);
473 SCM_ASSERT (0 <= ndim, args, s_bad_spec, what);
474 ra = scm_make_ra (ndim);
475 SCM_ARRAY_BASE (ra) = 0;
476 s = SCM_ARRAY_DIMS (ra);
477 for (; SCM_NIMP (args); s++, args = SCM_CDR (args))
478 {
479 spec = SCM_CAR (args);
480 if (SCM_IMP (spec))
481
482 {
483 SCM_ASSERT (SCM_INUMP (spec) && SCM_INUM (spec) >= 0, spec,
484 s_bad_spec, what);
485 s->lbnd = 0;
486 s->ubnd = SCM_INUM (spec) - 1;
487 s->inc = 1;
488 }
489 else
490 {
491 SCM_ASSERT (SCM_CONSP (spec) && SCM_INUMP (SCM_CAR (spec)), spec,
492 s_bad_spec, what);
493 s->lbnd = SCM_INUM (SCM_CAR (spec));
494 sp = SCM_CDR (spec);
495 SCM_ASSERT (SCM_NIMP (sp) && SCM_CONSP (sp)
496 && SCM_INUMP (SCM_CAR (sp)) && SCM_NULLP (SCM_CDR (sp)),
497 spec, s_bad_spec, what);
498 s->ubnd = SCM_INUM (SCM_CAR (sp));
499 s->inc = 1;
500 }
501 }
502 return ra;
503 }
504
505 GUILE_PROC(scm_dimensions_to_uniform_array, "dimensions->uniform-array", 2, 1, 0,
506 (SCM dims, SCM prot, SCM fill),
507 "")
508 #define FUNC_NAME s_scm_dimensions_to_uniform_array
509 {
510 scm_sizet k, vlen = 1;
511 long rlen = 1;
512 scm_array_dim *s;
513 SCM ra;
514 if (SCM_INUMP (dims))
515 {
516 if (SCM_INUM (dims) < SCM_LENGTH_MAX)
517 {
518 SCM answer = scm_make_uve (SCM_INUM (dims), prot);
519
520 if (!SCM_UNBNDP (fill))
521 scm_array_fill_x (answer, fill);
522 else if (SCM_NIMP (prot) && SCM_SYMBOLP (prot))
523 scm_array_fill_x (answer, SCM_MAKINUM (0));
524 else
525 scm_array_fill_x (answer, prot);
526 return answer;
527 }
528 else
529 dims = scm_cons (dims, SCM_EOL);
530 }
531 SCM_ASSERT (SCM_NULLP (dims) || (SCM_NIMP (dims) && SCM_CONSP (dims)),
532 dims, SCM_ARG1, FUNC_NAME);
533 ra = scm_shap2ra (dims, FUNC_NAME);
534 SCM_SETOR_CAR (ra, SCM_ARRAY_CONTIGUOUS);
535 s = SCM_ARRAY_DIMS (ra);
536 k = SCM_ARRAY_NDIM (ra);
537 while (k--)
538 {
539 s[k].inc = (rlen > 0 ? rlen : 0);
540 rlen = (s[k].ubnd - s[k].lbnd + 1) * s[k].inc;
541 vlen *= (s[k].ubnd - s[k].lbnd + 1);
542 }
543 if (rlen < SCM_LENGTH_MAX)
544 SCM_ARRAY_V (ra) = scm_make_uve ((rlen > 0 ? rlen : 0L), prot);
545 else
546 {
547 scm_sizet bit;
548 switch (SCM_TYP7 (scm_make_uve (0L, prot)))
549 {
550 default:
551 bit = SCM_LONG_BIT;
552 break;
553 case scm_tc7_bvect:
554 bit = 1;
555 break;
556 case scm_tc7_string:
557 bit = SCM_CHAR_BIT;
558 break;
559 case scm_tc7_fvect:
560 bit = sizeof (float) * SCM_CHAR_BIT / sizeof (char);
561 break;
562 case scm_tc7_dvect:
563 bit = sizeof (double) * SCM_CHAR_BIT / sizeof (char);
564 break;
565 case scm_tc7_cvect:
566 bit = 2 * sizeof (double) * SCM_CHAR_BIT / sizeof (char);
567 break;
568 }
569 SCM_ARRAY_BASE (ra) = (SCM_LONG_BIT + bit - 1) / bit;
570 rlen += SCM_ARRAY_BASE (ra);
571 SCM_ARRAY_V (ra) = scm_make_uve (rlen, prot);
572 *((long *) SCM_VELTS (SCM_ARRAY_V (ra))) = rlen;
573 }
574 if (!SCM_UNBNDP (fill))
575 {
576 scm_array_fill_x (ra, fill);
577 }
578 else if (SCM_NIMP (prot) && SCM_SYMBOLP (prot))
579 scm_array_fill_x (ra, SCM_MAKINUM (0));
580 else
581 scm_array_fill_x (ra, prot);
582 if (1 == SCM_ARRAY_NDIM (ra) && 0 == SCM_ARRAY_BASE (ra))
583 if (s->ubnd < s->lbnd || (0 == s->lbnd && 1 == s->inc))
584 return SCM_ARRAY_V (ra);
585 return ra;
586 }
587 #undef FUNC_NAME
588
589
590 void
591 scm_ra_set_contp (SCM ra)
592 {
593 scm_sizet k = SCM_ARRAY_NDIM (ra);
594 if (k)
595 {
596 long inc = SCM_ARRAY_DIMS (ra)[k - 1].inc;
597 while (k--)
598 {
599 if (inc != SCM_ARRAY_DIMS (ra)[k].inc)
600 {
601 SCM_SETAND_CAR (ra, ~SCM_ARRAY_CONTIGUOUS);
602 return;
603 }
604 inc *= (SCM_ARRAY_DIMS (ra)[k].ubnd
605 - SCM_ARRAY_DIMS (ra)[k].lbnd + 1);
606 }
607 }
608 SCM_SETOR_CAR (ra, SCM_ARRAY_CONTIGUOUS);
609 }
610
611
612 GUILE_PROC(scm_make_shared_array, "make-shared-array", 2, 0, 1,
613 (SCM oldra, SCM mapfunc, SCM dims),
614 "")
615 #define FUNC_NAME s_scm_make_shared_array
616 {
617 SCM ra;
618 SCM inds, indptr;
619 SCM imap;
620 scm_sizet i, k;
621 long old_min, new_min, old_max, new_max;
622 scm_array_dim *s;
623 SCM_VALIDATE_ARRAY(1,oldra);
624 SCM_VALIDATE_PROC(2,mapfunc);
625 ra = scm_shap2ra (dims, FUNC_NAME);
626 if (SCM_ARRAYP (oldra))
627 {
628 SCM_ARRAY_V (ra) = SCM_ARRAY_V (oldra);
629 old_min = old_max = SCM_ARRAY_BASE (oldra);
630 s = SCM_ARRAY_DIMS (oldra);
631 k = SCM_ARRAY_NDIM (oldra);
632 while (k--)
633 {
634 if (s[k].inc > 0)
635 old_max += (s[k].ubnd - s[k].lbnd) * s[k].inc;
636 else
637 old_min += (s[k].ubnd - s[k].lbnd) * s[k].inc;
638 }
639 }
640 else
641 {
642 SCM_ARRAY_V (ra) = oldra;
643 old_min = 0;
644 old_max = (long) SCM_LENGTH (oldra) - 1;
645 }
646 inds = SCM_EOL;
647 s = SCM_ARRAY_DIMS (ra);
648 for (k = 0; k < SCM_ARRAY_NDIM (ra); k++)
649 {
650 inds = scm_cons (SCM_MAKINUM (s[k].lbnd), inds);
651 if (s[k].ubnd < s[k].lbnd)
652 {
653 if (1 == SCM_ARRAY_NDIM (ra))
654 ra = scm_make_uve (0L, scm_array_prototype (ra));
655 else
656 SCM_ARRAY_V (ra) = scm_make_uve (0L, scm_array_prototype (ra));
657 return ra;
658 }
659 }
660 imap = scm_apply (mapfunc, scm_reverse (inds), SCM_EOL);
661 if (SCM_ARRAYP (oldra))
662 i = (scm_sizet) scm_aind (oldra, imap, FUNC_NAME);
663 else
664 {
665 if (SCM_NINUMP (imap))
666
667 {
668 SCM_ASSERT (1 == scm_ilength (imap) && SCM_INUMP (SCM_CAR (imap)),
669 imap, s_bad_ind, FUNC_NAME);
670 imap = SCM_CAR (imap);
671 }
672 i = SCM_INUM (imap);
673 }
674 SCM_ARRAY_BASE (ra) = new_min = new_max = i;
675 indptr = inds;
676 k = SCM_ARRAY_NDIM (ra);
677 while (k--)
678 {
679 if (s[k].ubnd > s[k].lbnd)
680 {
681 SCM_SETCAR (indptr, SCM_MAKINUM (SCM_INUM (SCM_CAR (indptr)) + 1));
682 imap = scm_apply (mapfunc, scm_reverse (inds), SCM_EOL);
683 if (SCM_ARRAYP (oldra))
684
685 s[k].inc = scm_aind (oldra, imap, FUNC_NAME) - i;
686 else
687 {
688 if (SCM_NINUMP (imap))
689
690 {
691 SCM_ASSERT (1 == scm_ilength (imap) && SCM_INUMP (SCM_CAR (imap)),
692 imap, s_bad_ind, FUNC_NAME);
693 imap = SCM_CAR (imap);
694 }
695 s[k].inc = (long) SCM_INUM (imap) - i;
696 }
697 i += s[k].inc;
698 if (s[k].inc > 0)
699 new_max += (s[k].ubnd - s[k].lbnd) * s[k].inc;
700 else
701 new_min += (s[k].ubnd - s[k].lbnd) * s[k].inc;
702 }
703 else
704 s[k].inc = new_max - new_min + 1; /* contiguous by default */
705 indptr = SCM_CDR (indptr);
706 }
707 SCM_ASSERT (old_min <= new_min && old_max >= new_max, SCM_UNDEFINED,
708 "mapping out of range", FUNC_NAME);
709 if (1 == SCM_ARRAY_NDIM (ra) && 0 == SCM_ARRAY_BASE (ra))
710 {
711 if (1 == s->inc && 0 == s->lbnd
712 && SCM_LENGTH (SCM_ARRAY_V (ra)) == 1 + s->ubnd)
713 return SCM_ARRAY_V (ra);
714 if (s->ubnd < s->lbnd)
715 return scm_make_uve (0L, scm_array_prototype (ra));
716 }
717 scm_ra_set_contp (ra);
718 return ra;
719 }
720 #undef FUNC_NAME
721
722
723 /* args are RA . DIMS */
724 GUILE_PROC(scm_transpose_array, "transpose-array", 0, 0, 1,
725 (SCM args),
726 "")
727 #define FUNC_NAME s_scm_transpose_array
728 {
729 SCM ra, res, vargs, *ve = &vargs;
730 scm_array_dim *s, *r;
731 int ndim, i, k;
732 SCM_ASSERT (SCM_NNULLP (args), scm_makfrom0str (FUNC_NAME),
733 SCM_WNA, NULL);
734 ra = SCM_CAR (args);
735 SCM_ASSERT (SCM_NIMP (ra), ra, SCM_ARG1, FUNC_NAME);
736 args = SCM_CDR (args);
737 switch (SCM_TYP7 (ra))
738 {
739 default:
740 badarg:SCM_WTA (1,ra);
741 case scm_tc7_bvect:
742 case scm_tc7_string:
743 case scm_tc7_byvect:
744 case scm_tc7_uvect:
745 case scm_tc7_ivect:
746 case scm_tc7_fvect:
747 case scm_tc7_dvect:
748 case scm_tc7_cvect:
749 case scm_tc7_svect:
750 #ifdef HAVE_LONG_LONGS
751 case scm_tc7_llvect:
752 #endif
753 SCM_ASSERT (SCM_NIMP (args) && SCM_NULLP (SCM_CDR (args)),
754 scm_makfrom0str (FUNC_NAME), SCM_WNA, NULL);
755 SCM_ASSERT (SCM_INUMP (SCM_CAR (args)), SCM_CAR (args), SCM_ARG2,
756 FUNC_NAME);
757 SCM_ASSERT (SCM_INUM0 == SCM_CAR (args), SCM_CAR (args), SCM_OUTOFRANGE,
758 FUNC_NAME);
759 return ra;
760 case scm_tc7_smob:
761 SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
762 vargs = scm_vector (args);
763 SCM_ASSERT (SCM_LENGTH (vargs) == SCM_ARRAY_NDIM (ra),
764 scm_makfrom0str (FUNC_NAME), SCM_WNA, NULL);
765 ve = SCM_VELTS (vargs);
766 ndim = 0;
767 for (k = 0; k < SCM_ARRAY_NDIM (ra); k++)
768 {
769 SCM_ASSERT (SCM_INUMP (ve[k]), ve[k], (SCM_ARG2 + k),
770 FUNC_NAME);
771 i = SCM_INUM (ve[k]);
772 SCM_ASSERT (i >= 0 && i < SCM_ARRAY_NDIM (ra), ve[k],
773 SCM_OUTOFRANGE, FUNC_NAME);
774 if (ndim < i)
775 ndim = i;
776 }
777 ndim++;
778 res = scm_make_ra (ndim);
779 SCM_ARRAY_V (res) = SCM_ARRAY_V (ra);
780 SCM_ARRAY_BASE (res) = SCM_ARRAY_BASE (ra);
781 for (k = ndim; k--;)
782 {
783 SCM_ARRAY_DIMS (res)[k].lbnd = 0;
784 SCM_ARRAY_DIMS (res)[k].ubnd = -1;
785 }
786 for (k = SCM_ARRAY_NDIM (ra); k--;)
787 {
788 i = SCM_INUM (ve[k]);
789 s = &(SCM_ARRAY_DIMS (ra)[k]);
790 r = &(SCM_ARRAY_DIMS (res)[i]);
791 if (r->ubnd < r->lbnd)
792 {
793 r->lbnd = s->lbnd;
794 r->ubnd = s->ubnd;
795 r->inc = s->inc;
796 ndim--;
797 }
798 else
799 {
800 if (r->ubnd > s->ubnd)
801 r->ubnd = s->ubnd;
802 if (r->lbnd < s->lbnd)
803 {
804 SCM_ARRAY_BASE (res) += (s->lbnd - r->lbnd) * r->inc;
805 r->lbnd = s->lbnd;
806 }
807 r->inc += s->inc;
808 }
809 }
810 SCM_ASSERT (ndim <= 0, args, "bad argument list", FUNC_NAME);
811 scm_ra_set_contp (res);
812 return res;
813 }
814 }
815 #undef FUNC_NAME
816
817 /* args are RA . AXES */
818 GUILE_PROC(scm_enclose_array, "enclose-array", 0, 0, 1,
819 (SCM axes),
820 "")
821 #define FUNC_NAME s_scm_enclose_array
822 {
823 SCM axv, ra, res, ra_inr;
824 scm_array_dim vdim, *s = &vdim;
825 int ndim, j, k, ninr, noutr;
826 SCM_ASSERT (SCM_NIMP (axes), scm_makfrom0str (FUNC_NAME), SCM_WNA,
827 NULL);
828 ra = SCM_CAR (axes);
829 axes = SCM_CDR (axes);
830 if (SCM_NULLP (axes))
831 axes = scm_cons ((SCM_ARRAYP (ra) ? SCM_MAKINUM (SCM_ARRAY_NDIM (ra) - 1) : SCM_INUM0), SCM_EOL);
832 ninr = scm_ilength (axes);
833 ra_inr = scm_make_ra (ninr);
834 SCM_ASRTGO (SCM_NIMP (ra), badarg1);
835 switch SCM_TYP7
836 (ra)
837 {
838 default:
839 badarg1:SCM_WTA (1,ra);
840 case scm_tc7_string:
841 case scm_tc7_bvect:
842 case scm_tc7_byvect:
843 case scm_tc7_uvect:
844 case scm_tc7_ivect:
845 case scm_tc7_fvect:
846 case scm_tc7_dvect:
847 case scm_tc7_cvect:
848 case scm_tc7_vector:
849 case scm_tc7_wvect:
850 case scm_tc7_svect:
851 #ifdef HAVE_LONG_LONGS
852 case scm_tc7_llvect:
853 #endif
854 s->lbnd = 0;
855 s->ubnd = SCM_LENGTH (ra) - 1;
856 s->inc = 1;
857 SCM_ARRAY_V (ra_inr) = ra;
858 SCM_ARRAY_BASE (ra_inr) = 0;
859 ndim = 1;
860 break;
861 case scm_tc7_smob:
862 SCM_ASRTGO (SCM_ARRAYP (ra), badarg1);
863 s = SCM_ARRAY_DIMS (ra);
864 SCM_ARRAY_V (ra_inr) = SCM_ARRAY_V (ra);
865 SCM_ARRAY_BASE (ra_inr) = SCM_ARRAY_BASE (ra);
866 ndim = SCM_ARRAY_NDIM (ra);
867 break;
868 }
869 noutr = ndim - ninr;
870 axv = scm_make_string (SCM_MAKINUM (ndim), SCM_MAKICHR (0));
871 SCM_ASSERT (0 <= noutr && 0 <= ninr, scm_makfrom0str (FUNC_NAME),
872 SCM_WNA, NULL);
873 res = scm_make_ra (noutr);
874 SCM_ARRAY_BASE (res) = SCM_ARRAY_BASE (ra_inr);
875 SCM_ARRAY_V (res) = ra_inr;
876 for (k = 0; k < ninr; k++, axes = SCM_CDR (axes))
877 {
878 SCM_ASSERT (SCM_INUMP (SCM_CAR (axes)), SCM_CAR (axes), "bad axis", FUNC_NAME);
879 j = SCM_INUM (SCM_CAR (axes));
880 SCM_ARRAY_DIMS (ra_inr)[k].lbnd = s[j].lbnd;
881 SCM_ARRAY_DIMS (ra_inr)[k].ubnd = s[j].ubnd;
882 SCM_ARRAY_DIMS (ra_inr)[k].inc = s[j].inc;
883 SCM_CHARS (axv)[j] = 1;
884 }
885 for (j = 0, k = 0; k < noutr; k++, j++)
886 {
887 while (SCM_CHARS (axv)[j])
888 j++;
889 SCM_ARRAY_DIMS (res)[k].lbnd = s[j].lbnd;
890 SCM_ARRAY_DIMS (res)[k].ubnd = s[j].ubnd;
891 SCM_ARRAY_DIMS (res)[k].inc = s[j].inc;
892 }
893 scm_ra_set_contp (ra_inr);
894 scm_ra_set_contp (res);
895 return res;
896 }
897 #undef FUNC_NAME
898
899
900
901 GUILE_PROC(scm_array_in_bounds_p, "array-in-bounds?", 0, 0, 1,
902 (SCM args),
903 "")
904 #define FUNC_NAME s_scm_array_in_bounds_p
905 {
906 SCM v, ind = SCM_EOL;
907 long pos = 0;
908 register scm_sizet k;
909 register long j;
910 scm_array_dim *s;
911 SCM_ASSERT (SCM_NIMP (args), scm_makfrom0str (FUNC_NAME),
912 SCM_WNA, NULL);
913 v = SCM_CAR (args);
914 args = SCM_CDR (args);
915 SCM_ASRTGO (SCM_NIMP (v), badarg1);
916 if (SCM_NIMP (args))
917
918 {
919 ind = SCM_CAR (args);
920 args = SCM_CDR (args);
921 SCM_ASSERT (SCM_INUMP (ind), ind, SCM_ARG2, FUNC_NAME);
922 pos = SCM_INUM (ind);
923 }
924 tail:
925 switch SCM_TYP7
926 (v)
927 {
928 default:
929 badarg1:SCM_WTA (1,v);
930 wna: scm_wrong_num_args (scm_makfrom0str (FUNC_NAME));
931 case scm_tc7_smob:
932 k = SCM_ARRAY_NDIM (v);
933 s = SCM_ARRAY_DIMS (v);
934 pos = SCM_ARRAY_BASE (v);
935 if (!k)
936 {
937 SCM_ASRTGO (SCM_NULLP (ind), wna);
938 ind = SCM_INUM0;
939 }
940 else
941 while (!0)
942 {
943 j = SCM_INUM (ind);
944 if (!(j >= (s->lbnd) && j <= (s->ubnd)))
945 {
946 SCM_ASRTGO (--k == scm_ilength (args), wna);
947 return SCM_BOOL_F;
948 }
949 pos += (j - s->lbnd) * (s->inc);
950 if (!(--k && SCM_NIMP (args)))
951 break;
952 ind = SCM_CAR (args);
953 args = SCM_CDR (args);
954 s++;
955 SCM_ASSERT (SCM_INUMP (ind), ind, s_bad_ind, FUNC_NAME);
956 }
957 SCM_ASRTGO (0 == k, wna);
958 v = SCM_ARRAY_V (v);
959 goto tail;
960 case scm_tc7_bvect:
961 case scm_tc7_string:
962 case scm_tc7_byvect:
963 case scm_tc7_uvect:
964 case scm_tc7_ivect:
965 case scm_tc7_fvect:
966 case scm_tc7_dvect:
967 case scm_tc7_cvect:
968 case scm_tc7_svect:
969 #ifdef HAVE_LONG_LONGS
970 case scm_tc7_llvect:
971 #endif
972 case scm_tc7_vector:
973 case scm_tc7_wvect:
974 SCM_ASRTGO (SCM_NULLP (args) && SCM_INUMP (ind), wna);
975 return SCM_BOOL(pos >= 0 && pos < SCM_LENGTH (v));
976 }
977 }
978 #undef FUNC_NAME
979
980
981 SCM_REGISTER_PROC(s_array_ref, "array-ref", 1, 0, 1, scm_uniform_vector_ref);
982
983
984 GUILE_PROC(scm_uniform_vector_ref, "uniform-vector-ref", 2, 0, 0,
985 (SCM v, SCM args),
986 "")
987 #define FUNC_NAME s_scm_uniform_vector_ref
988 {
989 long pos;
990
991 if (SCM_IMP (v))
992 {
993 SCM_ASRTGO (SCM_NULLP (args), badarg);
994 return v;
995 }
996 else if (SCM_ARRAYP (v))
997 {
998 pos = scm_aind (v, args, FUNC_NAME);
999 v = SCM_ARRAY_V (v);
1000 }
1001 else
1002 {
1003 if (SCM_NIMP (args))
1004
1005 {
1006 SCM_ASSERT (SCM_CONSP (args) && SCM_INUMP (SCM_CAR (args)), args, SCM_ARG2, FUNC_NAME);
1007 pos = SCM_INUM (SCM_CAR (args));
1008 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args)), wna);
1009 }
1010 else
1011 {
1012 SCM_VALIDATE_INT(2,args);
1013 pos = SCM_INUM (args);
1014 }
1015 SCM_ASRTGO (pos >= 0 && pos < SCM_LENGTH (v), outrng);
1016 }
1017 switch SCM_TYP7
1018 (v)
1019 {
1020 default:
1021 if (SCM_NULLP (args))
1022 return v;
1023 badarg:
1024 SCM_WTA (1,v);
1025 abort ();
1026 outrng:scm_out_of_range (FUNC_NAME, SCM_MAKINUM (pos));
1027 wna: scm_wrong_num_args (SCM_FUNC_NAME);
1028 case scm_tc7_smob:
1029 { /* enclosed */
1030 int k = SCM_ARRAY_NDIM (v);
1031 SCM res = scm_make_ra (k);
1032 SCM_ARRAY_V (res) = SCM_ARRAY_V (v);
1033 SCM_ARRAY_BASE (res) = pos;
1034 while (k--)
1035 {
1036 SCM_ARRAY_DIMS (res)[k].lbnd = SCM_ARRAY_DIMS (v)[k].lbnd;
1037 SCM_ARRAY_DIMS (res)[k].ubnd = SCM_ARRAY_DIMS (v)[k].ubnd;
1038 SCM_ARRAY_DIMS (res)[k].inc = SCM_ARRAY_DIMS (v)[k].inc;
1039 }
1040 return res;
1041 }
1042 case scm_tc7_bvect:
1043 if (SCM_VELTS (v)[pos / SCM_LONG_BIT] & (1L << (pos % SCM_LONG_BIT)))
1044 return SCM_BOOL_T;
1045 else
1046 return SCM_BOOL_F;
1047 case scm_tc7_string:
1048 return SCM_MAKICHR (SCM_UCHARS (v)[pos]);
1049 case scm_tc7_byvect:
1050 return SCM_MAKINUM (((char *)SCM_CHARS (v))[pos]);
1051 # ifdef SCM_INUMS_ONLY
1052 case scm_tc7_uvect:
1053 case scm_tc7_ivect:
1054 return SCM_MAKINUM (SCM_VELTS (v)[pos]);
1055 # else
1056 case scm_tc7_uvect:
1057 return scm_ulong2num(SCM_VELTS(v)[pos]);
1058 case scm_tc7_ivect:
1059 return scm_long2num(SCM_VELTS(v)[pos]);
1060 # endif
1061
1062 case scm_tc7_svect:
1063 return SCM_MAKINUM (((short *) SCM_CDR (v))[pos]);
1064 #ifdef HAVE_LONG_LONGS
1065 case scm_tc7_llvect:
1066 return scm_long_long2num (((long_long *) SCM_CDR (v))[pos]);
1067 #endif
1068
1069 #ifdef SCM_FLOATS
1070 #ifdef SCM_SINGLES
1071 case scm_tc7_fvect:
1072 return scm_makflo (((float *) SCM_CDR (v))[pos]);
1073 #endif
1074 case scm_tc7_dvect:
1075 return scm_makdbl (((double *) SCM_CDR (v))[pos], 0.0);
1076 case scm_tc7_cvect:
1077 return scm_makdbl (((double *) SCM_CDR (v))[2 * pos],
1078 ((double *) SCM_CDR (v))[2 * pos + 1]);
1079 #endif
1080 case scm_tc7_vector:
1081 case scm_tc7_wvect:
1082 return SCM_VELTS (v)[pos];
1083 }
1084 }
1085 #undef FUNC_NAME
1086
1087 /* Internal version of scm_uniform_vector_ref for uves that does no error checking and
1088 tries to recycle conses. (Make *sure* you want them recycled.) */
1089
1090 SCM
1091 scm_cvref (SCM v, scm_sizet pos, SCM last)
1092 {
1093 switch SCM_TYP7 (v)
1094 {
1095 default:
1096 scm_wta (v, (char *) SCM_ARG1, "PROGRAMMING ERROR: scm_cvref");
1097 case scm_tc7_bvect:
1098 if (SCM_VELTS (v)[pos / SCM_LONG_BIT] & (1L << (pos % SCM_LONG_BIT)))
1099 return SCM_BOOL_T;
1100 else
1101 return SCM_BOOL_F;
1102 case scm_tc7_string:
1103 return SCM_MAKICHR (SCM_UCHARS (v)[pos]);
1104 case scm_tc7_byvect:
1105 return SCM_MAKINUM (((char *)SCM_CHARS (v))[pos]);
1106 # ifdef SCM_INUMS_ONLY
1107 case scm_tc7_uvect:
1108 case scm_tc7_ivect:
1109 return SCM_MAKINUM (SCM_VELTS (v)[pos]);
1110 # else
1111 case scm_tc7_uvect:
1112 return scm_ulong2num(SCM_VELTS(v)[pos]);
1113 case scm_tc7_ivect:
1114 return scm_long2num(SCM_VELTS(v)[pos]);
1115 # endif
1116 case scm_tc7_svect:
1117 return SCM_MAKINUM (((short *) SCM_CDR (v))[pos]);
1118 #ifdef HAVE_LONG_LONGS
1119 case scm_tc7_llvect:
1120 return scm_long_long2num (((long_long *) SCM_CDR (v))[pos]);
1121 #endif
1122 #ifdef SCM_FLOATS
1123 #ifdef SCM_SINGLES
1124 case scm_tc7_fvect:
1125 if (SCM_NIMP (last) && (last != scm_flo0) && (scm_tc_flo == SCM_CAR (last)))
1126 {
1127 SCM_FLO (last) = ((float *) SCM_CDR (v))[pos];
1128 return last;
1129 }
1130 return scm_makflo (((float *) SCM_CDR (v))[pos]);
1131 #endif
1132 case scm_tc7_dvect:
1133 #ifdef SCM_SINGLES
1134 if (SCM_NIMP (last) && scm_tc_dblr == SCM_CAR (last))
1135 #else
1136 if (SCM_NIMP (last) && (last != scm_flo0) && (scm_tc_dblr == SCM_CAR (last)))
1137 #endif
1138 {
1139 SCM_REAL (last) = ((double *) SCM_CDR (v))[pos];
1140 return last;
1141 }
1142 return scm_makdbl (((double *) SCM_CDR (v))[pos], 0.0);
1143 case scm_tc7_cvect:
1144 if (SCM_NIMP (last) && scm_tc_dblc == SCM_CAR (last))
1145 {
1146 SCM_REAL (last) = ((double *) SCM_CDR (v))[2 * pos];
1147 SCM_IMAG (last) = ((double *) SCM_CDR (v))[2 * pos + 1];
1148 return last;
1149 }
1150 return scm_makdbl (((double *) SCM_CDR (v))[2 * pos],
1151 ((double *) SCM_CDR (v))[2 * pos + 1]);
1152 #endif
1153 case scm_tc7_vector:
1154 case scm_tc7_wvect:
1155 return SCM_VELTS (v)[pos];
1156 case scm_tc7_smob:
1157 { /* enclosed scm_array */
1158 int k = SCM_ARRAY_NDIM (v);
1159 SCM res = scm_make_ra (k);
1160 SCM_ARRAY_V (res) = SCM_ARRAY_V (v);
1161 SCM_ARRAY_BASE (res) = pos;
1162 while (k--)
1163 {
1164 SCM_ARRAY_DIMS (res)[k].ubnd = SCM_ARRAY_DIMS (v)[k].ubnd;
1165 SCM_ARRAY_DIMS (res)[k].lbnd = SCM_ARRAY_DIMS (v)[k].lbnd;
1166 SCM_ARRAY_DIMS (res)[k].inc = SCM_ARRAY_DIMS (v)[k].inc;
1167 }
1168 return res;
1169 }
1170 }
1171 }
1172
1173 SCM_REGISTER_PROC(s_uniform_array_set1_x, "uniform-array-set1!", 3, 0, 0, scm_array_set_x);
1174
1175
1176 /* Note that args may be a list or an immediate object, depending which
1177 PROC is used (and it's called from C too). */
1178 GUILE_PROC(scm_array_set_x, "array-set!", 2, 0, 1,
1179 (SCM v, SCM obj, SCM args),
1180 "")
1181 #define FUNC_NAME s_scm_array_set_x
1182 {
1183 long pos = 0;
1184 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1185 if (SCM_ARRAYP (v))
1186 {
1187 pos = scm_aind (v, args, FUNC_NAME);
1188 v = SCM_ARRAY_V (v);
1189 }
1190 else
1191 {
1192 if (SCM_NIMP (args))
1193 {
1194 SCM_ASSERT (SCM_CONSP(args) && SCM_INUMP (SCM_CAR (args)), args,
1195 SCM_ARG3, FUNC_NAME);
1196 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args)), wna);
1197 pos = SCM_INUM (SCM_CAR (args));
1198 }
1199 else
1200 {
1201 SCM_VALIDATE_INT_COPY(3,args,pos);
1202 }
1203 SCM_ASRTGO (pos >= 0 && pos < SCM_LENGTH (v), outrng);
1204 }
1205 switch (SCM_TYP7 (v))
1206 {
1207 default: badarg1:
1208 SCM_WTA (1,v);
1209 abort ();
1210 outrng:scm_out_of_range (FUNC_NAME, SCM_MAKINUM (pos));
1211 wna: scm_wrong_num_args (SCM_FUNC_NAME);
1212 case scm_tc7_smob: /* enclosed */
1213 goto badarg1;
1214 case scm_tc7_bvect:
1215 if (SCM_BOOL_F == obj)
1216 SCM_VELTS (v)[pos / SCM_LONG_BIT] &= ~(1L << (pos % SCM_LONG_BIT));
1217 else if (SCM_BOOL_T == obj)
1218 SCM_VELTS (v)[pos / SCM_LONG_BIT] |= (1L << (pos % SCM_LONG_BIT));
1219 else
1220 badobj:SCM_WTA (2,obj);
1221 break;
1222 case scm_tc7_string:
1223 SCM_ASRTGO (SCM_ICHRP (obj), badobj);
1224 SCM_UCHARS (v)[pos] = SCM_ICHR (obj);
1225 break;
1226 case scm_tc7_byvect:
1227 if (SCM_ICHRP (obj))
1228 obj = SCM_MAKINUM ((char) SCM_ICHR (obj));
1229 SCM_ASRTGO (SCM_INUMP (obj), badobj);
1230 ((char *)SCM_CHARS (v))[pos] = SCM_INUM (obj);
1231 break;
1232 # ifdef SCM_INUMS_ONLY
1233 case scm_tc7_uvect:
1234 SCM_ASRTGO (SCM_INUM (obj) >= 0, badobj);
1235 /* fall through */
1236 case scm_tc7_ivect:
1237 SCM_ASRTGO(SCM_INUMP(obj), badobj); SCM_VELTS(v)[pos] = SCM_INUM(obj); break;
1238 # else
1239 case scm_tc7_uvect:
1240 SCM_VELTS(v)[pos] = scm_num2ulong(obj, (char *)SCM_ARG2, FUNC_NAME); break;
1241 case scm_tc7_ivect:
1242 SCM_VELTS(v)[pos] = scm_num2long(obj, (char *)SCM_ARG2, FUNC_NAME); break;
1243 # endif
1244 case scm_tc7_svect:
1245 SCM_ASRTGO (SCM_INUMP (obj), badobj);
1246 ((short *) SCM_CDR (v))[pos] = SCM_INUM (obj);
1247 break;
1248 #ifdef HAVE_LONG_LONGS
1249 case scm_tc7_llvect:
1250 ((long_long *) SCM_CDR (v))[pos] = scm_num2long_long (obj, (char *)SCM_ARG2, FUNC_NAME);
1251 break;
1252 #endif
1253
1254
1255 #ifdef SCM_FLOATS
1256 #ifdef SCM_SINGLES
1257 case scm_tc7_fvect:
1258 ((float *) SCM_CDR (v))[pos] = (float)scm_num2dbl(obj, FUNC_NAME); break;
1259 break;
1260 #endif
1261 case scm_tc7_dvect:
1262 ((double *) SCM_CDR (v))[pos] = scm_num2dbl(obj, FUNC_NAME); break;
1263 break;
1264 case scm_tc7_cvect:
1265 SCM_ASRTGO (SCM_NIMP (obj) && SCM_INEXP (obj), badobj);
1266 ((double *) SCM_CDR (v))[2 * pos] = SCM_REALPART (obj);
1267 ((double *) SCM_CDR (v))[2 * pos + 1] = SCM_CPLXP (obj) ? SCM_IMAG (obj) : 0.0;
1268 break;
1269 #endif
1270 case scm_tc7_vector:
1271 case scm_tc7_wvect:
1272 SCM_VELTS (v)[pos] = obj;
1273 break;
1274 }
1275 return SCM_UNSPECIFIED;
1276 }
1277 #undef FUNC_NAME
1278
1279 /* attempts to unroll an array into a one-dimensional array.
1280 returns the unrolled array or #f if it can't be done. */
1281 /* if strict is not SCM_UNDEFINED, return #f if returned array
1282 wouldn't have contiguous elements. */
1283 GUILE_PROC(scm_array_contents, "array-contents", 1, 1, 0,
1284 (SCM ra, SCM strict),
1285 "")
1286 #define FUNC_NAME s_scm_array_contents
1287 {
1288 SCM sra;
1289 if (SCM_IMP (ra))
1290 return SCM_BOOL_F;
1291 switch SCM_TYP7 (ra)
1292 {
1293 default:
1294 return SCM_BOOL_F;
1295 case scm_tc7_vector:
1296 case scm_tc7_wvect:
1297 case scm_tc7_string:
1298 case scm_tc7_bvect:
1299 case scm_tc7_byvect:
1300 case scm_tc7_uvect:
1301 case scm_tc7_ivect:
1302 case scm_tc7_fvect:
1303 case scm_tc7_dvect:
1304 case scm_tc7_cvect:
1305 case scm_tc7_svect:
1306 #ifdef HAVE_LONG_LONGS
1307 case scm_tc7_llvect:
1308 #endif
1309 return ra;
1310 case scm_tc7_smob:
1311 {
1312 scm_sizet k, ndim = SCM_ARRAY_NDIM (ra), len = 1;
1313 if (!SCM_ARRAYP (ra) || !SCM_ARRAY_CONTP (ra))
1314 return SCM_BOOL_F;
1315 for (k = 0; k < ndim; k++)
1316 len *= SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1;
1317 if (!SCM_UNBNDP (strict))
1318 {
1319 if (ndim && (1 != SCM_ARRAY_DIMS (ra)[ndim - 1].inc))
1320 return SCM_BOOL_F;
1321 if (scm_tc7_bvect == SCM_TYP7 (SCM_ARRAY_V (ra)))
1322 {
1323 if (len != SCM_LENGTH (SCM_ARRAY_V (ra)) ||
1324 SCM_ARRAY_BASE (ra) % SCM_LONG_BIT ||
1325 len % SCM_LONG_BIT)
1326 return SCM_BOOL_F;
1327 }
1328 }
1329 if ((len == SCM_LENGTH (SCM_ARRAY_V (ra))) && 0 == SCM_ARRAY_BASE (ra) && SCM_ARRAY_DIMS (ra)->inc)
1330 return SCM_ARRAY_V (ra);
1331 sra = scm_make_ra (1);
1332 SCM_ARRAY_DIMS (sra)->lbnd = 0;
1333 SCM_ARRAY_DIMS (sra)->ubnd = len - 1;
1334 SCM_ARRAY_V (sra) = SCM_ARRAY_V (ra);
1335 SCM_ARRAY_BASE (sra) = SCM_ARRAY_BASE (ra);
1336 SCM_ARRAY_DIMS (sra)->inc = (ndim ? SCM_ARRAY_DIMS (ra)[ndim - 1].inc : 1);
1337 return sra;
1338 }
1339 }
1340 }
1341 #undef FUNC_NAME
1342
1343
1344 SCM
1345 scm_ra2contig (SCM ra, int copy)
1346 {
1347 SCM ret;
1348 long inc = 1;
1349 scm_sizet k, len = 1;
1350 for (k = SCM_ARRAY_NDIM (ra); k--;)
1351 len *= SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1;
1352 k = SCM_ARRAY_NDIM (ra);
1353 if (SCM_ARRAY_CONTP (ra) && ((0 == k) || (1 == SCM_ARRAY_DIMS (ra)[k - 1].inc)))
1354 {
1355 if (scm_tc7_bvect != SCM_TYP7 (ra))
1356 return ra;
1357 if ((len == SCM_LENGTH (SCM_ARRAY_V (ra)) &&
1358 0 == SCM_ARRAY_BASE (ra) % SCM_LONG_BIT &&
1359 0 == len % SCM_LONG_BIT))
1360 return ra;
1361 }
1362 ret = scm_make_ra (k);
1363 SCM_ARRAY_BASE (ret) = 0;
1364 while (k--)
1365 {
1366 SCM_ARRAY_DIMS (ret)[k].lbnd = SCM_ARRAY_DIMS (ra)[k].lbnd;
1367 SCM_ARRAY_DIMS (ret)[k].ubnd = SCM_ARRAY_DIMS (ra)[k].ubnd;
1368 SCM_ARRAY_DIMS (ret)[k].inc = inc;
1369 inc *= SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1;
1370 }
1371 SCM_ARRAY_V (ret) = scm_make_uve ((inc - 1), scm_array_prototype (ra));
1372 if (copy)
1373 scm_array_copy_x (ra, ret);
1374 return ret;
1375 }
1376
1377
1378
1379 GUILE_PROC(scm_uniform_array_read_x, "uniform-array-read!", 1, 3, 0,
1380 (SCM ra, SCM port_or_fd, SCM start, SCM end),
1381 "")
1382 #define FUNC_NAME s_scm_uniform_array_read_x
1383 {
1384 SCM cra = SCM_UNDEFINED, v = ra;
1385 long sz, vlen, ans;
1386 long cstart = 0;
1387 long cend;
1388 long offset = 0;
1389
1390 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1391 if (SCM_UNBNDP (port_or_fd))
1392 port_or_fd = scm_cur_inp;
1393 else
1394 SCM_ASSERT (SCM_INUMP (port_or_fd)
1395 || (SCM_NIMP (port_or_fd) && SCM_OPINPORTP (port_or_fd)),
1396 port_or_fd, SCM_ARG2, FUNC_NAME);
1397 vlen = SCM_LENGTH (v);
1398
1399 loop:
1400 switch SCM_TYP7 (v)
1401 {
1402 default:
1403 badarg1:scm_wta (v, (char *) SCM_ARG1, FUNC_NAME);
1404 case scm_tc7_smob:
1405 SCM_ASRTGO (SCM_ARRAYP (v), badarg1);
1406 cra = scm_ra2contig (ra, 0);
1407 cstart += SCM_ARRAY_BASE (cra);
1408 vlen = SCM_ARRAY_DIMS (cra)->inc *
1409 (SCM_ARRAY_DIMS (cra)->ubnd - SCM_ARRAY_DIMS (cra)->lbnd + 1);
1410 v = SCM_ARRAY_V (cra);
1411 goto loop;
1412 case scm_tc7_string:
1413 case scm_tc7_byvect:
1414 sz = sizeof (char);
1415 break;
1416 case scm_tc7_bvect:
1417 vlen = (vlen + SCM_LONG_BIT - 1) / SCM_LONG_BIT;
1418 cstart /= SCM_LONG_BIT;
1419 case scm_tc7_uvect:
1420 case scm_tc7_ivect:
1421 sz = sizeof (long);
1422 break;
1423 case scm_tc7_svect:
1424 sz = sizeof (short);
1425 break;
1426 #ifdef HAVE_LONG_LONGS
1427 case scm_tc7_llvect:
1428 sz = sizeof (long_long);
1429 break;
1430 #endif
1431 #ifdef SCM_FLOATS
1432 #ifdef SCM_SINGLES
1433 case scm_tc7_fvect:
1434 sz = sizeof (float);
1435 break;
1436 #endif
1437 case scm_tc7_dvect:
1438 sz = sizeof (double);
1439 break;
1440 case scm_tc7_cvect:
1441 sz = 2 * sizeof (double);
1442 break;
1443 #endif
1444 }
1445
1446 cend = vlen;
1447 if (!SCM_UNBNDP (start))
1448 {
1449 offset =
1450 scm_num2long (start, (char *) SCM_ARG3, FUNC_NAME);
1451
1452 if (offset < 0 || offset >= cend)
1453 scm_out_of_range (FUNC_NAME, start);
1454
1455 if (!SCM_UNBNDP (end))
1456 {
1457 long tend =
1458 scm_num2long (end, (char *) SCM_ARG4, FUNC_NAME);
1459
1460 if (tend <= offset || tend > cend)
1461 scm_out_of_range (FUNC_NAME, end);
1462 cend = tend;
1463 }
1464 }
1465
1466 if (SCM_NIMP (port_or_fd))
1467 {
1468 scm_port *pt = SCM_PTAB_ENTRY (port_or_fd);
1469 int remaining = (cend - offset) * sz;
1470 char *dest = SCM_CHARS (v) + (cstart + offset) * sz;
1471
1472 if (pt->rw_active == SCM_PORT_WRITE)
1473 scm_flush (port_or_fd);
1474
1475 ans = cend - offset;
1476 while (remaining > 0)
1477 {
1478 if (pt->read_pos < pt->read_end)
1479 {
1480 int to_copy = min (pt->read_end - pt->read_pos,
1481 remaining);
1482
1483 memcpy (dest, pt->read_pos, to_copy);
1484 pt->read_pos += to_copy;
1485 remaining -= to_copy;
1486 dest += to_copy;
1487 }
1488 else
1489 {
1490 if (scm_fill_input (port_or_fd) == EOF)
1491 {
1492 if (remaining % sz != 0)
1493 {
1494 scm_misc_error (FUNC_NAME,
1495 "unexpected EOF",
1496 SCM_EOL);
1497 }
1498 ans -= remaining / sz;
1499 break;
1500 }
1501 }
1502 }
1503
1504 if (pt->rw_random)
1505 pt->rw_active = SCM_PORT_READ;
1506 }
1507 else /* file descriptor. */
1508 {
1509 SCM_SYSCALL (ans = read (SCM_INUM (port_or_fd),
1510 SCM_CHARS (v) + (cstart + offset) * sz,
1511 (scm_sizet) (sz * (cend - offset))));
1512 if (ans == -1)
1513 SCM_SYSERROR;
1514 }
1515 if (SCM_TYP7 (v) == scm_tc7_bvect)
1516 ans *= SCM_LONG_BIT;
1517
1518 if (v != ra && cra != ra)
1519 scm_array_copy_x (cra, ra);
1520
1521 return SCM_MAKINUM (ans);
1522 }
1523 #undef FUNC_NAME
1524
1525 GUILE_PROC(scm_uniform_array_write, "uniform-array-write", 1, 3, 0,
1526 (SCM v, SCM port_or_fd, SCM start, SCM end),
1527 "")
1528 #define FUNC_NAME s_scm_uniform_array_write
1529 {
1530 long sz, vlen, ans;
1531 long offset = 0;
1532 long cstart = 0;
1533 long cend;
1534
1535 port_or_fd = SCM_COERCE_OUTPORT (port_or_fd);
1536
1537 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1538 if (SCM_UNBNDP (port_or_fd))
1539 port_or_fd = scm_cur_outp;
1540 else
1541 SCM_ASSERT (SCM_INUMP (port_or_fd)
1542 || (SCM_NIMP (port_or_fd) && SCM_OPOUTPORTP (port_or_fd)),
1543 port_or_fd, SCM_ARG2, FUNC_NAME);
1544 vlen = SCM_LENGTH (v);
1545
1546 loop:
1547 switch SCM_TYP7 (v)
1548 {
1549 default:
1550 badarg1:scm_wta (v, (char *) SCM_ARG1, FUNC_NAME);
1551 case scm_tc7_smob:
1552 SCM_ASRTGO (SCM_ARRAYP (v), badarg1);
1553 v = scm_ra2contig (v, 1);
1554 cstart = SCM_ARRAY_BASE (v);
1555 vlen = SCM_ARRAY_DIMS (v)->inc
1556 * (SCM_ARRAY_DIMS (v)->ubnd - SCM_ARRAY_DIMS (v)->lbnd + 1);
1557 v = SCM_ARRAY_V (v);
1558 goto loop;
1559 case scm_tc7_string:
1560 case scm_tc7_byvect:
1561 sz = sizeof (char);
1562 break;
1563 case scm_tc7_bvect:
1564 vlen = (vlen + SCM_LONG_BIT - 1) / SCM_LONG_BIT;
1565 cstart /= SCM_LONG_BIT;
1566 case scm_tc7_uvect:
1567 case scm_tc7_ivect:
1568 sz = sizeof (long);
1569 break;
1570 case scm_tc7_svect:
1571 sz = sizeof (short);
1572 break;
1573 #ifdef HAVE_LONG_LONGS
1574 case scm_tc7_llvect:
1575 sz = sizeof (long_long);
1576 break;
1577 #endif
1578 #ifdef SCM_FLOATS
1579 #ifdef SCM_SINGLES
1580 case scm_tc7_fvect:
1581 sz = sizeof (float);
1582 break;
1583 #endif
1584 case scm_tc7_dvect:
1585 sz = sizeof (double);
1586 break;
1587 case scm_tc7_cvect:
1588 sz = 2 * sizeof (double);
1589 break;
1590 #endif
1591 }
1592
1593 cend = vlen;
1594 if (!SCM_UNBNDP (start))
1595 {
1596 offset =
1597 scm_num2long (start, (char *) SCM_ARG3, FUNC_NAME);
1598
1599 if (offset < 0 || offset >= cend)
1600 scm_out_of_range (FUNC_NAME, start);
1601
1602 if (!SCM_UNBNDP (end))
1603 {
1604 long tend =
1605 scm_num2long (end, (char *) SCM_ARG4, FUNC_NAME);
1606
1607 if (tend <= offset || tend > cend)
1608 scm_out_of_range (FUNC_NAME, end);
1609 cend = tend;
1610 }
1611 }
1612
1613 if (SCM_NIMP (port_or_fd))
1614 {
1615 char *source = SCM_CHARS (v) + (cstart + offset) * sz;
1616
1617 ans = cend - offset;
1618 scm_lfwrite (source, ans * sz, port_or_fd);
1619 }
1620 else /* file descriptor. */
1621 {
1622 SCM_SYSCALL (ans = write (SCM_INUM (port_or_fd),
1623 SCM_CHARS (v) + (cstart + offset) * sz,
1624 (scm_sizet) (sz * (cend - offset))));
1625 if (ans == -1)
1626 SCM_SYSERROR;
1627 }
1628 if (SCM_TYP7 (v) == scm_tc7_bvect)
1629 ans *= SCM_LONG_BIT;
1630
1631 return SCM_MAKINUM (ans);
1632 }
1633 #undef FUNC_NAME
1634
1635
1636 static char cnt_tab[16] =
1637 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1638
1639 GUILE_PROC(scm_bit_count, "bit-count", 2, 0, 0,
1640 (SCM item, SCM seq),
1641 "")
1642 #define FUNC_NAME s_scm_bit_count
1643 {
1644 long i;
1645 register unsigned long cnt = 0, w;
1646 SCM_VALIDATE_INT(2,seq);
1647 switch SCM_TYP7 (seq)
1648 {
1649 default:
1650 SCM_WTA (2,seq);
1651 case scm_tc7_bvect:
1652 if (0 == SCM_LENGTH (seq))
1653 return SCM_INUM0;
1654 i = (SCM_LENGTH (seq) - 1) / SCM_LONG_BIT;
1655 w = SCM_VELTS (seq)[i];
1656 if (SCM_FALSEP (item))
1657 w = ~w;
1658 w <<= SCM_LONG_BIT - 1 - ((SCM_LENGTH (seq) - 1) % SCM_LONG_BIT);
1659 while (!0)
1660 {
1661 for (; w; w >>= 4)
1662 cnt += cnt_tab[w & 0x0f];
1663 if (0 == i--)
1664 return SCM_MAKINUM (cnt);
1665 w = SCM_VELTS (seq)[i];
1666 if (SCM_FALSEP (item))
1667 w = ~w;
1668 }
1669 }
1670 }
1671 #undef FUNC_NAME
1672
1673
1674 GUILE_PROC(scm_bit_position, "bit-position", 3, 0, 0,
1675 (SCM item, SCM v, SCM k),
1676 "")
1677 #define FUNC_NAME s_scm_bit_position
1678 {
1679 long i, lenw, xbits, pos;
1680 register unsigned long w;
1681 SCM_VALIDATE_NIM (2,v);
1682 SCM_VALIDATE_INT_COPY(3,k,pos);
1683 SCM_ASSERT ((pos <= SCM_LENGTH (v)) && (pos >= 0),
1684 k, SCM_OUTOFRANGE, FUNC_NAME);
1685 if (pos == SCM_LENGTH (v))
1686 return SCM_BOOL_F;
1687 switch SCM_TYP7 (v)
1688 {
1689 default:
1690 SCM_WTA (2,v);
1691 case scm_tc7_bvect:
1692 if (0 == SCM_LENGTH (v))
1693 return SCM_MAKINUM (-1L);
1694 lenw = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT; /* watch for part words */
1695 i = pos / SCM_LONG_BIT;
1696 w = SCM_VELTS (v)[i];
1697 if (SCM_FALSEP (item))
1698 w = ~w;
1699 xbits = (pos % SCM_LONG_BIT);
1700 pos -= xbits;
1701 w = ((w >> xbits) << xbits);
1702 xbits = SCM_LONG_BIT - 1 - (SCM_LENGTH (v) - 1) % SCM_LONG_BIT;
1703 while (!0)
1704 {
1705 if (w && (i == lenw))
1706 w = ((w << xbits) >> xbits);
1707 if (w)
1708 while (w)
1709 switch (w & 0x0f)
1710 {
1711 default:
1712 return SCM_MAKINUM (pos);
1713 case 2:
1714 case 6:
1715 case 10:
1716 case 14:
1717 return SCM_MAKINUM (pos + 1);
1718 case 4:
1719 case 12:
1720 return SCM_MAKINUM (pos + 2);
1721 case 8:
1722 return SCM_MAKINUM (pos + 3);
1723 case 0:
1724 pos += 4;
1725 w >>= 4;
1726 }
1727 if (++i > lenw)
1728 break;
1729 pos += SCM_LONG_BIT;
1730 w = SCM_VELTS (v)[i];
1731 if (SCM_FALSEP (item))
1732 w = ~w;
1733 }
1734 return SCM_BOOL_F;
1735 }
1736 }
1737 #undef FUNC_NAME
1738
1739
1740 GUILE_PROC(scm_bit_set_star_x, "bit-set*!", 3, 0, 0,
1741 (SCM v, SCM kv, SCM obj),
1742 "")
1743 #define FUNC_NAME s_scm_bit_set_star_x
1744 {
1745 register long i, k, vlen;
1746 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1747 SCM_ASRTGO (SCM_NIMP (kv), badarg2);
1748 switch SCM_TYP7 (kv)
1749 {
1750 default:
1751 badarg2:SCM_WTA (2,kv);
1752 case scm_tc7_uvect:
1753 switch SCM_TYP7 (v)
1754 {
1755 default:
1756 badarg1:SCM_WTA (1,v);
1757 case scm_tc7_bvect:
1758 vlen = SCM_LENGTH (v);
1759 if (SCM_BOOL_F == obj)
1760 for (i = SCM_LENGTH (kv); i;)
1761 {
1762 k = SCM_VELTS (kv)[--i];
1763 SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, FUNC_NAME);
1764 SCM_VELTS (v)[k / SCM_LONG_BIT] &= ~(1L << (k % SCM_LONG_BIT));
1765 }
1766 else if (SCM_BOOL_T == obj)
1767 for (i = SCM_LENGTH (kv); i;)
1768 {
1769 k = SCM_VELTS (kv)[--i];
1770 SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, FUNC_NAME);
1771 SCM_VELTS (v)[k / SCM_LONG_BIT] |= (1L << (k % SCM_LONG_BIT));
1772 }
1773 else
1774 badarg3:SCM_WTA (3,obj);
1775 }
1776 break;
1777 case scm_tc7_bvect:
1778 SCM_ASRTGO (SCM_TYP7 (v) == scm_tc7_bvect && SCM_LENGTH (v) == SCM_LENGTH (kv), badarg1);
1779 if (SCM_BOOL_F == obj)
1780 for (k = (SCM_LENGTH (v) + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k--;)
1781 SCM_VELTS (v)[k] &= ~(SCM_VELTS (kv)[k]);
1782 else if (SCM_BOOL_T == obj)
1783 for (k = (SCM_LENGTH (v) + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k--;)
1784 SCM_VELTS (v)[k] |= SCM_VELTS (kv)[k];
1785 else
1786 goto badarg3;
1787 break;
1788 }
1789 return SCM_UNSPECIFIED;
1790 }
1791 #undef FUNC_NAME
1792
1793
1794 GUILE_PROC(scm_bit_count_star, "bit-count*", 3, 0, 0,
1795 (SCM v, SCM kv, SCM obj),
1796 "")
1797 #define FUNC_NAME s_scm_bit_count_star
1798 {
1799 register long i, vlen, count = 0;
1800 register unsigned long k;
1801 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1802 SCM_ASRTGO (SCM_NIMP (kv), badarg2);
1803 switch SCM_TYP7 (kv)
1804 {
1805 default:
1806 badarg2:SCM_WTA (2,kv);
1807 case scm_tc7_uvect:
1808 switch SCM_TYP7
1809 (v)
1810 {
1811 default:
1812 badarg1:SCM_WTA (1,v);
1813 case scm_tc7_bvect:
1814 vlen = SCM_LENGTH (v);
1815 if (SCM_BOOL_F == obj)
1816 for (i = SCM_LENGTH (kv); i;)
1817 {
1818 k = SCM_VELTS (kv)[--i];
1819 SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, FUNC_NAME);
1820 if (!(SCM_VELTS (v)[k / SCM_LONG_BIT] & (1L << (k % SCM_LONG_BIT))))
1821 count++;
1822 }
1823 else if (SCM_BOOL_T == obj)
1824 for (i = SCM_LENGTH (kv); i;)
1825 {
1826 k = SCM_VELTS (kv)[--i];
1827 SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, FUNC_NAME);
1828 if (SCM_VELTS (v)[k / SCM_LONG_BIT] & (1L << (k % SCM_LONG_BIT)))
1829 count++;
1830 }
1831 else
1832 badarg3:SCM_WTA (3,obj);
1833 }
1834 break;
1835 case scm_tc7_bvect:
1836 SCM_ASRTGO (SCM_TYP7 (v) == scm_tc7_bvect && SCM_LENGTH (v) == SCM_LENGTH (kv), badarg1);
1837 if (0 == SCM_LENGTH (v))
1838 return SCM_INUM0;
1839 SCM_ASRTGO (SCM_BOOL_T == obj || SCM_BOOL_F == obj, badarg3);
1840 obj = (SCM_BOOL_T == obj);
1841 i = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT;
1842 k = SCM_VELTS (kv)[i] & (obj ? SCM_VELTS (v)[i] : ~SCM_VELTS (v)[i]);
1843 k <<= SCM_LONG_BIT - 1 - ((SCM_LENGTH (v) - 1) % SCM_LONG_BIT);
1844 while (!0)
1845 {
1846 for (; k; k >>= 4)
1847 count += cnt_tab[k & 0x0f];
1848 if (0 == i--)
1849 return SCM_MAKINUM (count);
1850 k = SCM_VELTS (kv)[i] & (obj ? SCM_VELTS (v)[i] : ~SCM_VELTS (v)[i]);
1851 }
1852 }
1853 return SCM_MAKINUM (count);
1854 }
1855 #undef FUNC_NAME
1856
1857
1858 GUILE_PROC(scm_bit_invert_x, "bit-invert!", 1, 0, 0,
1859 (SCM v),
1860 "")
1861 #define FUNC_NAME s_scm_bit_invert_x
1862 {
1863 register long k;
1864 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1865 k = SCM_LENGTH (v);
1866 switch SCM_TYP7
1867 (v)
1868 {
1869 case scm_tc7_bvect:
1870 for (k = (k + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k--;)
1871 SCM_VELTS (v)[k] = ~SCM_VELTS (v)[k];
1872 break;
1873 default:
1874 badarg1:SCM_WTA (1,v);
1875 }
1876 return SCM_UNSPECIFIED;
1877 }
1878 #undef FUNC_NAME
1879
1880
1881 SCM
1882 scm_istr2bve (char *str, long len)
1883 {
1884 SCM v = scm_make_uve (len, SCM_BOOL_T);
1885 long *data = (long *) SCM_VELTS (v);
1886 register unsigned long mask;
1887 register long k;
1888 register long j;
1889 for (k = 0; k < (len + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k++)
1890 {
1891 data[k] = 0L;
1892 j = len - k * SCM_LONG_BIT;
1893 if (j > SCM_LONG_BIT)
1894 j = SCM_LONG_BIT;
1895 for (mask = 1L; j--; mask <<= 1)
1896 switch (*str++)
1897 {
1898 case '0':
1899 break;
1900 case '1':
1901 data[k] |= mask;
1902 break;
1903 default:
1904 return SCM_BOOL_F;
1905 }
1906 }
1907 return v;
1908 }
1909
1910
1911
1912 static SCM
1913 ra2l (SCM ra,scm_sizet base,scm_sizet k)
1914 {
1915 register SCM res = SCM_EOL;
1916 register long inc = SCM_ARRAY_DIMS (ra)[k].inc;
1917 register scm_sizet i;
1918 if (SCM_ARRAY_DIMS (ra)[k].ubnd < SCM_ARRAY_DIMS (ra)[k].lbnd)
1919 return SCM_EOL;
1920 i = base + (1 + SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd) * inc;
1921 if (k < SCM_ARRAY_NDIM (ra) - 1)
1922 {
1923 do
1924 {
1925 i -= inc;
1926 res = scm_cons (ra2l (ra, i, k + 1), res);
1927 }
1928 while (i != base);
1929 }
1930 else
1931 do
1932 {
1933 i -= inc;
1934 res = scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra), SCM_MAKINUM (i)), res);
1935 }
1936 while (i != base);
1937 return res;
1938 }
1939
1940
1941 GUILE_PROC(scm_array_to_list, "array->list", 1, 0, 0,
1942 (SCM v),
1943 "")
1944 #define FUNC_NAME s_scm_array_to_list
1945 {
1946 SCM res = SCM_EOL;
1947 register long k;
1948 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1949 switch SCM_TYP7
1950 (v)
1951 {
1952 default:
1953 badarg1:SCM_WTA (1,v);
1954 case scm_tc7_smob:
1955 SCM_ASRTGO (SCM_ARRAYP (v), badarg1);
1956 return ra2l (v, SCM_ARRAY_BASE (v), 0);
1957 case scm_tc7_vector:
1958 case scm_tc7_wvect:
1959 return scm_vector_to_list (v);
1960 case scm_tc7_string:
1961 return scm_string_to_list (v);
1962 case scm_tc7_bvect:
1963 {
1964 long *data = (long *) SCM_VELTS (v);
1965 register unsigned long mask;
1966 for (k = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT; k > 0; k--)
1967 for (mask = 1UL << (SCM_LONG_BIT - 1); mask; mask >>= 1)
1968 res = scm_cons (SCM_BOOL(((long *) data)[k] & mask), res);
1969 for (mask = 1L << ((SCM_LENGTH (v) % SCM_LONG_BIT) - 1); mask; mask >>= 1)
1970 res = scm_cons (SCM_BOOL(((long *) data)[k] & mask), res);
1971 return res;
1972 }
1973 # ifdef SCM_INUMS_ONLY
1974 case scm_tc7_uvect:
1975 case scm_tc7_ivect:
1976 {
1977 long *data = (long *) SCM_VELTS (v);
1978 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
1979 res = scm_cons (SCM_MAKINUM (data[k]), res);
1980 return res;
1981 }
1982 # else
1983 case scm_tc7_uvect: {
1984 long *data = (long *)SCM_VELTS(v);
1985 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
1986 res = scm_cons(scm_ulong2num(data[k]), res);
1987 return res;
1988 }
1989 case scm_tc7_ivect: {
1990 long *data = (long *)SCM_VELTS(v);
1991 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
1992 res = scm_cons(scm_long2num(data[k]), res);
1993 return res;
1994 }
1995 # endif
1996 case scm_tc7_svect: {
1997 short *data;
1998 data = (short *)SCM_VELTS(v);
1999 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
2000 res = scm_cons(SCM_MAKINUM (data[k]), res);
2001 return res;
2002 }
2003 #ifdef HAVE_LONG_LONGS
2004 case scm_tc7_llvect: {
2005 long_long *data;
2006 data = (long_long *)SCM_VELTS(v);
2007 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
2008 res = scm_cons(scm_long_long2num(data[k]), res);
2009 return res;
2010 }
2011 #endif
2012
2013
2014 #ifdef SCM_FLOATS
2015 #ifdef SCM_SINGLES
2016 case scm_tc7_fvect:
2017 {
2018 float *data = (float *) SCM_VELTS (v);
2019 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2020 res = scm_cons (scm_makflo (data[k]), res);
2021 return res;
2022 }
2023 #endif /*SCM_SINGLES*/
2024 case scm_tc7_dvect:
2025 {
2026 double *data = (double *) SCM_VELTS (v);
2027 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2028 res = scm_cons (scm_makdbl (data[k], 0.0), res);
2029 return res;
2030 }
2031 case scm_tc7_cvect:
2032 {
2033 double (*data)[2] = (double (*)[2]) SCM_VELTS (v);
2034 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2035 res = scm_cons (scm_makdbl (data[k][0], data[k][1]), res);
2036 return res;
2037 }
2038 #endif /*SCM_FLOATS*/
2039 }
2040 }
2041 #undef FUNC_NAME
2042
2043
2044 static char s_bad_ralst[] = "Bad scm_array contents list";
2045
2046 static int l2ra(SCM lst, SCM ra, scm_sizet base, scm_sizet k);
2047
2048 GUILE_PROC(scm_list_to_uniform_array, "list->uniform-array", 3, 0, 0,
2049 (SCM ndim, SCM prot, SCM lst),
2050 "")
2051 #define FUNC_NAME s_scm_list_to_uniform_array
2052 {
2053 SCM shp = SCM_EOL;
2054 SCM row = lst;
2055 SCM ra;
2056 scm_sizet k;
2057 long n;
2058 SCM_VALIDATE_INT_COPY(1,ndim,k);
2059 while (k--)
2060 {
2061 n = scm_ilength (row);
2062 SCM_ASSERT (n >= 0, lst, SCM_ARG3, FUNC_NAME);
2063 shp = scm_cons (SCM_MAKINUM (n), shp);
2064 if (SCM_NIMP (row))
2065 row = SCM_CAR (row);
2066 }
2067 ra = scm_dimensions_to_uniform_array (scm_reverse (shp), prot,
2068 SCM_UNDEFINED);
2069 if (SCM_NULLP (shp))
2070
2071 {
2072 SCM_ASRTGO (1 == scm_ilength (lst), badlst);
2073 scm_array_set_x (ra, SCM_CAR (lst), SCM_EOL);
2074 return ra;
2075 }
2076 if (!SCM_ARRAYP (ra))
2077 {
2078 for (k = 0; k < SCM_LENGTH (ra); k++, lst = SCM_CDR (lst))
2079 scm_array_set_x (ra, SCM_CAR (lst), SCM_MAKINUM (k));
2080 return ra;
2081 }
2082 if (l2ra (lst, ra, SCM_ARRAY_BASE (ra), 0))
2083 return ra;
2084 else
2085 badlst:scm_wta (lst, s_bad_ralst, FUNC_NAME);
2086 return SCM_BOOL_F;
2087 }
2088 #undef FUNC_NAME
2089
2090 static int
2091 l2ra (SCM lst, SCM ra, scm_sizet base, scm_sizet k)
2092 {
2093 register long inc = SCM_ARRAY_DIMS (ra)[k].inc;
2094 register long n = (1 + SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd);
2095 int ok = 1;
2096 if (n <= 0)
2097 return (SCM_EOL == lst);
2098 if (k < SCM_ARRAY_NDIM (ra) - 1)
2099 {
2100 while (n--)
2101 {
2102 if (SCM_IMP (lst) || SCM_NCONSP (lst))
2103 return 0;
2104 ok = ok && l2ra (SCM_CAR (lst), ra, base, k + 1);
2105 base += inc;
2106 lst = SCM_CDR (lst);
2107 }
2108 if (SCM_NNULLP (lst))
2109 return 0;
2110 }
2111 else
2112 {
2113 while (n--)
2114 {
2115 if (SCM_IMP (lst) || SCM_NCONSP (lst))
2116 return 0;
2117 ok = ok && scm_array_set_x (SCM_ARRAY_V (ra), SCM_CAR (lst), SCM_MAKINUM (base));
2118 base += inc;
2119 lst = SCM_CDR (lst);
2120 }
2121 if (SCM_NNULLP (lst))
2122 return 0;
2123 }
2124 return ok;
2125 }
2126
2127
2128 static void
2129 rapr1 (SCM ra,scm_sizet j,scm_sizet k,SCM port,scm_print_state *pstate)
2130 {
2131 long inc = 1;
2132 long n = SCM_LENGTH (ra);
2133 int enclosed = 0;
2134 tail:
2135 switch SCM_TYP7 (ra)
2136 {
2137 case scm_tc7_smob:
2138 if (enclosed++)
2139 {
2140 SCM_ARRAY_BASE (ra) = j;
2141 if (n-- > 0)
2142 scm_iprin1 (ra, port, pstate);
2143 for (j += inc; n-- > 0; j += inc)
2144 {
2145 scm_putc (' ', port);
2146 SCM_ARRAY_BASE (ra) = j;
2147 scm_iprin1 (ra, port, pstate);
2148 }
2149 break;
2150 }
2151 if (k + 1 < SCM_ARRAY_NDIM (ra))
2152 {
2153 long i;
2154 inc = SCM_ARRAY_DIMS (ra)[k].inc;
2155 for (i = SCM_ARRAY_DIMS (ra)[k].lbnd; i < SCM_ARRAY_DIMS (ra)[k].ubnd; i++)
2156 {
2157 scm_putc ('(', port);
2158 rapr1 (ra, j, k + 1, port, pstate);
2159 scm_puts (") ", port);
2160 j += inc;
2161 }
2162 if (i == SCM_ARRAY_DIMS (ra)[k].ubnd)
2163 { /* could be zero size. */
2164 scm_putc ('(', port);
2165 rapr1 (ra, j, k + 1, port, pstate);
2166 scm_putc (')', port);
2167 }
2168 break;
2169 }
2170 if SCM_ARRAY_NDIM
2171 (ra)
2172 { /* Could be zero-dimensional */
2173 inc = SCM_ARRAY_DIMS (ra)[k].inc;
2174 n = (SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1);
2175 }
2176 else
2177 n = 1;
2178 ra = SCM_ARRAY_V (ra);
2179 goto tail;
2180 default:
2181 /* scm_tc7_bvect and scm_tc7_llvect only? */
2182 if (n-- > 0)
2183 scm_iprin1 (scm_uniform_vector_ref (ra, SCM_MAKINUM (j)), port, pstate);
2184 for (j += inc; n-- > 0; j += inc)
2185 {
2186 scm_putc (' ', port);
2187 scm_iprin1 (scm_cvref (ra, j, SCM_UNDEFINED), port, pstate);
2188 }
2189 break;
2190 case scm_tc7_string:
2191 if (n-- > 0)
2192 scm_iprin1 (SCM_MAKICHR (SCM_UCHARS (ra)[j]), port, pstate);
2193 if (SCM_WRITINGP (pstate))
2194 for (j += inc; n-- > 0; j += inc)
2195 {
2196 scm_putc (' ', port);
2197 scm_iprin1 (SCM_MAKICHR (SCM_UCHARS (ra)[j]), port, pstate);
2198 }
2199 else
2200 for (j += inc; n-- > 0; j += inc)
2201 scm_putc (SCM_CHARS (ra)[j], port);
2202 break;
2203 case scm_tc7_byvect:
2204 if (n-- > 0)
2205 scm_intprint (((char *)SCM_CDR (ra))[j], 10, port);
2206 for (j += inc; n-- > 0; j += inc)
2207 {
2208 scm_putc (' ', port);
2209 scm_intprint (((char *)SCM_CDR (ra))[j], 10, port);
2210 }
2211 break;
2212
2213 case scm_tc7_uvect:
2214 {
2215 char str[11];
2216
2217 if (n-- > 0)
2218 {
2219 /* intprint can't handle >= 2^31. */
2220 sprintf (str, "%lu", (unsigned long) SCM_VELTS (ra)[j]);
2221 scm_puts (str, port);
2222 }
2223 for (j += inc; n-- > 0; j += inc)
2224 {
2225 scm_putc (' ', port);
2226 sprintf (str, "%lu", (unsigned long) SCM_VELTS (ra)[j]);
2227 scm_puts (str, port);
2228 }
2229 }
2230 case scm_tc7_ivect:
2231 if (n-- > 0)
2232 scm_intprint (SCM_VELTS (ra)[j], 10, port);
2233 for (j += inc; n-- > 0; j += inc)
2234 {
2235 scm_putc (' ', port);
2236 scm_intprint (SCM_VELTS (ra)[j], 10, port);
2237 }
2238 break;
2239
2240 case scm_tc7_svect:
2241 if (n-- > 0)
2242 scm_intprint (((short *)SCM_CDR (ra))[j], 10, port);
2243 for (j += inc; n-- > 0; j += inc)
2244 {
2245 scm_putc (' ', port);
2246 scm_intprint (((short *)SCM_CDR (ra))[j], 10, port);
2247 }
2248 break;
2249
2250 #ifdef SCM_FLOATS
2251 #ifdef SCM_SINGLES
2252 case scm_tc7_fvect:
2253 if (n-- > 0)
2254 {
2255 SCM z = scm_makflo (1.0);
2256 SCM_FLO (z) = ((float *) SCM_VELTS (ra))[j];
2257 scm_floprint (z, port, pstate);
2258 for (j += inc; n-- > 0; j += inc)
2259 {
2260 scm_putc (' ', port);
2261 SCM_FLO (z) = ((float *) SCM_VELTS (ra))[j];
2262 scm_floprint (z, port, pstate);
2263 }
2264 }
2265 break;
2266 #endif /*SCM_SINGLES*/
2267 case scm_tc7_dvect:
2268 if (n-- > 0)
2269 {
2270 SCM z = scm_makdbl (1.0 / 3.0, 0.0);
2271 SCM_REAL (z) = ((double *) SCM_VELTS (ra))[j];
2272 scm_floprint (z, port, pstate);
2273 for (j += inc; n-- > 0; j += inc)
2274 {
2275 scm_putc (' ', port);
2276 SCM_REAL (z) = ((double *) SCM_VELTS (ra))[j];
2277 scm_floprint (z, port, pstate);
2278 }
2279 }
2280 break;
2281 case scm_tc7_cvect:
2282 if (n-- > 0)
2283 {
2284 SCM cz = scm_makdbl (0.0, 1.0), z = scm_makdbl (1.0 / 3.0, 0.0);
2285 SCM_REAL (z) = SCM_REAL (cz) = (((double *) SCM_VELTS (ra))[2 * j]);
2286 SCM_IMAG (cz) = ((double *) SCM_VELTS (ra))[2 * j + 1];
2287 scm_floprint ((0.0 == SCM_IMAG (cz) ? z : cz), port, pstate);
2288 for (j += inc; n-- > 0; j += inc)
2289 {
2290 scm_putc (' ', port);
2291 SCM_REAL (z) = SCM_REAL (cz) = ((double *) SCM_VELTS (ra))[2 * j];
2292 SCM_IMAG (cz) = ((double *) SCM_VELTS (ra))[2 * j + 1];
2293 scm_floprint ((0.0 == SCM_IMAG (cz) ? z : cz), port, pstate);
2294 }
2295 }
2296 break;
2297 #endif /*SCM_FLOATS*/
2298 }
2299 }
2300
2301
2302
2303 int
2304 scm_raprin1 (SCM exp, SCM port, scm_print_state *pstate)
2305 {
2306 SCM v = exp;
2307 scm_sizet base = 0;
2308 scm_putc ('#', port);
2309 tail:
2310 switch SCM_TYP7 (v)
2311 {
2312 case scm_tc7_smob:
2313 {
2314 long ndim = SCM_ARRAY_NDIM (v);
2315 base = SCM_ARRAY_BASE (v);
2316 v = SCM_ARRAY_V (v);
2317 if (SCM_ARRAYP (v))
2318
2319 {
2320 scm_puts ("<enclosed-array ", port);
2321 rapr1 (exp, base, 0, port, pstate);
2322 scm_putc ('>', port);
2323 return 1;
2324 }
2325 else
2326 {
2327 scm_intprint (ndim, 10, port);
2328 goto tail;
2329 }
2330 }
2331 case scm_tc7_bvect:
2332 if (exp == v)
2333 { /* a uve, not an scm_array */
2334 register long i, j, w;
2335 scm_putc ('*', port);
2336 for (i = 0; i < (SCM_LENGTH (exp)) / SCM_LONG_BIT; i++)
2337 {
2338 w = SCM_VELTS (exp)[i];
2339 for (j = SCM_LONG_BIT; j; j--)
2340 {
2341 scm_putc (w & 1 ? '1' : '0', port);
2342 w >>= 1;
2343 }
2344 }
2345 j = SCM_LENGTH (exp) % SCM_LONG_BIT;
2346 if (j)
2347 {
2348 w = SCM_VELTS (exp)[SCM_LENGTH (exp) / SCM_LONG_BIT];
2349 for (; j; j--)
2350 {
2351 scm_putc (w & 1 ? '1' : '0', port);
2352 w >>= 1;
2353 }
2354 }
2355 return 1;
2356 }
2357 else
2358 scm_putc ('b', port);
2359 break;
2360 case scm_tc7_string:
2361 scm_putc ('a', port);
2362 break;
2363 case scm_tc7_byvect:
2364 scm_putc ('y', port);
2365 break;
2366 case scm_tc7_uvect:
2367 scm_putc ('u', port);
2368 break;
2369 case scm_tc7_ivect:
2370 scm_putc ('e', port);
2371 break;
2372 case scm_tc7_svect:
2373 scm_putc ('h', port);
2374 break;
2375 #ifdef HAVE_LONG_LONGS
2376 case scm_tc7_llvect:
2377 scm_putc ('l', port);
2378 break;
2379 #endif
2380 #ifdef SCM_FLOATS
2381 #ifdef SCM_SINGLES
2382 case scm_tc7_fvect:
2383 scm_putc ('s', port);
2384 break;
2385 #endif /*SCM_SINGLES*/
2386 case scm_tc7_dvect:
2387 scm_putc ('i', port);
2388 break;
2389 case scm_tc7_cvect:
2390 scm_putc ('c', port);
2391 break;
2392 #endif /*SCM_FLOATS*/
2393 }
2394 scm_putc ('(', port);
2395 rapr1 (exp, base, 0, port, pstate);
2396 scm_putc (')', port);
2397 return 1;
2398 }
2399
2400 GUILE_PROC(scm_array_prototype, "array-prototype", 1, 0, 0,
2401 (SCM ra),
2402 "")
2403 #define FUNC_NAME s_scm_array_prototype
2404 {
2405 int enclosed = 0;
2406 SCM_ASRTGO (SCM_NIMP (ra), badarg);
2407 loop:
2408 switch SCM_TYP7
2409 (ra)
2410 {
2411 default:
2412 badarg:SCM_WTA (1,ra);
2413 case scm_tc7_smob:
2414 SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
2415 if (enclosed++)
2416 return SCM_UNSPECIFIED;
2417 ra = SCM_ARRAY_V (ra);
2418 goto loop;
2419 case scm_tc7_vector:
2420 case scm_tc7_wvect:
2421 return SCM_EOL;
2422 case scm_tc7_bvect:
2423 return SCM_BOOL_T;
2424 case scm_tc7_string:
2425 return SCM_MAKICHR ('a');
2426 case scm_tc7_byvect:
2427 return SCM_MAKICHR ('\0');
2428 case scm_tc7_uvect:
2429 return SCM_MAKINUM (1L);
2430 case scm_tc7_ivect:
2431 return SCM_MAKINUM (-1L);
2432 case scm_tc7_svect:
2433 return SCM_CDR (scm_intern ("s", 1));
2434 #ifdef HAVE_LONG_LONGS
2435 case scm_tc7_llvect:
2436 return SCM_CDR (scm_intern ("l", 1));
2437 #endif
2438 #ifdef SCM_FLOATS
2439 #ifdef SCM_SINGLES
2440 case scm_tc7_fvect:
2441 return scm_makflo (1.0);
2442 #endif
2443 case scm_tc7_dvect:
2444 return scm_makdbl (1.0 / 3.0, 0.0);
2445 case scm_tc7_cvect:
2446 return scm_makdbl (0.0, 1.0);
2447 #endif
2448 }
2449 }
2450 #undef FUNC_NAME
2451
2452
2453 static SCM
2454 markra (SCM ptr)
2455 {
2456 return SCM_ARRAY_V (ptr);
2457 }
2458
2459
2460 static scm_sizet
2461 freera (SCM ptr)
2462 {
2463 scm_must_free (SCM_CHARS (ptr));
2464 return sizeof (scm_array) + SCM_ARRAY_NDIM (ptr) * sizeof (scm_array_dim);
2465 }
2466
2467 void
2468 scm_init_unif ()
2469 {
2470 scm_tc16_array = scm_make_smob_type_mfpe ("array", 0,
2471 markra,
2472 freera,
2473 scm_raprin1,
2474 scm_array_equal_p);
2475 scm_add_feature ("array");
2476 #include "unif.x"
2477 }