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