*** empty log message ***
[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:
c209c88e 1200 if (SCM_NIMP (last) && (last != scm_flo0) && (scm_tc_flo == SCM_CARW (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
c209c88e 1209 if (SCM_NIMP (last) && scm_tc_dblr == SCM_CARW (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:
c209c88e 1219 if (SCM_NIMP (last) && scm_tc_dblc == SCM_CARW (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:
c209c88e
GB
1319 SCM_VELTS(v)[pos] = SCM_ASSCM (scm_num2ulong(obj, (char *)SCM_ARG2, FUNC_NAME));
1320 break;
1bbd0b84 1321 case scm_tc7_ivect:
c209c88e
GB
1322 SCM_VELTS(v)[pos] = SCM_ASSCM (scm_num2long(obj, (char *)SCM_ARG2, FUNC_NAME));
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;
c209c88e 1765 w = SCM_ASWORD (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);
c209c88e 1775 w = SCM_ASWORD (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;
c209c88e 1808 w = SCM_ASWORD (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;
c209c88e 1842 w = SCM_ASWORD (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 {
c209c88e 1880 k = SCM_ASWORD (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 {
c209c88e 1887 k = SCM_ASWORD (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--;)
c209c88e 1899 SCM_ASWORD (SCM_VELTS (v)[k]) &= ~ SCM_ASWORD(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--;)
c209c88e 1902 SCM_ASWORD (SCM_VELTS (v)[k]) |= SCM_ASWORD (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;
c209c88e 1923
0f2d19dd
JB
1924 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1925 SCM_ASRTGO (SCM_NIMP (kv), badarg2);
5c11cc9d 1926 switch SCM_TYP7 (kv)
0f2d19dd
JB
1927 {
1928 default:
c209c88e
GB
1929 badarg2:
1930 SCM_WTA (2,kv);
0f2d19dd
JB
1931 case scm_tc7_uvect:
1932 switch SCM_TYP7
1933 (v)
1934 {
1935 default:
c209c88e
GB
1936 badarg1:
1937 SCM_WTA (1,v);
0f2d19dd
JB
1938 case scm_tc7_bvect:
1939 vlen = SCM_LENGTH (v);
1940 if (SCM_BOOL_F == obj)
1941 for (i = SCM_LENGTH (kv); i;)
1942 {
c209c88e 1943 k = SCM_ASWORD (SCM_VELTS (kv)[--i]);
1bbd0b84 1944 SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, FUNC_NAME);
c209c88e 1945 if (!SCM_BITVEC_REF(v,k))
0f2d19dd
JB
1946 count++;
1947 }
1948 else if (SCM_BOOL_T == obj)
1949 for (i = SCM_LENGTH (kv); i;)
1950 {
c209c88e 1951 k = SCM_ASWORD (SCM_VELTS (kv)[--i]);
1bbd0b84 1952 SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, FUNC_NAME);
c209c88e 1953 if (SCM_BITVEC_REF (v,k))
0f2d19dd
JB
1954 count++;
1955 }
1956 else
1bbd0b84 1957 badarg3:SCM_WTA (3,obj);
0f2d19dd
JB
1958 }
1959 break;
1960 case scm_tc7_bvect:
1961 SCM_ASRTGO (SCM_TYP7 (v) == scm_tc7_bvect && SCM_LENGTH (v) == SCM_LENGTH (kv), badarg1);
1962 if (0 == SCM_LENGTH (v))
1963 return SCM_INUM0;
1964 SCM_ASRTGO (SCM_BOOL_T == obj || SCM_BOOL_F == obj, badarg3);
c209c88e 1965 obj = (SCM_BOOL_T == obj); /* ugh. */
0f2d19dd 1966 i = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT;
c209c88e 1967 k = SCM_ASWORD (SCM_VELTS (kv)[i]) & (obj ? SCM_ASWORD (SCM_VELTS (v)[i]) : ~ SCM_ASWORD (SCM_VELTS (v)[i]));
0f2d19dd 1968 k <<= SCM_LONG_BIT - 1 - ((SCM_LENGTH (v) - 1) % SCM_LONG_BIT);
c209c88e 1969 while (1)
0f2d19dd
JB
1970 {
1971 for (; k; k >>= 4)
1972 count += cnt_tab[k & 0x0f];
1973 if (0 == i--)
1974 return SCM_MAKINUM (count);
c209c88e
GB
1975
1976 /* urg. repetitive (see above.) */
1977 k = SCM_ASWORD (SCM_VELTS (kv)[i]) & (obj ? SCM_ASWORD(SCM_VELTS (v)[i]) : ~SCM_ASWORD (SCM_VELTS (v)[i]));
0f2d19dd
JB
1978 }
1979 }
1980 return SCM_MAKINUM (count);
1981}
1bbd0b84 1982#undef FUNC_NAME
0f2d19dd
JB
1983
1984
3b3b36dd 1985SCM_DEFINE (scm_bit_invert_x, "bit-invert!", 1, 0, 0,
1bbd0b84 1986 (SCM v),
b380b885 1987 "Modifies @var{bv} by replacing each element with its negation.")
1bbd0b84 1988#define FUNC_NAME s_scm_bit_invert_x
0f2d19dd
JB
1989{
1990 register long k;
1991 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1992 k = SCM_LENGTH (v);
1993 switch SCM_TYP7
1994 (v)
1995 {
1996 case scm_tc7_bvect:
1997 for (k = (k + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k--;)
c209c88e 1998 SCM_ASWORD (SCM_VELTS (v)[k]) = ~SCM_ASWORD(SCM_VELTS (v)[k]);
0f2d19dd
JB
1999 break;
2000 default:
1bbd0b84 2001 badarg1:SCM_WTA (1,v);
0f2d19dd
JB
2002 }
2003 return SCM_UNSPECIFIED;
2004}
1bbd0b84 2005#undef FUNC_NAME
0f2d19dd
JB
2006
2007
0f2d19dd 2008SCM
1bbd0b84 2009scm_istr2bve (char *str, long len)
0f2d19dd
JB
2010{
2011 SCM v = scm_make_uve (len, SCM_BOOL_T);
2012 long *data = (long *) SCM_VELTS (v);
2013 register unsigned long mask;
2014 register long k;
2015 register long j;
2016 for (k = 0; k < (len + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k++)
2017 {
2018 data[k] = 0L;
2019 j = len - k * SCM_LONG_BIT;
2020 if (j > SCM_LONG_BIT)
2021 j = SCM_LONG_BIT;
2022 for (mask = 1L; j--; mask <<= 1)
2023 switch (*str++)
2024 {
2025 case '0':
2026 break;
2027 case '1':
2028 data[k] |= mask;
2029 break;
2030 default:
2031 return SCM_BOOL_F;
2032 }
2033 }
2034 return v;
2035}
2036
2037
1cc91f1b 2038
0f2d19dd 2039static SCM
1bbd0b84 2040ra2l (SCM ra,scm_sizet base,scm_sizet k)
0f2d19dd
JB
2041{
2042 register SCM res = SCM_EOL;
2043 register long inc = SCM_ARRAY_DIMS (ra)[k].inc;
2044 register scm_sizet i;
2045 if (SCM_ARRAY_DIMS (ra)[k].ubnd < SCM_ARRAY_DIMS (ra)[k].lbnd)
2046 return SCM_EOL;
2047 i = base + (1 + SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd) * inc;
2048 if (k < SCM_ARRAY_NDIM (ra) - 1)
2049 {
2050 do
2051 {
2052 i -= inc;
2053 res = scm_cons (ra2l (ra, i, k + 1), res);
2054 }
2055 while (i != base);
2056 }
2057 else
2058 do
2059 {
2060 i -= inc;
2061 res = scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra), SCM_MAKINUM (i)), res);
2062 }
2063 while (i != base);
2064 return res;
2065}
2066
2067
3b3b36dd 2068SCM_DEFINE (scm_array_to_list, "array->list", 1, 0, 0,
1bbd0b84 2069 (SCM v),
b380b885 2070 "Returns a list consisting of all the elements, in order, of @var{array}.")
1bbd0b84 2071#define FUNC_NAME s_scm_array_to_list
0f2d19dd
JB
2072{
2073 SCM res = SCM_EOL;
2074 register long k;
2075 SCM_ASRTGO (SCM_NIMP (v), badarg1);
2076 switch SCM_TYP7
2077 (v)
2078 {
2079 default:
1bbd0b84 2080 badarg1:SCM_WTA (1,v);
0f2d19dd
JB
2081 case scm_tc7_smob:
2082 SCM_ASRTGO (SCM_ARRAYP (v), badarg1);
2083 return ra2l (v, SCM_ARRAY_BASE (v), 0);
2084 case scm_tc7_vector:
95f5b0f5 2085 case scm_tc7_wvect:
0f2d19dd
JB
2086 return scm_vector_to_list (v);
2087 case scm_tc7_string:
2088 return scm_string_to_list (v);
2089 case scm_tc7_bvect:
2090 {
2091 long *data = (long *) SCM_VELTS (v);
2092 register unsigned long mask;
2093 for (k = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT; k > 0; k--)
cdbadcac 2094 for (mask = 1UL << (SCM_LONG_BIT - 1); mask; mask >>= 1)
156dcb09 2095 res = scm_cons (SCM_BOOL(((long *) data)[k] & mask), res);
0f2d19dd 2096 for (mask = 1L << ((SCM_LENGTH (v) % SCM_LONG_BIT) - 1); mask; mask >>= 1)
156dcb09 2097 res = scm_cons (SCM_BOOL(((long *) data)[k] & mask), res);
0f2d19dd
JB
2098 return res;
2099 }
2100# ifdef SCM_INUMS_ONLY
2101 case scm_tc7_uvect:
2102 case scm_tc7_ivect:
2103 {
2104 long *data = (long *) SCM_VELTS (v);
2105 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2106 res = scm_cons (SCM_MAKINUM (data[k]), res);
2107 return res;
2108 }
2109# else
2110 case scm_tc7_uvect: {
2111 long *data = (long *)SCM_VELTS(v);
2112 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
2113 res = scm_cons(scm_ulong2num(data[k]), res);
2114 return res;
2115 }
2116 case scm_tc7_ivect: {
2117 long *data = (long *)SCM_VELTS(v);
2118 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
2119 res = scm_cons(scm_long2num(data[k]), res);
2120 return res;
2121 }
2122# endif
2123 case scm_tc7_svect: {
2124 short *data;
2125 data = (short *)SCM_VELTS(v);
2126 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
2127 res = scm_cons(SCM_MAKINUM (data[k]), res);
2128 return res;
2129 }
5c11cc9d 2130#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
2131 case scm_tc7_llvect: {
2132 long_long *data;
2133 data = (long_long *)SCM_VELTS(v);
2134 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
2135 res = scm_cons(scm_long_long2num(data[k]), res);
2136 return res;
2137 }
2138#endif
2139
2140
2141#ifdef SCM_FLOATS
2142#ifdef SCM_SINGLES
2143 case scm_tc7_fvect:
2144 {
2145 float *data = (float *) SCM_VELTS (v);
2146 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2147 res = scm_cons (scm_makflo (data[k]), res);
2148 return res;
2149 }
2150#endif /*SCM_SINGLES*/
2151 case scm_tc7_dvect:
2152 {
2153 double *data = (double *) SCM_VELTS (v);
2154 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2155 res = scm_cons (scm_makdbl (data[k], 0.0), res);
2156 return res;
2157 }
2158 case scm_tc7_cvect:
2159 {
2160 double (*data)[2] = (double (*)[2]) SCM_VELTS (v);
2161 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2162 res = scm_cons (scm_makdbl (data[k][0], data[k][1]), res);
2163 return res;
2164 }
2165#endif /*SCM_FLOATS*/
2166 }
2167}
1bbd0b84 2168#undef FUNC_NAME
0f2d19dd
JB
2169
2170
20a54673 2171static char s_bad_ralst[] = "Bad scm_array contents list";
1cc91f1b 2172
1bbd0b84 2173static int l2ra(SCM lst, SCM ra, scm_sizet base, scm_sizet k);
1cc91f1b 2174
3b3b36dd 2175SCM_DEFINE (scm_list_to_uniform_array, "list->uniform-array", 3, 0, 0,
1bbd0b84 2176 (SCM ndim, SCM prot, SCM lst),
b380b885
MD
2177 "@deffnx procedure list->uniform-vector prot lst\n"
2178 "Returns a uniform array of the type indicated by prototype @var{prot}\n"
2179 "with elements the same as those of @var{lst}. Elements must be of the\n"
2180 "appropriate type, no coercions are done.")
1bbd0b84 2181#define FUNC_NAME s_scm_list_to_uniform_array
0f2d19dd
JB
2182{
2183 SCM shp = SCM_EOL;
2184 SCM row = lst;
2185 SCM ra;
2186 scm_sizet k;
2187 long n;
3b3b36dd 2188 SCM_VALIDATE_INUM_COPY (1,ndim,k);
0f2d19dd
JB
2189 while (k--)
2190 {
2191 n = scm_ilength (row);
1bbd0b84 2192 SCM_ASSERT (n >= 0, lst, SCM_ARG3, FUNC_NAME);
0f2d19dd
JB
2193 shp = scm_cons (SCM_MAKINUM (n), shp);
2194 if (SCM_NIMP (row))
2195 row = SCM_CAR (row);
2196 }
d12feca3
GH
2197 ra = scm_dimensions_to_uniform_array (scm_reverse (shp), prot,
2198 SCM_UNDEFINED);
0f2d19dd
JB
2199 if (SCM_NULLP (shp))
2200
2201 {
2202 SCM_ASRTGO (1 == scm_ilength (lst), badlst);
2203 scm_array_set_x (ra, SCM_CAR (lst), SCM_EOL);
2204 return ra;
2205 }
2206 if (!SCM_ARRAYP (ra))
2207 {
2208 for (k = 0; k < SCM_LENGTH (ra); k++, lst = SCM_CDR (lst))
2209 scm_array_set_x (ra, SCM_CAR (lst), SCM_MAKINUM (k));
2210 return ra;
2211 }
2212 if (l2ra (lst, ra, SCM_ARRAY_BASE (ra), 0))
2213 return ra;
2214 else
1bbd0b84 2215 badlst:scm_wta (lst, s_bad_ralst, FUNC_NAME);
0f2d19dd
JB
2216 return SCM_BOOL_F;
2217}
1bbd0b84 2218#undef FUNC_NAME
0f2d19dd 2219
0f2d19dd 2220static int
1bbd0b84 2221l2ra (SCM lst, SCM ra, scm_sizet base, scm_sizet k)
0f2d19dd
JB
2222{
2223 register long inc = SCM_ARRAY_DIMS (ra)[k].inc;
2224 register long n = (1 + SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd);
2225 int ok = 1;
2226 if (n <= 0)
2227 return (SCM_EOL == lst);
2228 if (k < SCM_ARRAY_NDIM (ra) - 1)
2229 {
2230 while (n--)
2231 {
2232 if (SCM_IMP (lst) || SCM_NCONSP (lst))
2233 return 0;
2234 ok = ok && l2ra (SCM_CAR (lst), ra, base, k + 1);
2235 base += inc;
2236 lst = SCM_CDR (lst);
2237 }
2238 if (SCM_NNULLP (lst))
2239 return 0;
2240 }
2241 else
2242 {
2243 while (n--)
2244 {
2245 if (SCM_IMP (lst) || SCM_NCONSP (lst))
2246 return 0;
2247 ok = ok && scm_array_set_x (SCM_ARRAY_V (ra), SCM_CAR (lst), SCM_MAKINUM (base));
2248 base += inc;
2249 lst = SCM_CDR (lst);
2250 }
2251 if (SCM_NNULLP (lst))
2252 return 0;
2253 }
2254 return ok;
2255}
2256
1cc91f1b 2257
0f2d19dd 2258static void
1bbd0b84 2259rapr1 (SCM ra,scm_sizet j,scm_sizet k,SCM port,scm_print_state *pstate)
0f2d19dd
JB
2260{
2261 long inc = 1;
2262 long n = SCM_LENGTH (ra);
2263 int enclosed = 0;
2264tail:
5c11cc9d 2265 switch SCM_TYP7 (ra)
0f2d19dd
JB
2266 {
2267 case scm_tc7_smob:
2268 if (enclosed++)
2269 {
2270 SCM_ARRAY_BASE (ra) = j;
2271 if (n-- > 0)
9882ea19 2272 scm_iprin1 (ra, port, pstate);
0f2d19dd
JB
2273 for (j += inc; n-- > 0; j += inc)
2274 {
b7f3516f 2275 scm_putc (' ', port);
0f2d19dd 2276 SCM_ARRAY_BASE (ra) = j;
9882ea19 2277 scm_iprin1 (ra, port, pstate);
0f2d19dd
JB
2278 }
2279 break;
2280 }
2281 if (k + 1 < SCM_ARRAY_NDIM (ra))
2282 {
2283 long i;
2284 inc = SCM_ARRAY_DIMS (ra)[k].inc;
2285 for (i = SCM_ARRAY_DIMS (ra)[k].lbnd; i < SCM_ARRAY_DIMS (ra)[k].ubnd; i++)
2286 {
b7f3516f 2287 scm_putc ('(', port);
9882ea19 2288 rapr1 (ra, j, k + 1, port, pstate);
b7f3516f 2289 scm_puts (") ", port);
0f2d19dd
JB
2290 j += inc;
2291 }
2292 if (i == SCM_ARRAY_DIMS (ra)[k].ubnd)
2293 { /* could be zero size. */
b7f3516f 2294 scm_putc ('(', port);
9882ea19 2295 rapr1 (ra, j, k + 1, port, pstate);
b7f3516f 2296 scm_putc (')', port);
0f2d19dd
JB
2297 }
2298 break;
2299 }
2300 if SCM_ARRAY_NDIM
2301 (ra)
2302 { /* Could be zero-dimensional */
2303 inc = SCM_ARRAY_DIMS (ra)[k].inc;
2304 n = (SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1);
2305 }
2306 else
2307 n = 1;
2308 ra = SCM_ARRAY_V (ra);
2309 goto tail;
2310 default:
5c11cc9d 2311 /* scm_tc7_bvect and scm_tc7_llvect only? */
0f2d19dd 2312 if (n-- > 0)
9882ea19 2313 scm_iprin1 (scm_uniform_vector_ref (ra, SCM_MAKINUM (j)), port, pstate);
0f2d19dd
JB
2314 for (j += inc; n-- > 0; j += inc)
2315 {
b7f3516f 2316 scm_putc (' ', port);
9882ea19 2317 scm_iprin1 (scm_cvref (ra, j, SCM_UNDEFINED), port, pstate);
0f2d19dd
JB
2318 }
2319 break;
2320 case scm_tc7_string:
2321 if (n-- > 0)
7866a09b 2322 scm_iprin1 (SCM_MAKE_CHAR (SCM_UCHARS (ra)[j]), port, pstate);
9882ea19 2323 if (SCM_WRITINGP (pstate))
0f2d19dd
JB
2324 for (j += inc; n-- > 0; j += inc)
2325 {
b7f3516f 2326 scm_putc (' ', port);
7866a09b 2327 scm_iprin1 (SCM_MAKE_CHAR (SCM_UCHARS (ra)[j]), port, pstate);
0f2d19dd
JB
2328 }
2329 else
2330 for (j += inc; n-- > 0; j += inc)
b7f3516f 2331 scm_putc (SCM_CHARS (ra)[j], port);
0f2d19dd
JB
2332 break;
2333 case scm_tc7_byvect:
2334 if (n-- > 0)
2335 scm_intprint (((char *)SCM_CDR (ra))[j], 10, port);
2336 for (j += inc; n-- > 0; j += inc)
2337 {
b7f3516f 2338 scm_putc (' ', port);
0f2d19dd
JB
2339 scm_intprint (((char *)SCM_CDR (ra))[j], 10, port);
2340 }
2341 break;
2342
2343 case scm_tc7_uvect:
5c11cc9d
GH
2344 {
2345 char str[11];
2346
2347 if (n-- > 0)
2348 {
2349 /* intprint can't handle >= 2^31. */
2350 sprintf (str, "%lu", (unsigned long) SCM_VELTS (ra)[j]);
2351 scm_puts (str, port);
2352 }
2353 for (j += inc; n-- > 0; j += inc)
2354 {
2355 scm_putc (' ', port);
2356 sprintf (str, "%lu", (unsigned long) SCM_VELTS (ra)[j]);
2357 scm_puts (str, port);
2358 }
2359 }
0f2d19dd
JB
2360 case scm_tc7_ivect:
2361 if (n-- > 0)
c209c88e 2362 scm_intprint ((int)SCM_VELTS (ra)[j], 10, port);
0f2d19dd
JB
2363 for (j += inc; n-- > 0; j += inc)
2364 {
b7f3516f 2365 scm_putc (' ', port);
c209c88e 2366 scm_intprint ((int)SCM_VELTS (ra)[j], 10, port);
0f2d19dd
JB
2367 }
2368 break;
2369
2370 case scm_tc7_svect:
2371 if (n-- > 0)
2372 scm_intprint (((short *)SCM_CDR (ra))[j], 10, port);
2373 for (j += inc; n-- > 0; j += inc)
2374 {
b7f3516f 2375 scm_putc (' ', port);
0f2d19dd
JB
2376 scm_intprint (((short *)SCM_CDR (ra))[j], 10, port);
2377 }
2378 break;
2379
2380#ifdef SCM_FLOATS
2381#ifdef SCM_SINGLES
2382 case scm_tc7_fvect:
2383 if (n-- > 0)
2384 {
2385 SCM z = scm_makflo (1.0);
2386 SCM_FLO (z) = ((float *) SCM_VELTS (ra))[j];
9882ea19 2387 scm_floprint (z, port, pstate);
0f2d19dd
JB
2388 for (j += inc; n-- > 0; j += inc)
2389 {
b7f3516f 2390 scm_putc (' ', port);
0f2d19dd 2391 SCM_FLO (z) = ((float *) SCM_VELTS (ra))[j];
9882ea19 2392 scm_floprint (z, port, pstate);
0f2d19dd
JB
2393 }
2394 }
2395 break;
2396#endif /*SCM_SINGLES*/
2397 case scm_tc7_dvect:
2398 if (n-- > 0)
2399 {
2400 SCM z = scm_makdbl (1.0 / 3.0, 0.0);
2401 SCM_REAL (z) = ((double *) SCM_VELTS (ra))[j];
9882ea19 2402 scm_floprint (z, port, pstate);
0f2d19dd
JB
2403 for (j += inc; n-- > 0; j += inc)
2404 {
b7f3516f 2405 scm_putc (' ', port);
0f2d19dd 2406 SCM_REAL (z) = ((double *) SCM_VELTS (ra))[j];
9882ea19 2407 scm_floprint (z, port, pstate);
0f2d19dd
JB
2408 }
2409 }
2410 break;
2411 case scm_tc7_cvect:
2412 if (n-- > 0)
2413 {
2414 SCM cz = scm_makdbl (0.0, 1.0), z = scm_makdbl (1.0 / 3.0, 0.0);
2415 SCM_REAL (z) = SCM_REAL (cz) = (((double *) SCM_VELTS (ra))[2 * j]);
2416 SCM_IMAG (cz) = ((double *) SCM_VELTS (ra))[2 * j + 1];
9882ea19 2417 scm_floprint ((0.0 == SCM_IMAG (cz) ? z : cz), port, pstate);
0f2d19dd
JB
2418 for (j += inc; n-- > 0; j += inc)
2419 {
b7f3516f 2420 scm_putc (' ', port);
0f2d19dd
JB
2421 SCM_REAL (z) = SCM_REAL (cz) = ((double *) SCM_VELTS (ra))[2 * j];
2422 SCM_IMAG (cz) = ((double *) SCM_VELTS (ra))[2 * j + 1];
9882ea19 2423 scm_floprint ((0.0 == SCM_IMAG (cz) ? z : cz), port, pstate);
0f2d19dd
JB
2424 }
2425 }
2426 break;
2427#endif /*SCM_FLOATS*/
2428 }
2429}
2430
2431
1cc91f1b 2432
0f2d19dd 2433int
1bbd0b84 2434scm_raprin1 (SCM exp, SCM port, scm_print_state *pstate)
0f2d19dd
JB
2435{
2436 SCM v = exp;
2437 scm_sizet base = 0;
b7f3516f 2438 scm_putc ('#', port);
0f2d19dd 2439tail:
5c11cc9d 2440 switch SCM_TYP7 (v)
0f2d19dd
JB
2441 {
2442 case scm_tc7_smob:
2443 {
2444 long ndim = SCM_ARRAY_NDIM (v);
2445 base = SCM_ARRAY_BASE (v);
2446 v = SCM_ARRAY_V (v);
2447 if (SCM_ARRAYP (v))
2448
2449 {
b7f3516f 2450 scm_puts ("<enclosed-array ", port);
9882ea19 2451 rapr1 (exp, base, 0, port, pstate);
b7f3516f 2452 scm_putc ('>', port);
0f2d19dd
JB
2453 return 1;
2454 }
2455 else
2456 {
2457 scm_intprint (ndim, 10, port);
2458 goto tail;
2459 }
2460 }
2461 case scm_tc7_bvect:
2462 if (exp == v)
2463 { /* a uve, not an scm_array */
2464 register long i, j, w;
b7f3516f 2465 scm_putc ('*', port);
0f2d19dd
JB
2466 for (i = 0; i < (SCM_LENGTH (exp)) / SCM_LONG_BIT; i++)
2467 {
c209c88e 2468 SCMWORD w = SCM_ASWORD (SCM_VELTS (exp)[i]);
0f2d19dd
JB
2469 for (j = SCM_LONG_BIT; j; j--)
2470 {
b7f3516f 2471 scm_putc (w & 1 ? '1' : '0', port);
0f2d19dd
JB
2472 w >>= 1;
2473 }
2474 }
2475 j = SCM_LENGTH (exp) % SCM_LONG_BIT;
2476 if (j)
2477 {
c209c88e 2478 w = SCM_ASWORD (SCM_VELTS (exp)[SCM_LENGTH (exp) / SCM_LONG_BIT]);
0f2d19dd
JB
2479 for (; j; j--)
2480 {
b7f3516f 2481 scm_putc (w & 1 ? '1' : '0', port);
0f2d19dd
JB
2482 w >>= 1;
2483 }
2484 }
2485 return 1;
2486 }
2487 else
b7f3516f 2488 scm_putc ('b', port);
0f2d19dd
JB
2489 break;
2490 case scm_tc7_string:
b7f3516f 2491 scm_putc ('a', port);
0f2d19dd
JB
2492 break;
2493 case scm_tc7_byvect:
05c33d09 2494 scm_putc ('y', port);
0f2d19dd
JB
2495 break;
2496 case scm_tc7_uvect:
b7f3516f 2497 scm_putc ('u', port);
0f2d19dd
JB
2498 break;
2499 case scm_tc7_ivect:
b7f3516f 2500 scm_putc ('e', port);
0f2d19dd
JB
2501 break;
2502 case scm_tc7_svect:
05c33d09 2503 scm_putc ('h', port);
0f2d19dd 2504 break;
5c11cc9d 2505#ifdef HAVE_LONG_LONGS
0f2d19dd 2506 case scm_tc7_llvect:
5c11cc9d 2507 scm_putc ('l', port);
0f2d19dd
JB
2508 break;
2509#endif
2510#ifdef SCM_FLOATS
2511#ifdef SCM_SINGLES
2512 case scm_tc7_fvect:
b7f3516f 2513 scm_putc ('s', port);
0f2d19dd
JB
2514 break;
2515#endif /*SCM_SINGLES*/
2516 case scm_tc7_dvect:
b7f3516f 2517 scm_putc ('i', port);
0f2d19dd
JB
2518 break;
2519 case scm_tc7_cvect:
b7f3516f 2520 scm_putc ('c', port);
0f2d19dd
JB
2521 break;
2522#endif /*SCM_FLOATS*/
2523 }
b7f3516f 2524 scm_putc ('(', port);
9882ea19 2525 rapr1 (exp, base, 0, port, pstate);
b7f3516f 2526 scm_putc (')', port);
0f2d19dd
JB
2527 return 1;
2528}
2529
3b3b36dd 2530SCM_DEFINE (scm_array_prototype, "array-prototype", 1, 0, 0,
1bbd0b84 2531 (SCM ra),
b380b885
MD
2532 "Returns an object that would produce an array of the same type as\n"
2533 "@var{array}, if used as the @var{prototype} for\n"
2534 "@code{make-uniform-array}.")
1bbd0b84 2535#define FUNC_NAME s_scm_array_prototype
0f2d19dd
JB
2536{
2537 int enclosed = 0;
2538 SCM_ASRTGO (SCM_NIMP (ra), badarg);
2539loop:
2540 switch SCM_TYP7
2541 (ra)
2542 {
2543 default:
1bbd0b84 2544 badarg:SCM_WTA (1,ra);
0f2d19dd
JB
2545 case scm_tc7_smob:
2546 SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
2547 if (enclosed++)
2548 return SCM_UNSPECIFIED;
2549 ra = SCM_ARRAY_V (ra);
2550 goto loop;
2551 case scm_tc7_vector:
95f5b0f5 2552 case scm_tc7_wvect:
0f2d19dd
JB
2553 return SCM_EOL;
2554 case scm_tc7_bvect:
2555 return SCM_BOOL_T;
2556 case scm_tc7_string:
7866a09b 2557 return SCM_MAKE_CHAR ('a');
0f2d19dd 2558 case scm_tc7_byvect:
7866a09b 2559 return SCM_MAKE_CHAR ('\0');
0f2d19dd
JB
2560 case scm_tc7_uvect:
2561 return SCM_MAKINUM (1L);
2562 case scm_tc7_ivect:
2563 return SCM_MAKINUM (-1L);
2564 case scm_tc7_svect:
2565 return SCM_CDR (scm_intern ("s", 1));
5c11cc9d 2566#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
2567 case scm_tc7_llvect:
2568 return SCM_CDR (scm_intern ("l", 1));
2569#endif
2570#ifdef SCM_FLOATS
2571#ifdef SCM_SINGLES
2572 case scm_tc7_fvect:
2573 return scm_makflo (1.0);
2574#endif
2575 case scm_tc7_dvect:
2576 return scm_makdbl (1.0 / 3.0, 0.0);
2577 case scm_tc7_cvect:
2578 return scm_makdbl (0.0, 1.0);
2579#endif
2580 }
2581}
1bbd0b84 2582#undef FUNC_NAME
0f2d19dd 2583
1cc91f1b 2584
0f2d19dd 2585static SCM
1bbd0b84 2586markra (SCM ptr)
0f2d19dd 2587{
0f2d19dd
JB
2588 return SCM_ARRAY_V (ptr);
2589}
2590
1cc91f1b 2591
0f2d19dd 2592static scm_sizet
1bbd0b84 2593freera (SCM ptr)
0f2d19dd
JB
2594{
2595 scm_must_free (SCM_CHARS (ptr));
2596 return sizeof (scm_array) + SCM_ARRAY_NDIM (ptr) * sizeof (scm_array_dim);
2597}
2598
0f2d19dd
JB
2599void
2600scm_init_unif ()
0f2d19dd 2601{
23a62151
MD
2602 scm_tc16_array = scm_make_smob_type_mfpe ("array", 0,
2603 markra,
2604 freera,
2605 scm_raprin1,
2606 scm_array_equal_p);
0f2d19dd 2607 scm_add_feature ("array");
23a62151 2608#include "unif.x"
0f2d19dd 2609}