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