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