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