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