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