1 /* Copyright (C) 1995,1996,1997,1998, 2000 Free Software Foundation, Inc.
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)
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.
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
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
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.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
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.
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.
40 * If you do not wish that, delete this exception notice. */
42 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
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.)
75 /* The set of uniform scm_vector types is:
77 * unsigned char string
84 * complex double cvect
91 /* return the size of an element in a uniform array or 0 if type not
94 scm_uniform_element_size (SCM obj
)
98 switch (SCM_TYP7 (obj
))
103 result
= sizeof (long);
107 result
= sizeof (char);
111 result
= sizeof (short);
114 #ifdef HAVE_LONG_LONGS
116 result
= sizeof (long_long
);
121 result
= sizeof (float);
125 result
= sizeof (double);
129 result
= 2 * sizeof (double);
138 /* Silly function used not to modify the semantics of the silly
139 * prototype system in order to be backward compatible.
144 if (!SCM_SLOPPY_REALP (obj
))
148 double x
= SCM_REAL_VALUE (obj
);
150 return (- SCM_FLTMAX
< x
) && (x
< SCM_FLTMAX
) && (fx
== x
);
155 scm_make_uve (long k
, SCM prot
)
159 if (SCM_TRUE_P (prot
))
161 i
= sizeof (long) * ((k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
);
162 type
= scm_tc7_bvect
;
164 else if (SCM_CHARP (prot
) && (SCM_CHAR (prot
) == '\0'))
166 i
= sizeof (char) * k
;
167 type
= scm_tc7_byvect
;
169 else if (SCM_CHARP (prot
))
171 i
= sizeof (char) * k
;
172 type
= scm_tc7_string
;
174 else if (SCM_INUMP (prot
))
176 i
= sizeof (long) * k
;
177 if (SCM_INUM (prot
) > 0)
178 type
= scm_tc7_uvect
;
180 type
= scm_tc7_ivect
;
182 else if (SCM_SYMBOLP (prot
) && (1 == SCM_LENGTH (prot
)))
186 s
= SCM_CHARS (prot
)[0];
189 i
= sizeof (short) * k
;
190 type
= scm_tc7_svect
;
192 #ifdef HAVE_LONG_LONGS
195 i
= sizeof (long_long
) * k
;
196 type
= scm_tc7_llvect
;
201 return scm_make_vector (SCM_MAKINUM (k
), SCM_UNDEFINED
);
205 if (SCM_IMP (prot
) || !SCM_INEXP (prot
))
206 /* Huge non-unif vectors are NOT supported. */
207 /* no special scm_vector */
208 return scm_make_vector (SCM_MAKINUM (k
), SCM_UNDEFINED
);
209 else if (singp (prot
))
211 i
= sizeof (float) * k
;
212 type
= scm_tc7_fvect
;
214 else if (SCM_CPLXP (prot
))
216 i
= 2 * sizeof (double) * k
;
217 type
= scm_tc7_cvect
;
221 i
= sizeof (double) * k
;
222 type
= scm_tc7_dvect
;
227 SCM_SETCHARS (v
, (char *) scm_must_malloc (i
? i
: 1, "vector"));
228 SCM_SETLENGTH (v
, (k
< SCM_LENGTH_MAX
? k
: SCM_LENGTH_MAX
), type
);
233 SCM_DEFINE (scm_uniform_vector_length
, "uniform-vector-length", 1, 0, 0,
235 "Returns the number of elements in @var{uve}.")
236 #define FUNC_NAME s_scm_uniform_vector_length
238 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
243 badarg1
:SCM_WTA(1,v
);
255 #ifdef HAVE_LONG_LONGS
258 return SCM_MAKINUM (SCM_LENGTH (v
));
263 SCM_DEFINE (scm_array_p
, "array?", 1, 1, 0,
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"
268 #define FUNC_NAME s_scm_array_p
272 nprot
= SCM_UNBNDP (prot
);
277 while (SCM_TYP7 (v
) == scm_tc7_smob
)
288 return SCM_BOOL(nprot
);
293 switch (SCM_TYP7 (v
))
296 protp
= (SCM_TRUE_P (prot
));
298 protp
= SCM_CHARP(prot
) && (SCM_CHAR (prot
) != '\0');
300 protp
= SCM_EQ_P (prot
, SCM_MAKE_CHAR ('\0'));
302 protp
= SCM_INUMP(prot
) && SCM_INUM(prot
)>0;
304 protp
= SCM_INUMP(prot
) && SCM_INUM(prot
)<=0;
307 protp
= SCM_SYMBOLP (prot
)
308 && (1 == SCM_LENGTH (prot
))
309 && ('s' == SCM_CHARS (prot
)[0]);
310 #ifdef HAVE_LONG_LONGS
312 protp
= SCM_SYMBOLP (prot
)
313 && (1 == SCM_LENGTH (prot
))
314 && ('s' == SCM_CHARS (prot
)[0]);
317 protp
= singp (prot
);
319 protp
= SCM_REALP(prot
);
321 protp
= SCM_CPLXP(prot
);
324 protp
= SCM_NULLP(prot
);
329 return SCM_BOOL(protp
);
335 SCM_DEFINE (scm_array_rank
, "array-rank", 1, 0, 0,
337 "Returns the number of dimensions of @var{obj}. If @var{obj} is not an\n"
338 "array, @code{0} is returned.")
339 #define FUNC_NAME s_scm_array_rank
343 switch (SCM_TYP7 (ra
))
356 #ifdef HAVE_LONG_LONGS
360 return SCM_MAKINUM (1L);
363 return SCM_MAKINUM (SCM_ARRAY_NDIM (ra
));
370 SCM_DEFINE (scm_array_dimensions
, "array-dimensions", 1, 0, 0,
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"
375 "(array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5)\n"
377 #define FUNC_NAME s_scm_array_dimensions
384 switch (SCM_TYP7 (ra
))
399 #ifdef HAVE_LONG_LONGS
402 return scm_cons (SCM_MAKINUM (SCM_LENGTH (ra
)), SCM_EOL
);
404 if (!SCM_ARRAYP (ra
))
406 k
= SCM_ARRAY_NDIM (ra
);
407 s
= SCM_ARRAY_DIMS (ra
);
409 res
= scm_cons (s
[k
].lbnd
410 ? scm_cons2 (SCM_MAKINUM (s
[k
].lbnd
),
411 SCM_MAKINUM (s
[k
].ubnd
),
413 : SCM_MAKINUM (1 + s
[k
].ubnd
),
421 SCM_DEFINE (scm_shared_array_root
, "shared-array-root", 1, 0, 0,
423 "Return the root vector of a shared array.")
424 #define FUNC_NAME s_scm_shared_array_root
426 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
427 return SCM_ARRAY_V (ra
);
432 SCM_DEFINE (scm_shared_array_offset
, "shared-array-offset", 1, 0, 0,
434 "Return the root vector index of the first element in the array.")
435 #define FUNC_NAME s_scm_shared_array_offset
437 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
438 return SCM_MAKINUM (SCM_ARRAY_BASE (ra
));
443 SCM_DEFINE (scm_shared_array_increments
, "shared-array-increments", 1, 0, 0,
445 "For each dimension, return the distance between elements in the root vector.")
446 #define FUNC_NAME s_scm_shared_array_increments
451 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
452 k
= SCM_ARRAY_NDIM (ra
);
453 s
= SCM_ARRAY_DIMS (ra
);
455 res
= scm_cons (SCM_MAKINUM (s
[k
].inc
), res
);
461 static char s_bad_ind
[] = "Bad scm_array index";
465 scm_aind (SCM ra
, SCM args
, const char *what
)
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
))
474 SCM_ASSERT (1 == k
, scm_makfrom0str (what
), SCM_WNA
, NULL
);
475 return pos
+ (SCM_INUM (args
) - s
->lbnd
) * (s
->inc
);
477 while (k
&& SCM_NIMP (args
))
479 ind
= SCM_CAR (args
);
480 args
= SCM_CDR (args
);
481 SCM_ASSERT (SCM_INUMP (ind
), ind
, s_bad_ind
, what
);
483 SCM_ASSERT (j
>= (s
->lbnd
) && j
<= (s
->ubnd
), ind
, SCM_OUTOFRANGE
, what
);
484 pos
+= (j
- s
->lbnd
) * (s
->inc
);
488 SCM_ASSERT (0 == k
&& SCM_NULLP (args
), scm_makfrom0str (what
), SCM_WNA
,
496 scm_make_ra (int ndim
)
501 SCM_NEWSMOB(ra
, ((long) ndim
<< 17) + scm_tc16_array
,
502 scm_must_malloc ((long) (sizeof (scm_array
) + ndim
* sizeof (scm_array_dim
)),
504 SCM_ARRAY_V (ra
) = scm_nullvect
;
509 static char s_bad_spec
[] = "Bad scm_array dimension";
510 /* Increments will still need to be set. */
514 scm_shap2ra (SCM args
, const char *what
)
518 int ndim
= scm_ilength (args
);
519 SCM_ASSERT (0 <= ndim
, args
, s_bad_spec
, what
);
520 ra
= scm_make_ra (ndim
);
521 SCM_ARRAY_BASE (ra
) = 0;
522 s
= SCM_ARRAY_DIMS (ra
);
523 for (; SCM_NIMP (args
); s
++, args
= SCM_CDR (args
))
525 spec
= SCM_CAR (args
);
529 SCM_ASSERT (SCM_INUMP (spec
) && SCM_INUM (spec
) >= 0, spec
,
532 s
->ubnd
= SCM_INUM (spec
) - 1;
537 SCM_ASSERT (SCM_CONSP (spec
) && SCM_INUMP (SCM_CAR (spec
)), spec
,
539 s
->lbnd
= SCM_INUM (SCM_CAR (spec
));
541 SCM_ASSERT (SCM_CONSP (sp
)
542 && SCM_INUMP (SCM_CAR (sp
)) && SCM_NULLP (SCM_CDR (sp
)),
543 spec
, s_bad_spec
, what
);
544 s
->ubnd
= SCM_INUM (SCM_CAR (sp
));
551 SCM_DEFINE (scm_dimensions_to_uniform_array
, "dimensions->uniform-array", 2, 1, 0,
552 (SCM dims
, SCM prot
, SCM fill
),
553 "@deffnx primitive make-uniform-vector length prototype [fill]\n"
554 "Creates and returns a uniform array or vector of type corresponding to\n"
555 "@var{prototype} with dimensions @var{dims} or length @var{length}. If\n"
556 "@var{fill} is supplied, it's used to fill the array, otherwise \n"
557 "@var{prototype} is used.")
558 #define FUNC_NAME s_scm_dimensions_to_uniform_array
560 scm_sizet k
, vlen
= 1;
564 if (SCM_INUMP (dims
))
566 if (SCM_INUM (dims
) < SCM_LENGTH_MAX
)
568 SCM answer
= scm_make_uve (SCM_INUM (dims
), prot
);
570 if (!SCM_UNBNDP (fill
))
571 scm_array_fill_x (answer
, fill
);
572 else if (SCM_SYMBOLP (prot
))
573 scm_array_fill_x (answer
, SCM_MAKINUM (0));
575 scm_array_fill_x (answer
, prot
);
579 dims
= scm_cons (dims
, SCM_EOL
);
581 SCM_ASSERT (SCM_NULLP (dims
) || SCM_CONSP (dims
),
582 dims
, SCM_ARG1
, FUNC_NAME
);
583 ra
= scm_shap2ra (dims
, FUNC_NAME
);
584 SCM_SETOR_CAR (ra
, SCM_ARRAY_CONTIGUOUS
);
585 s
= SCM_ARRAY_DIMS (ra
);
586 k
= SCM_ARRAY_NDIM (ra
);
589 s
[k
].inc
= (rlen
> 0 ? rlen
: 0);
590 rlen
= (s
[k
].ubnd
- s
[k
].lbnd
+ 1) * s
[k
].inc
;
591 vlen
*= (s
[k
].ubnd
- s
[k
].lbnd
+ 1);
593 if (rlen
< SCM_LENGTH_MAX
)
594 SCM_ARRAY_V (ra
) = scm_make_uve ((rlen
> 0 ? rlen
: 0L), prot
);
598 switch (SCM_TYP7 (scm_make_uve (0L, prot
)))
610 bit
= sizeof (float) * SCM_CHAR_BIT
/ sizeof (char);
613 bit
= sizeof (double) * SCM_CHAR_BIT
/ sizeof (char);
616 bit
= 2 * sizeof (double) * SCM_CHAR_BIT
/ sizeof (char);
619 SCM_ARRAY_BASE (ra
) = (SCM_LONG_BIT
+ bit
- 1) / bit
;
620 rlen
+= SCM_ARRAY_BASE (ra
);
621 SCM_ARRAY_V (ra
) = scm_make_uve (rlen
, prot
);
622 *((long *) SCM_VELTS (SCM_ARRAY_V (ra
))) = rlen
;
624 if (!SCM_UNBNDP (fill
))
626 scm_array_fill_x (ra
, fill
);
628 else if (SCM_SYMBOLP (prot
))
629 scm_array_fill_x (ra
, SCM_MAKINUM (0));
631 scm_array_fill_x (ra
, prot
);
632 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
633 if (s
->ubnd
< s
->lbnd
|| (0 == s
->lbnd
&& 1 == s
->inc
))
634 return SCM_ARRAY_V (ra
);
641 scm_ra_set_contp (SCM ra
)
643 scm_sizet k
= SCM_ARRAY_NDIM (ra
);
646 long inc
= SCM_ARRAY_DIMS (ra
)[k
- 1].inc
;
649 if (inc
!= SCM_ARRAY_DIMS (ra
)[k
].inc
)
651 SCM_SETAND_CAR (ra
, ~SCM_ARRAY_CONTIGUOUS
);
654 inc
*= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
655 - SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
658 SCM_SETOR_CAR (ra
, SCM_ARRAY_CONTIGUOUS
);
662 SCM_DEFINE (scm_make_shared_array
, "make-shared-array", 2, 0, 1,
663 (SCM oldra
, SCM mapfunc
, SCM dims
),
664 "@code{make-shared-array} can be used to create shared subarrays of other\n"
665 "arrays. The @var{mapper} is a function that translates coordinates in\n"
666 "the new array into coordinates in the old array. A @var{mapper} must be\n"
667 "linear, and its range must stay within the bounds of the old array, but\n"
668 "it can be otherwise arbitrary. A simple example:\n"
670 "(define fred (make-array #f 8 8))\n"
671 "(define freds-diagonal\n"
672 " (make-shared-array fred (lambda (i) (list i i)) 8))\n"
673 "(array-set! freds-diagonal 'foo 3)\n"
674 "(array-ref fred 3 3) @result{} foo\n"
675 "(define freds-center\n"
676 " (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))\n"
677 "(array-ref freds-center 0 0) @result{} foo\n"
679 #define FUNC_NAME s_scm_make_shared_array
685 long old_min
, new_min
, old_max
, new_max
;
687 SCM_VALIDATE_ARRAY (1,oldra
);
688 SCM_VALIDATE_PROC (2,mapfunc
);
689 ra
= scm_shap2ra (dims
, FUNC_NAME
);
690 if (SCM_ARRAYP (oldra
))
692 SCM_ARRAY_V (ra
) = SCM_ARRAY_V (oldra
);
693 old_min
= old_max
= SCM_ARRAY_BASE (oldra
);
694 s
= SCM_ARRAY_DIMS (oldra
);
695 k
= SCM_ARRAY_NDIM (oldra
);
699 old_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
701 old_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
706 SCM_ARRAY_V (ra
) = oldra
;
708 old_max
= (long) SCM_LENGTH (oldra
) - 1;
711 s
= SCM_ARRAY_DIMS (ra
);
712 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
714 inds
= scm_cons (SCM_MAKINUM (s
[k
].lbnd
), inds
);
715 if (s
[k
].ubnd
< s
[k
].lbnd
)
717 if (1 == SCM_ARRAY_NDIM (ra
))
718 ra
= scm_make_uve (0L, scm_array_prototype (ra
));
720 SCM_ARRAY_V (ra
) = scm_make_uve (0L, scm_array_prototype (ra
));
724 imap
= scm_apply (mapfunc
, scm_reverse (inds
), SCM_EOL
);
725 if (SCM_ARRAYP (oldra
))
726 i
= (scm_sizet
) scm_aind (oldra
, imap
, FUNC_NAME
);
729 if (SCM_NINUMP (imap
))
732 SCM_ASSERT (1 == scm_ilength (imap
) && SCM_INUMP (SCM_CAR (imap
)),
733 imap
, s_bad_ind
, FUNC_NAME
);
734 imap
= SCM_CAR (imap
);
738 SCM_ARRAY_BASE (ra
) = new_min
= new_max
= i
;
740 k
= SCM_ARRAY_NDIM (ra
);
743 if (s
[k
].ubnd
> s
[k
].lbnd
)
745 SCM_SETCAR (indptr
, SCM_MAKINUM (SCM_INUM (SCM_CAR (indptr
)) + 1));
746 imap
= scm_apply (mapfunc
, scm_reverse (inds
), SCM_EOL
);
747 if (SCM_ARRAYP (oldra
))
749 s
[k
].inc
= scm_aind (oldra
, imap
, FUNC_NAME
) - i
;
752 if (SCM_NINUMP (imap
))
755 SCM_ASSERT (1 == scm_ilength (imap
) && SCM_INUMP (SCM_CAR (imap
)),
756 imap
, s_bad_ind
, FUNC_NAME
);
757 imap
= SCM_CAR (imap
);
759 s
[k
].inc
= (long) SCM_INUM (imap
) - i
;
763 new_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
765 new_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
768 s
[k
].inc
= new_max
- new_min
+ 1; /* contiguous by default */
769 indptr
= SCM_CDR (indptr
);
771 SCM_ASSERT (old_min
<= new_min
&& old_max
>= new_max
, SCM_UNDEFINED
,
772 "mapping out of range", FUNC_NAME
);
773 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
775 if (1 == s
->inc
&& 0 == s
->lbnd
776 && SCM_LENGTH (SCM_ARRAY_V (ra
)) == 1 + s
->ubnd
)
777 return SCM_ARRAY_V (ra
);
778 if (s
->ubnd
< s
->lbnd
)
779 return scm_make_uve (0L, scm_array_prototype (ra
));
781 scm_ra_set_contp (ra
);
787 /* args are RA . DIMS */
788 SCM_DEFINE (scm_transpose_array
, "transpose-array", 0, 0, 1,
790 "Returns an array sharing contents with @var{array}, but with dimensions\n"
791 "arranged in a different order. There must be one @var{dim} argument for\n"
792 "each dimension of @var{array}. @var{dim0}, @var{dim1}, @dots{} should\n"
793 "be integers between 0 and the rank of the array to be returned. Each\n"
794 "integer in that range must appear at least once in the argument list.\n\n"
795 "The values of @var{dim0}, @var{dim1}, @dots{} correspond to dimensions\n"
796 "in the array to be returned, their positions in the argument list to\n"
797 "dimensions of @var{array}. Several @var{dim}s may have the same value,\n"
798 "in which case the returned array will have smaller rank than\n"
802 "(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))\n"
803 "(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)\n"
804 "(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}\n"
805 " #2((a 4) (b 5) (c 6))\n"
807 #define FUNC_NAME s_scm_transpose_array
809 SCM ra
, res
, vargs
, *ve
= &vargs
;
810 scm_array_dim
*s
, *r
;
812 SCM_ASSERT (SCM_NNULLP (args
), scm_makfrom0str (FUNC_NAME
),
815 SCM_ASSERT (SCM_NIMP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
816 args
= SCM_CDR (args
);
817 switch (SCM_TYP7 (ra
))
820 badarg
:SCM_WTA (1,ra
);
830 #ifdef HAVE_LONG_LONGS
833 SCM_ASSERT (SCM_NIMP (args
) && SCM_NULLP (SCM_CDR (args
)),
834 scm_makfrom0str (FUNC_NAME
), SCM_WNA
, NULL
);
835 SCM_ASSERT (SCM_INUMP (SCM_CAR (args
)), SCM_CAR (args
), SCM_ARG2
,
837 SCM_ASSERT (SCM_EQ_P (SCM_INUM0
, SCM_CAR (args
)), SCM_CAR (args
), SCM_OUTOFRANGE
,
841 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
842 vargs
= scm_vector (args
);
843 SCM_ASSERT (SCM_LENGTH (vargs
) == SCM_ARRAY_NDIM (ra
),
844 scm_makfrom0str (FUNC_NAME
), SCM_WNA
, NULL
);
845 ve
= SCM_VELTS (vargs
);
847 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
849 SCM_ASSERT (SCM_INUMP (ve
[k
]), ve
[k
], (SCM_ARG2
+ k
),
851 i
= SCM_INUM (ve
[k
]);
852 SCM_ASSERT (i
>= 0 && i
< SCM_ARRAY_NDIM (ra
), ve
[k
],
853 SCM_OUTOFRANGE
, FUNC_NAME
);
858 res
= scm_make_ra (ndim
);
859 SCM_ARRAY_V (res
) = SCM_ARRAY_V (ra
);
860 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra
);
863 SCM_ARRAY_DIMS (res
)[k
].lbnd
= 0;
864 SCM_ARRAY_DIMS (res
)[k
].ubnd
= -1;
866 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
868 i
= SCM_INUM (ve
[k
]);
869 s
= &(SCM_ARRAY_DIMS (ra
)[k
]);
870 r
= &(SCM_ARRAY_DIMS (res
)[i
]);
871 if (r
->ubnd
< r
->lbnd
)
880 if (r
->ubnd
> s
->ubnd
)
882 if (r
->lbnd
< s
->lbnd
)
884 SCM_ARRAY_BASE (res
) += (s
->lbnd
- r
->lbnd
) * r
->inc
;
890 SCM_ASSERT (ndim
<= 0, args
, "bad argument list", FUNC_NAME
);
891 scm_ra_set_contp (res
);
897 /* args are RA . AXES */
898 SCM_DEFINE (scm_enclose_array
, "enclose-array", 0, 0, 1,
900 "@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than\n"
901 "the rank of @var{array}. @var{enclose-array} returns an array\n"
902 "resembling an array of shared arrays. The dimensions of each shared\n"
903 "array are the same as the @var{dim}th dimensions of the original array,\n"
904 "the dimensions of the outer array are the same as those of the original\n"
905 "array that did not match a @var{dim}.\n\n"
906 "An enclosed array is not a general Scheme array. Its elements may not\n"
907 "be set using @code{array-set!}. Two references to the same element of\n"
908 "an enclosed array will be @code{equal?} but will not in general be\n"
909 "@code{eq?}. The value returned by @var{array-prototype} when given an\n"
910 "enclosed array is unspecified.\n\n"
913 "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) @result{}\n"
914 " #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>\n\n"
915 "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{}\n"
916 " #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>\n"
918 #define FUNC_NAME s_scm_enclose_array
920 SCM axv
, ra
, res
, ra_inr
;
921 scm_array_dim vdim
, *s
= &vdim
;
922 int ndim
, j
, k
, ninr
, noutr
;
923 SCM_ASSERT (SCM_NIMP (axes
), scm_makfrom0str (FUNC_NAME
), SCM_WNA
,
926 axes
= SCM_CDR (axes
);
927 if (SCM_NULLP (axes
))
928 axes
= scm_cons ((SCM_ARRAYP (ra
) ? SCM_MAKINUM (SCM_ARRAY_NDIM (ra
) - 1) : SCM_INUM0
), SCM_EOL
);
929 ninr
= scm_ilength (axes
);
930 ra_inr
= scm_make_ra (ninr
);
931 SCM_ASRTGO (SCM_NIMP (ra
), badarg1
);
936 badarg1
:SCM_WTA (1,ra
);
948 #ifdef HAVE_LONG_LONGS
952 s
->ubnd
= SCM_LENGTH (ra
) - 1;
954 SCM_ARRAY_V (ra_inr
) = ra
;
955 SCM_ARRAY_BASE (ra_inr
) = 0;
959 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg1
);
960 s
= SCM_ARRAY_DIMS (ra
);
961 SCM_ARRAY_V (ra_inr
) = SCM_ARRAY_V (ra
);
962 SCM_ARRAY_BASE (ra_inr
) = SCM_ARRAY_BASE (ra
);
963 ndim
= SCM_ARRAY_NDIM (ra
);
967 axv
= scm_make_string (SCM_MAKINUM (ndim
), SCM_MAKE_CHAR (0));
968 SCM_ASSERT (0 <= noutr
&& 0 <= ninr
, scm_makfrom0str (FUNC_NAME
),
970 res
= scm_make_ra (noutr
);
971 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra_inr
);
972 SCM_ARRAY_V (res
) = ra_inr
;
973 for (k
= 0; k
< ninr
; k
++, axes
= SCM_CDR (axes
))
975 SCM_ASSERT (SCM_INUMP (SCM_CAR (axes
)), SCM_CAR (axes
), "bad axis", FUNC_NAME
);
976 j
= SCM_INUM (SCM_CAR (axes
));
977 SCM_ARRAY_DIMS (ra_inr
)[k
].lbnd
= s
[j
].lbnd
;
978 SCM_ARRAY_DIMS (ra_inr
)[k
].ubnd
= s
[j
].ubnd
;
979 SCM_ARRAY_DIMS (ra_inr
)[k
].inc
= s
[j
].inc
;
980 SCM_CHARS (axv
)[j
] = 1;
982 for (j
= 0, k
= 0; k
< noutr
; k
++, j
++)
984 while (SCM_CHARS (axv
)[j
])
986 SCM_ARRAY_DIMS (res
)[k
].lbnd
= s
[j
].lbnd
;
987 SCM_ARRAY_DIMS (res
)[k
].ubnd
= s
[j
].ubnd
;
988 SCM_ARRAY_DIMS (res
)[k
].inc
= s
[j
].inc
;
990 scm_ra_set_contp (ra_inr
);
991 scm_ra_set_contp (res
);
998 SCM_DEFINE (scm_array_in_bounds_p
, "array-in-bounds?", 0, 0, 1,
1000 "Returns @code{#t} if its arguments would be acceptable to array-ref.")
1001 #define FUNC_NAME s_scm_array_in_bounds_p
1003 SCM v
, ind
= SCM_EOL
;
1005 register scm_sizet k
;
1008 SCM_ASSERT (SCM_NIMP (args
), scm_makfrom0str (FUNC_NAME
),
1011 args
= SCM_CDR (args
);
1012 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1013 if (SCM_NIMP (args
))
1016 ind
= SCM_CAR (args
);
1017 args
= SCM_CDR (args
);
1018 SCM_ASSERT (SCM_INUMP (ind
), ind
, SCM_ARG2
, FUNC_NAME
);
1019 pos
= SCM_INUM (ind
);
1026 badarg1
:SCM_WTA (1,v
);
1027 wna
: scm_wrong_num_args (scm_makfrom0str (FUNC_NAME
));
1029 k
= SCM_ARRAY_NDIM (v
);
1030 s
= SCM_ARRAY_DIMS (v
);
1031 pos
= SCM_ARRAY_BASE (v
);
1034 SCM_ASRTGO (SCM_NULLP (ind
), wna
);
1041 if (!(j
>= (s
->lbnd
) && j
<= (s
->ubnd
)))
1043 SCM_ASRTGO (--k
== scm_ilength (args
), wna
);
1046 pos
+= (j
- s
->lbnd
) * (s
->inc
);
1047 if (!(--k
&& SCM_NIMP (args
)))
1049 ind
= SCM_CAR (args
);
1050 args
= SCM_CDR (args
);
1052 SCM_ASSERT (SCM_INUMP (ind
), ind
, s_bad_ind
, FUNC_NAME
);
1054 SCM_ASRTGO (0 == k
, wna
);
1055 v
= SCM_ARRAY_V (v
);
1058 case scm_tc7_string
:
1059 case scm_tc7_byvect
:
1066 #ifdef HAVE_LONG_LONGS
1067 case scm_tc7_llvect
:
1069 case scm_tc7_vector
:
1071 SCM_ASRTGO (SCM_NULLP (args
) && SCM_INUMP (ind
), wna
);
1072 return SCM_BOOL(pos
>= 0 && pos
< SCM_LENGTH (v
));
1078 SCM_REGISTER_PROC(s_array_ref
, "array-ref", 1, 0, 1, scm_uniform_vector_ref
);
1081 SCM_DEFINE (scm_uniform_vector_ref
, "uniform-vector-ref", 2, 0, 0,
1083 "Returns the element at the @code{(index1, index2)} element in @var{array}.")
1084 #define FUNC_NAME s_scm_uniform_vector_ref
1090 SCM_ASRTGO (SCM_NULLP (args
), badarg
);
1093 else if (SCM_ARRAYP (v
))
1095 pos
= scm_aind (v
, args
, FUNC_NAME
);
1096 v
= SCM_ARRAY_V (v
);
1100 if (SCM_NIMP (args
))
1103 SCM_ASSERT (SCM_CONSP (args
) && SCM_INUMP (SCM_CAR (args
)), args
, SCM_ARG2
, FUNC_NAME
);
1104 pos
= SCM_INUM (SCM_CAR (args
));
1105 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1109 SCM_VALIDATE_INUM (2,args
);
1110 pos
= SCM_INUM (args
);
1112 SCM_ASRTGO (pos
>= 0 && pos
< SCM_LENGTH (v
), outrng
);
1118 if (SCM_NULLP (args
))
1125 scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (pos
));
1127 scm_wrong_num_args (SCM_FUNC_NAME
);
1130 int k
= SCM_ARRAY_NDIM (v
);
1131 SCM res
= scm_make_ra (k
);
1132 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1133 SCM_ARRAY_BASE (res
) = pos
;
1136 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1137 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1138 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1143 if (SCM_BITVEC_REF (v
, pos
))
1147 case scm_tc7_string
:
1148 return SCM_MAKE_CHAR (SCM_UCHARS (v
)[pos
]);
1149 case scm_tc7_byvect
:
1150 return SCM_MAKINUM (((char *)SCM_CHARS (v
))[pos
]);
1152 return scm_ulong2num((unsigned long ) SCM_VELTS(v
)[pos
]);
1154 return scm_long2num((long) SCM_VELTS(v
)[pos
]);
1157 return SCM_MAKINUM (((short *) SCM_CELL_WORD_1 (v
))[pos
]);
1158 #ifdef HAVE_LONG_LONGS
1159 case scm_tc7_llvect
:
1160 return scm_long_long2num (((long_long
*) SCM_CELL_WORD_1 (v
))[pos
]);
1164 return scm_make_real (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1166 return scm_make_real (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1168 return scm_make_complex (((double *) SCM_CELL_WORD_1 (v
))[2 * pos
],
1169 ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1]);
1170 case scm_tc7_vector
:
1172 return SCM_VELTS (v
)[pos
];
1177 /* Internal version of scm_uniform_vector_ref for uves that does no error checking and
1178 tries to recycle conses. (Make *sure* you want them recycled.) */
1181 scm_cvref (SCM v
, scm_sizet pos
, SCM last
)
1186 scm_wta (v
, (char *) SCM_ARG1
, "PROGRAMMING ERROR: scm_cvref");
1188 if (SCM_BITVEC_REF(v
,pos
))
1192 case scm_tc7_string
:
1193 return SCM_MAKE_CHAR (SCM_UCHARS (v
)[pos
]);
1194 case scm_tc7_byvect
:
1195 return SCM_MAKINUM (((char *)SCM_CHARS (v
))[pos
]);
1197 return scm_ulong2num((unsigned long) SCM_VELTS(v
)[pos
]);
1199 return scm_long2num((long) SCM_VELTS(v
)[pos
]);
1201 return SCM_MAKINUM (((short *) SCM_CELL_WORD_1 (v
))[pos
]);
1202 #ifdef HAVE_LONG_LONGS
1203 case scm_tc7_llvect
:
1204 return scm_long_long2num (((long_long
*) SCM_CELL_WORD_1 (v
))[pos
]);
1207 if (SCM_NIMP (last
) && last
!= scm_flo0
&& SCM_SLOPPY_REALP (last
))
1209 SCM_REAL_VALUE (last
) = ((float *) SCM_CELL_WORD_1 (v
))[pos
];
1212 return scm_make_real (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1214 if (SCM_NIMP (last
) && last
!= scm_flo0
&& SCM_SLOPPY_REALP (last
))
1216 SCM_REAL_VALUE (last
) = ((double *) SCM_CELL_WORD_1 (v
))[pos
];
1219 return scm_make_real (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1221 if (SCM_NIMP (last
) && SCM_SLOPPY_COMPLEXP (last
))
1223 SCM_COMPLEX_REAL (last
) = ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
];
1224 SCM_COMPLEX_IMAG (last
) = ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1];
1227 return scm_make_complex (((double *) SCM_CELL_WORD_1 (v
))[2 * pos
],
1228 ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1]);
1229 case scm_tc7_vector
:
1231 return SCM_VELTS (v
)[pos
];
1233 { /* enclosed scm_array */
1234 int k
= SCM_ARRAY_NDIM (v
);
1235 SCM res
= scm_make_ra (k
);
1236 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1237 SCM_ARRAY_BASE (res
) = pos
;
1240 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1241 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1242 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1249 SCM_REGISTER_PROC(s_uniform_array_set1_x
, "uniform-array-set1!", 3, 0, 0, scm_array_set_x
);
1252 /* Note that args may be a list or an immediate object, depending which
1253 PROC is used (and it's called from C too). */
1254 SCM_DEFINE (scm_array_set_x
, "array-set!", 2, 0, 1,
1255 (SCM v
, SCM obj
, SCM args
),
1256 "Sets the element at the @code{(index1, index2)} element in @var{array} to\n"
1257 "@var{new-value}. The value returned by array-set! is unspecified.")
1258 #define FUNC_NAME s_scm_array_set_x
1261 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1264 pos
= scm_aind (v
, args
, FUNC_NAME
);
1265 v
= SCM_ARRAY_V (v
);
1269 if (SCM_NIMP (args
))
1271 SCM_ASSERT (SCM_CONSP(args
) && SCM_INUMP (SCM_CAR (args
)), args
,
1272 SCM_ARG3
, FUNC_NAME
);
1273 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1274 pos
= SCM_INUM (SCM_CAR (args
));
1278 SCM_VALIDATE_INUM_COPY (3,args
,pos
);
1280 SCM_ASRTGO (pos
>= 0 && pos
< SCM_LENGTH (v
), outrng
);
1282 switch (SCM_TYP7 (v
))
1288 scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (pos
));
1290 scm_wrong_num_args (SCM_FUNC_NAME
);
1291 case scm_tc7_smob
: /* enclosed */
1294 if (SCM_FALSEP (obj
))
1295 SCM_BITVEC_CLR(v
,pos
);
1296 else if (SCM_TRUE_P (obj
))
1297 SCM_BITVEC_SET(v
,pos
);
1299 badobj
:SCM_WTA (2,obj
);
1301 case scm_tc7_string
:
1302 SCM_ASRTGO (SCM_CHARP (obj
), badobj
);
1303 SCM_UCHARS (v
)[pos
] = SCM_CHAR (obj
);
1305 case scm_tc7_byvect
:
1306 if (SCM_CHARP (obj
))
1307 obj
= SCM_MAKINUM ((char) SCM_CHAR (obj
));
1308 SCM_ASRTGO (SCM_INUMP (obj
), badobj
);
1309 ((char *)SCM_CHARS (v
))[pos
] = SCM_INUM (obj
);
1312 SCM_VELTS(v
)[pos
] = SCM_PACK (scm_num2ulong(obj
, (char *)SCM_ARG2
, FUNC_NAME
));
1315 SCM_VELTS(v
)[pos
] = SCM_PACK (scm_num2long(obj
, (char *)SCM_ARG2
, FUNC_NAME
));
1318 SCM_ASRTGO (SCM_INUMP (obj
), badobj
);
1319 ((short *) SCM_CELL_WORD_1 (v
))[pos
] = SCM_INUM (obj
);
1321 #ifdef HAVE_LONG_LONGS
1322 case scm_tc7_llvect
:
1323 ((long_long
*) SCM_CELL_WORD_1 (v
))[pos
] = scm_num2long_long (obj
, (char *)SCM_ARG2
, FUNC_NAME
);
1329 ((float *) SCM_CELL_WORD_1 (v
))[pos
] = (float) scm_num2dbl (obj
, FUNC_NAME
);
1332 ((double *) SCM_CELL_WORD_1 (v
))[pos
] = scm_num2dbl (obj
, FUNC_NAME
);
1335 SCM_ASRTGO (SCM_INEXP (obj
), badobj
);
1336 ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
] = SCM_REALPART (obj
);
1337 ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1] = SCM_CPLXP (obj
) ? SCM_IMAG (obj
) : 0.0;
1339 case scm_tc7_vector
:
1341 SCM_VELTS (v
)[pos
] = obj
;
1344 return SCM_UNSPECIFIED
;
1348 /* attempts to unroll an array into a one-dimensional array.
1349 returns the unrolled array or #f if it can't be done. */
1350 /* if strict is not SCM_UNDEFINED, return #f if returned array
1351 wouldn't have contiguous elements. */
1352 SCM_DEFINE (scm_array_contents
, "array-contents", 1, 1, 0,
1353 (SCM ra
, SCM strict
),
1354 "@deffnx primitive array-contents array strict\n"
1355 "If @var{array} may be @dfn{unrolled} into a one dimensional shared array\n"
1356 "without changing their order (last subscript changing fastest), then\n"
1357 "@code{array-contents} returns that shared array, otherwise it returns\n"
1358 "@code{#f}. All arrays made by @var{make-array} and\n"
1359 "@var{make-uniform-array} may be unrolled, some arrays made by\n"
1360 "@var{make-shared-array} may not be.\n\n"
1361 "If the optional argument @var{strict} is provided, a shared array will\n"
1362 "be returned only if its elements are stored internally contiguous in\n"
1364 #define FUNC_NAME s_scm_array_contents
1369 switch SCM_TYP7 (ra
)
1373 case scm_tc7_vector
:
1375 case scm_tc7_string
:
1377 case scm_tc7_byvect
:
1384 #ifdef HAVE_LONG_LONGS
1385 case scm_tc7_llvect
:
1390 scm_sizet k
, ndim
= SCM_ARRAY_NDIM (ra
), len
= 1;
1391 if (!SCM_ARRAYP (ra
) || !SCM_ARRAY_CONTP (ra
))
1393 for (k
= 0; k
< ndim
; k
++)
1394 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1395 if (!SCM_UNBNDP (strict
))
1397 if (ndim
&& (1 != SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
))
1399 if (scm_tc7_bvect
== SCM_TYP7 (SCM_ARRAY_V (ra
)))
1401 if (len
!= SCM_LENGTH (SCM_ARRAY_V (ra
)) ||
1402 SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
||
1407 if ((len
== SCM_LENGTH (SCM_ARRAY_V (ra
))) && 0 == SCM_ARRAY_BASE (ra
) && SCM_ARRAY_DIMS (ra
)->inc
)
1408 return SCM_ARRAY_V (ra
);
1409 sra
= scm_make_ra (1);
1410 SCM_ARRAY_DIMS (sra
)->lbnd
= 0;
1411 SCM_ARRAY_DIMS (sra
)->ubnd
= len
- 1;
1412 SCM_ARRAY_V (sra
) = SCM_ARRAY_V (ra
);
1413 SCM_ARRAY_BASE (sra
) = SCM_ARRAY_BASE (ra
);
1414 SCM_ARRAY_DIMS (sra
)->inc
= (ndim
? SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
: 1);
1423 scm_ra2contig (SCM ra
, int copy
)
1427 scm_sizet k
, len
= 1;
1428 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
1429 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1430 k
= SCM_ARRAY_NDIM (ra
);
1431 if (SCM_ARRAY_CONTP (ra
) && ((0 == k
) || (1 == SCM_ARRAY_DIMS (ra
)[k
- 1].inc
)))
1433 if (scm_tc7_bvect
!= SCM_TYP7 (ra
))
1435 if ((len
== SCM_LENGTH (SCM_ARRAY_V (ra
)) &&
1436 0 == SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
&&
1437 0 == len
% SCM_LONG_BIT
))
1440 ret
= scm_make_ra (k
);
1441 SCM_ARRAY_BASE (ret
) = 0;
1444 SCM_ARRAY_DIMS (ret
)[k
].lbnd
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
;
1445 SCM_ARRAY_DIMS (ret
)[k
].ubnd
= SCM_ARRAY_DIMS (ra
)[k
].ubnd
;
1446 SCM_ARRAY_DIMS (ret
)[k
].inc
= inc
;
1447 inc
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1449 SCM_ARRAY_V (ret
) = scm_make_uve ((inc
- 1), scm_array_prototype (ra
));
1451 scm_array_copy_x (ra
, ret
);
1457 SCM_DEFINE (scm_uniform_array_read_x
, "uniform-array-read!", 1, 3, 0,
1458 (SCM ra
, SCM port_or_fd
, SCM start
, SCM end
),
1459 "@deffnx primitive uniform-vector-read! uve [port-or-fdes] [start] [end]\n"
1460 "Attempts to read all elements of @var{ura}, in lexicographic order, as\n"
1461 "binary objects from @var{port-or-fdes}.\n"
1462 "If an end of file is encountered during\n"
1463 "uniform-array-read! the objects up to that point only are put into @var{ura}\n"
1464 "(starting at the beginning) and the remainder of the array is\n"
1466 "The optional arguments @var{start} and @var{end} allow\n"
1467 "a specified region of a vector (or linearized array) to be read,\n"
1468 "leaving the remainder of the vector unchanged.\n\n"
1469 "@code{uniform-array-read!} returns the number of objects read.\n"
1470 "@var{port-or-fdes} may be omitted, in which case it defaults to the value\n"
1471 "returned by @code{(current-input-port)}.")
1472 #define FUNC_NAME s_scm_uniform_array_read_x
1474 SCM cra
= SCM_UNDEFINED
, v
= ra
;
1480 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1481 if (SCM_UNBNDP (port_or_fd
))
1482 port_or_fd
= scm_cur_inp
;
1484 SCM_ASSERT (SCM_INUMP (port_or_fd
)
1485 || (SCM_OPINPORTP (port_or_fd
)),
1486 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1487 vlen
= SCM_LENGTH (v
);
1493 badarg1
:SCM_WTA (SCM_ARG1
,v
);
1495 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1496 cra
= scm_ra2contig (ra
, 0);
1497 cstart
+= SCM_ARRAY_BASE (cra
);
1498 vlen
= SCM_ARRAY_DIMS (cra
)->inc
*
1499 (SCM_ARRAY_DIMS (cra
)->ubnd
- SCM_ARRAY_DIMS (cra
)->lbnd
+ 1);
1500 v
= SCM_ARRAY_V (cra
);
1502 case scm_tc7_string
:
1503 case scm_tc7_byvect
:
1507 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1508 cstart
/= SCM_LONG_BIT
;
1514 sz
= sizeof (short);
1516 #ifdef HAVE_LONG_LONGS
1517 case scm_tc7_llvect
:
1518 sz
= sizeof (long_long
);
1522 sz
= sizeof (float);
1525 sz
= sizeof (double);
1528 sz
= 2 * sizeof (double);
1533 if (!SCM_UNBNDP (start
))
1536 SCM_NUM2LONG (3, start
);
1538 if (offset
< 0 || offset
>= cend
)
1539 scm_out_of_range (FUNC_NAME
, start
);
1541 if (!SCM_UNBNDP (end
))
1544 SCM_NUM2LONG (4, end
);
1546 if (tend
<= offset
|| tend
> cend
)
1547 scm_out_of_range (FUNC_NAME
, end
);
1552 if (SCM_NIMP (port_or_fd
))
1554 scm_port
*pt
= SCM_PTAB_ENTRY (port_or_fd
);
1555 int remaining
= (cend
- offset
) * sz
;
1556 char *dest
= SCM_CHARS (v
) + (cstart
+ offset
) * sz
;
1558 if (pt
->rw_active
== SCM_PORT_WRITE
)
1559 scm_flush (port_or_fd
);
1561 ans
= cend
- offset
;
1562 while (remaining
> 0)
1564 if (pt
->read_pos
< pt
->read_end
)
1566 int to_copy
= min (pt
->read_end
- pt
->read_pos
,
1569 memcpy (dest
, pt
->read_pos
, to_copy
);
1570 pt
->read_pos
+= to_copy
;
1571 remaining
-= to_copy
;
1576 if (scm_fill_input (port_or_fd
) == EOF
)
1578 if (remaining
% sz
!= 0)
1580 SCM_MISC_ERROR ("unexpected EOF", SCM_EOL
);
1582 ans
-= remaining
/ sz
;
1589 pt
->rw_active
= SCM_PORT_READ
;
1591 else /* file descriptor. */
1593 SCM_SYSCALL (ans
= read (SCM_INUM (port_or_fd
),
1594 SCM_CHARS (v
) + (cstart
+ offset
) * sz
,
1595 (scm_sizet
) (sz
* (cend
- offset
))));
1599 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1600 ans
*= SCM_LONG_BIT
;
1602 if (v
!= ra
&& cra
!= ra
)
1603 scm_array_copy_x (cra
, ra
);
1605 return SCM_MAKINUM (ans
);
1609 SCM_DEFINE (scm_uniform_array_write
, "uniform-array-write", 1, 3, 0,
1610 (SCM v
, SCM port_or_fd
, SCM start
, SCM end
),
1611 "@deffnx primitive uniform-vector-write uve [port-or-fdes] [start] [end]\n"
1612 "Writes all elements of @var{ura} as binary objects to\n"
1613 "@var{port-or-fdes}.\n\n"
1614 "The optional arguments @var{start}\n"
1615 "and @var{end} allow\n"
1616 "a specified region of a vector (or linearized array) to be written.\n\n"
1617 "The number of objects actually written is returned. \n"
1618 "@var{port-or-fdes} may be\n"
1619 "omitted, in which case it defaults to the value returned by\n"
1620 "@code{(current-output-port)}.")
1621 #define FUNC_NAME s_scm_uniform_array_write
1628 port_or_fd
= SCM_COERCE_OUTPORT (port_or_fd
);
1630 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1631 if (SCM_UNBNDP (port_or_fd
))
1632 port_or_fd
= scm_cur_outp
;
1634 SCM_ASSERT (SCM_INUMP (port_or_fd
)
1635 || (SCM_OPOUTPORTP (port_or_fd
)),
1636 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1637 vlen
= SCM_LENGTH (v
);
1643 badarg1
:SCM_WTA (1, v
);
1645 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1646 v
= scm_ra2contig (v
, 1);
1647 cstart
= SCM_ARRAY_BASE (v
);
1648 vlen
= SCM_ARRAY_DIMS (v
)->inc
1649 * (SCM_ARRAY_DIMS (v
)->ubnd
- SCM_ARRAY_DIMS (v
)->lbnd
+ 1);
1650 v
= SCM_ARRAY_V (v
);
1652 case scm_tc7_string
:
1653 case scm_tc7_byvect
:
1657 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1658 cstart
/= SCM_LONG_BIT
;
1664 sz
= sizeof (short);
1666 #ifdef HAVE_LONG_LONGS
1667 case scm_tc7_llvect
:
1668 sz
= sizeof (long_long
);
1672 sz
= sizeof (float);
1675 sz
= sizeof (double);
1678 sz
= 2 * sizeof (double);
1683 if (!SCM_UNBNDP (start
))
1686 SCM_NUM2LONG (3, start
);
1688 if (offset
< 0 || offset
>= cend
)
1689 scm_out_of_range (FUNC_NAME
, start
);
1691 if (!SCM_UNBNDP (end
))
1694 SCM_NUM2LONG (4, end
);
1696 if (tend
<= offset
|| tend
> cend
)
1697 scm_out_of_range (FUNC_NAME
, end
);
1702 if (SCM_NIMP (port_or_fd
))
1704 char *source
= SCM_CHARS (v
) + (cstart
+ offset
) * sz
;
1706 ans
= cend
- offset
;
1707 scm_lfwrite (source
, ans
* sz
, port_or_fd
);
1709 else /* file descriptor. */
1711 SCM_SYSCALL (ans
= write (SCM_INUM (port_or_fd
),
1712 SCM_CHARS (v
) + (cstart
+ offset
) * sz
,
1713 (scm_sizet
) (sz
* (cend
- offset
))));
1717 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1718 ans
*= SCM_LONG_BIT
;
1720 return SCM_MAKINUM (ans
);
1725 static char cnt_tab
[16] =
1726 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1728 SCM_DEFINE (scm_bit_count
, "bit-count", 2, 0, 0,
1729 (SCM item
, SCM seq
),
1730 "Returns the number occurrences of @var{bool} in @var{bv}.")
1731 #define FUNC_NAME s_scm_bit_count
1734 register unsigned long cnt
= 0;
1735 register unsigned long w
;
1736 SCM_VALIDATE_INUM (2,seq
);
1737 switch SCM_TYP7 (seq
)
1742 if (0 == SCM_LENGTH (seq
))
1744 i
= (SCM_LENGTH (seq
) - 1) / SCM_LONG_BIT
;
1745 w
= SCM_UNPACK (SCM_VELTS (seq
)[i
]);
1746 if (SCM_FALSEP (item
))
1748 w
<<= SCM_LONG_BIT
- 1 - ((SCM_LENGTH (seq
) - 1) % SCM_LONG_BIT
);
1752 cnt
+= cnt_tab
[w
& 0x0f];
1754 return SCM_MAKINUM (cnt
);
1755 w
= SCM_UNPACK (SCM_VELTS (seq
)[i
]);
1756 if (SCM_FALSEP (item
))
1764 SCM_DEFINE (scm_bit_position
, "bit-position", 3, 0, 0,
1765 (SCM item
, SCM v
, SCM k
),
1766 "Returns the minimum index of an occurrence of @var{bool} in @var{bv}\n"
1767 "which is at least @var{k}. If no @var{bool} occurs within the specified\n"
1768 "range @code{#f} is returned.")
1769 #define FUNC_NAME s_scm_bit_position
1771 long i
, lenw
, xbits
, pos
;
1772 register unsigned long w
;
1773 SCM_VALIDATE_NIM (2,v
);
1774 SCM_VALIDATE_INUM_COPY (3,k
,pos
);
1775 SCM_ASSERT ((pos
<= SCM_LENGTH (v
)) && (pos
>= 0),
1776 k
, SCM_OUTOFRANGE
, FUNC_NAME
);
1777 if (pos
== SCM_LENGTH (v
))
1784 if (0 == SCM_LENGTH (v
))
1785 return SCM_MAKINUM (-1L);
1786 lenw
= (SCM_LENGTH (v
) - 1) / SCM_LONG_BIT
; /* watch for part words */
1787 i
= pos
/ SCM_LONG_BIT
;
1788 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1789 if (SCM_FALSEP (item
))
1791 xbits
= (pos
% SCM_LONG_BIT
);
1793 w
= ((w
>> xbits
) << xbits
);
1794 xbits
= SCM_LONG_BIT
- 1 - (SCM_LENGTH (v
) - 1) % SCM_LONG_BIT
;
1797 if (w
&& (i
== lenw
))
1798 w
= ((w
<< xbits
) >> xbits
);
1804 return SCM_MAKINUM (pos
);
1809 return SCM_MAKINUM (pos
+ 1);
1812 return SCM_MAKINUM (pos
+ 2);
1814 return SCM_MAKINUM (pos
+ 3);
1821 pos
+= SCM_LONG_BIT
;
1822 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1823 if (SCM_FALSEP (item
))
1832 SCM_DEFINE (scm_bit_set_star_x
, "bit-set*!", 3, 0, 0,
1833 (SCM v
, SCM kv
, SCM obj
),
1834 "If uve is a bit-vector @var{bv} and uve must be of the same length. If\n"
1835 "@var{bool} is @code{#t}, uve is OR'ed into @var{bv}; If @var{bool} is @code{#f}, the\n"
1836 "inversion of uve is AND'ed into @var{bv}.\n\n"
1837 "If uve is a unsigned integer vector all the elements of uve must be\n"
1838 "between 0 and the @code{LENGTH} of @var{bv}. The bits of @var{bv}\n"
1839 "corresponding to the indexes in uve are set to @var{bool}.\n\n"
1840 "The return value is unspecified.")
1841 #define FUNC_NAME s_scm_bit_set_star_x
1843 register long i
, k
, vlen
;
1844 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1845 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1846 switch SCM_TYP7 (kv
)
1849 badarg2
:SCM_WTA (2,kv
);
1854 badarg1
: SCM_WTA (1,v
);
1856 vlen
= SCM_LENGTH (v
);
1857 if (SCM_FALSEP (obj
))
1858 for (i
= SCM_LENGTH (kv
); i
;)
1860 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1861 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1862 SCM_BITVEC_CLR(v
,k
);
1864 else if (SCM_TRUE_P (obj
))
1865 for (i
= SCM_LENGTH (kv
); i
;)
1867 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1868 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1869 SCM_BITVEC_SET(v
,k
);
1872 badarg3
:SCM_WTA (3,obj
);
1876 SCM_ASRTGO (SCM_TYP7 (v
) == scm_tc7_bvect
&& SCM_LENGTH (v
) == SCM_LENGTH (kv
), badarg1
);
1877 if (SCM_FALSEP (obj
))
1878 for (k
= (SCM_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1879 SCM_UNPACK (SCM_VELTS (v
)[k
]) &= ~ SCM_UNPACK(SCM_VELTS (kv
)[k
]);
1880 else if (SCM_TRUE_P (obj
))
1881 for (k
= (SCM_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1882 SCM_UNPACK (SCM_VELTS (v
)[k
]) |= SCM_UNPACK (SCM_VELTS (kv
)[k
]);
1887 return SCM_UNSPECIFIED
;
1892 SCM_DEFINE (scm_bit_count_star
, "bit-count*", 3, 0, 0,
1893 (SCM v
, SCM kv
, SCM obj
),
1896 "(bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t).\n"
1898 "@var{bv} is not modified.")
1899 #define FUNC_NAME s_scm_bit_count_star
1901 register long i
, vlen
, count
= 0;
1902 register unsigned long k
;
1905 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1906 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1907 switch SCM_TYP7 (kv
)
1920 vlen
= SCM_LENGTH (v
);
1921 if (SCM_FALSEP (obj
))
1922 for (i
= SCM_LENGTH (kv
); i
;)
1924 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1925 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1926 if (!SCM_BITVEC_REF(v
,k
))
1929 else if (SCM_TRUE_P (obj
))
1930 for (i
= SCM_LENGTH (kv
); i
;)
1932 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1933 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1934 if (SCM_BITVEC_REF (v
,k
))
1938 badarg3
:SCM_WTA (3,obj
);
1942 SCM_ASRTGO (SCM_TYP7 (v
) == scm_tc7_bvect
&& SCM_LENGTH (v
) == SCM_LENGTH (kv
), badarg1
);
1943 if (0 == SCM_LENGTH (v
))
1945 SCM_ASRTGO (SCM_BOOLP (obj
), badarg3
);
1946 fObj
= SCM_TRUE_P (obj
);
1947 i
= (SCM_LENGTH (v
) - 1) / SCM_LONG_BIT
;
1948 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK (SCM_VELTS (v
)[i
]) : ~ SCM_UNPACK (SCM_VELTS (v
)[i
]));
1949 k
<<= SCM_LONG_BIT
- 1 - ((SCM_LENGTH (v
) - 1) % SCM_LONG_BIT
);
1953 count
+= cnt_tab
[k
& 0x0f];
1955 return SCM_MAKINUM (count
);
1957 /* urg. repetitive (see above.) */
1958 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK(SCM_VELTS (v
)[i
]) : ~SCM_UNPACK (SCM_VELTS (v
)[i
]));
1961 return SCM_MAKINUM (count
);
1966 SCM_DEFINE (scm_bit_invert_x
, "bit-invert!", 1, 0, 0,
1968 "Modifies @var{bv} by replacing each element with its negation.")
1969 #define FUNC_NAME s_scm_bit_invert_x
1972 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1978 for (k
= (k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1979 SCM_UNPACK (SCM_VELTS (v
)[k
]) = ~SCM_UNPACK(SCM_VELTS (v
)[k
]);
1982 badarg1
:SCM_WTA (1,v
);
1984 return SCM_UNSPECIFIED
;
1990 scm_istr2bve (char *str
, long len
)
1992 SCM v
= scm_make_uve (len
, SCM_BOOL_T
);
1993 long *data
= (long *) SCM_VELTS (v
);
1994 register unsigned long mask
;
1997 for (k
= 0; k
< (len
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
++)
2000 j
= len
- k
* SCM_LONG_BIT
;
2001 if (j
> SCM_LONG_BIT
)
2003 for (mask
= 1L; j
--; mask
<<= 1)
2021 ra2l (SCM ra
,scm_sizet base
,scm_sizet k
)
2023 register SCM res
= SCM_EOL
;
2024 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2025 register scm_sizet i
;
2026 if (SCM_ARRAY_DIMS (ra
)[k
].ubnd
< SCM_ARRAY_DIMS (ra
)[k
].lbnd
)
2028 i
= base
+ (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
) * inc
;
2029 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2034 res
= scm_cons (ra2l (ra
, i
, k
+ 1), res
);
2042 res
= scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra
), SCM_MAKINUM (i
)), res
);
2049 SCM_DEFINE (scm_array_to_list
, "array->list", 1, 0, 0,
2051 "Returns a list consisting of all the elements, in order, of @var{array}.")
2052 #define FUNC_NAME s_scm_array_to_list
2056 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
2061 badarg1
:SCM_WTA (1,v
);
2063 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
2064 return ra2l (v
, SCM_ARRAY_BASE (v
), 0);
2065 case scm_tc7_vector
:
2067 return scm_vector_to_list (v
);
2068 case scm_tc7_string
:
2069 return scm_string_to_list (v
);
2072 long *data
= (long *) SCM_VELTS (v
);
2073 register unsigned long mask
;
2074 for (k
= (SCM_LENGTH (v
) - 1) / SCM_LONG_BIT
; k
> 0; k
--)
2075 for (mask
= 1UL << (SCM_LONG_BIT
- 1); mask
; mask
>>= 1)
2076 res
= scm_cons (SCM_BOOL(((long *) data
)[k
] & mask
), res
);
2077 for (mask
= 1L << ((SCM_LENGTH (v
) % SCM_LONG_BIT
) - 1); mask
; mask
>>= 1)
2078 res
= scm_cons (SCM_BOOL(((long *) data
)[k
] & mask
), res
);
2081 case scm_tc7_uvect
: {
2082 long *data
= (long *)SCM_VELTS(v
);
2083 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2084 res
= scm_cons(scm_ulong2num(data
[k
]), res
);
2087 case scm_tc7_ivect
: {
2088 long *data
= (long *)SCM_VELTS(v
);
2089 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2090 res
= scm_cons(scm_long2num(data
[k
]), res
);
2093 case scm_tc7_svect
: {
2095 data
= (short *)SCM_VELTS(v
);
2096 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2097 res
= scm_cons(SCM_MAKINUM (data
[k
]), res
);
2100 #ifdef HAVE_LONG_LONGS
2101 case scm_tc7_llvect
: {
2103 data
= (long_long
*)SCM_VELTS(v
);
2104 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2105 res
= scm_cons(scm_long_long2num(data
[k
]), res
);
2113 float *data
= (float *) SCM_VELTS (v
);
2114 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2115 res
= scm_cons (scm_make_real (data
[k
]), res
);
2120 double *data
= (double *) SCM_VELTS (v
);
2121 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2122 res
= scm_cons (scm_makdbl (data
[k
], 0.0), res
);
2127 double (*data
)[2] = (double (*)[2]) SCM_VELTS (v
);
2128 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2129 res
= scm_cons (scm_makdbl (data
[k
][0], data
[k
][1]), res
);
2137 static char s_bad_ralst
[] = "Bad scm_array contents list";
2139 static int l2ra(SCM lst
, SCM ra
, scm_sizet base
, scm_sizet k
);
2141 SCM_DEFINE (scm_list_to_uniform_array
, "list->uniform-array", 3, 0, 0,
2142 (SCM ndim
, SCM prot
, SCM lst
),
2143 "@deffnx procedure list->uniform-vector prot lst\n"
2144 "Returns a uniform array of the type indicated by prototype @var{prot}\n"
2145 "with elements the same as those of @var{lst}. Elements must be of the\n"
2146 "appropriate type, no coercions are done.")
2147 #define FUNC_NAME s_scm_list_to_uniform_array
2154 SCM_VALIDATE_INUM_COPY (1,ndim
,k
);
2157 n
= scm_ilength (row
);
2158 SCM_ASSERT (n
>= 0, lst
, SCM_ARG3
, FUNC_NAME
);
2159 shp
= scm_cons (SCM_MAKINUM (n
), shp
);
2161 row
= SCM_CAR (row
);
2163 ra
= scm_dimensions_to_uniform_array (scm_reverse (shp
), prot
,
2165 if (SCM_NULLP (shp
))
2168 SCM_ASRTGO (1 == scm_ilength (lst
), badlst
);
2169 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_EOL
);
2172 if (!SCM_ARRAYP (ra
))
2174 for (k
= 0; k
< SCM_LENGTH (ra
); k
++, lst
= SCM_CDR (lst
))
2175 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_MAKINUM (k
));
2178 if (l2ra (lst
, ra
, SCM_ARRAY_BASE (ra
), 0))
2181 badlst
:scm_wta (lst
, s_bad_ralst
, FUNC_NAME
);
2187 l2ra (SCM lst
, SCM ra
, scm_sizet base
, scm_sizet k
)
2189 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2190 register long n
= (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
);
2193 return (SCM_NULLP (lst
));
2194 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2198 if (SCM_IMP (lst
) || SCM_NCONSP (lst
))
2200 ok
= ok
&& l2ra (SCM_CAR (lst
), ra
, base
, k
+ 1);
2202 lst
= SCM_CDR (lst
);
2204 if (SCM_NNULLP (lst
))
2211 if (SCM_IMP (lst
) || SCM_NCONSP (lst
))
2213 ok
= ok
&& scm_array_set_x (SCM_ARRAY_V (ra
), SCM_CAR (lst
), SCM_MAKINUM (base
));
2215 lst
= SCM_CDR (lst
);
2217 if (SCM_NNULLP (lst
))
2225 rapr1 (SCM ra
,scm_sizet j
,scm_sizet k
,SCM port
,scm_print_state
*pstate
)
2228 long n
= SCM_LENGTH (ra
);
2231 switch SCM_TYP7 (ra
)
2236 SCM_ARRAY_BASE (ra
) = j
;
2238 scm_iprin1 (ra
, port
, pstate
);
2239 for (j
+= inc
; n
-- > 0; j
+= inc
)
2241 scm_putc (' ', port
);
2242 SCM_ARRAY_BASE (ra
) = j
;
2243 scm_iprin1 (ra
, port
, pstate
);
2247 if (k
+ 1 < SCM_ARRAY_NDIM (ra
))
2250 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2251 for (i
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
; i
< SCM_ARRAY_DIMS (ra
)[k
].ubnd
; i
++)
2253 scm_putc ('(', port
);
2254 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2255 scm_puts (") ", port
);
2258 if (i
== SCM_ARRAY_DIMS (ra
)[k
].ubnd
)
2259 { /* could be zero size. */
2260 scm_putc ('(', port
);
2261 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2262 scm_putc (')', port
);
2268 { /* Could be zero-dimensional */
2269 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2270 n
= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
2274 ra
= SCM_ARRAY_V (ra
);
2277 /* scm_tc7_bvect and scm_tc7_llvect only? */
2279 scm_iprin1 (scm_uniform_vector_ref (ra
, SCM_MAKINUM (j
)), port
, pstate
);
2280 for (j
+= inc
; n
-- > 0; j
+= inc
)
2282 scm_putc (' ', port
);
2283 scm_iprin1 (scm_cvref (ra
, j
, SCM_UNDEFINED
), port
, pstate
);
2286 case scm_tc7_string
:
2288 scm_iprin1 (SCM_MAKE_CHAR (SCM_UCHARS (ra
)[j
]), port
, pstate
);
2289 if (SCM_WRITINGP (pstate
))
2290 for (j
+= inc
; n
-- > 0; j
+= inc
)
2292 scm_putc (' ', port
);
2293 scm_iprin1 (SCM_MAKE_CHAR (SCM_UCHARS (ra
)[j
]), port
, pstate
);
2296 for (j
+= inc
; n
-- > 0; j
+= inc
)
2297 scm_putc (SCM_CHARS (ra
)[j
], port
);
2299 case scm_tc7_byvect
:
2301 scm_intprint (((char *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2302 for (j
+= inc
; n
-- > 0; j
+= inc
)
2304 scm_putc (' ', port
);
2305 scm_intprint (((char *)SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2315 /* intprint can't handle >= 2^31. */
2316 sprintf (str
, "%lu", (unsigned long) SCM_VELTS (ra
)[j
]);
2317 scm_puts (str
, port
);
2319 for (j
+= inc
; n
-- > 0; j
+= inc
)
2321 scm_putc (' ', port
);
2322 sprintf (str
, "%lu", (unsigned long) SCM_VELTS (ra
)[j
]);
2323 scm_puts (str
, port
);
2328 scm_intprint ((int)SCM_VELTS (ra
)[j
], 10, port
);
2329 for (j
+= inc
; n
-- > 0; j
+= inc
)
2331 scm_putc (' ', port
);
2332 scm_intprint ((int)SCM_VELTS (ra
)[j
], 10, port
);
2338 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2339 for (j
+= inc
; n
-- > 0; j
+= inc
)
2341 scm_putc (' ', port
);
2342 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2349 SCM z
= scm_make_real (1.0);
2350 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2351 scm_print_real (z
, port
, pstate
);
2352 for (j
+= inc
; n
-- > 0; j
+= inc
)
2354 scm_putc (' ', port
);
2355 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2356 scm_print_real (z
, port
, pstate
);
2363 SCM z
= scm_make_real (1.0 / 3.0);
2364 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2365 scm_print_real (z
, port
, pstate
);
2366 for (j
+= inc
; n
-- > 0; j
+= inc
)
2368 scm_putc (' ', port
);
2369 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2370 scm_print_real (z
, port
, pstate
);
2377 SCM cz
= scm_make_complex (0.0, 1.0), z
= scm_make_real (1.0 / 3.0);
2378 SCM_REAL_VALUE (z
) =
2379 SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2380 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2381 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2383 for (j
+= inc
; n
-- > 0; j
+= inc
)
2385 scm_putc (' ', port
);
2387 = SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2388 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2389 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2400 scm_raprin1 (SCM exp
, SCM port
, scm_print_state
*pstate
)
2404 scm_putc ('#', port
);
2410 long ndim
= SCM_ARRAY_NDIM (v
);
2411 base
= SCM_ARRAY_BASE (v
);
2412 v
= SCM_ARRAY_V (v
);
2416 scm_puts ("<enclosed-array ", port
);
2417 rapr1 (exp
, base
, 0, port
, pstate
);
2418 scm_putc ('>', port
);
2423 scm_intprint (ndim
, 10, port
);
2429 { /* a uve, not an scm_array */
2430 register long i
, j
, w
;
2431 scm_putc ('*', port
);
2432 for (i
= 0; i
< (SCM_LENGTH (exp
)) / SCM_LONG_BIT
; i
++)
2434 scm_bits_t w
= SCM_UNPACK (SCM_VELTS (exp
)[i
]);
2435 for (j
= SCM_LONG_BIT
; j
; j
--)
2437 scm_putc (w
& 1 ? '1' : '0', port
);
2441 j
= SCM_LENGTH (exp
) % SCM_LONG_BIT
;
2444 w
= SCM_UNPACK (SCM_VELTS (exp
)[SCM_LENGTH (exp
) / SCM_LONG_BIT
]);
2447 scm_putc (w
& 1 ? '1' : '0', port
);
2454 scm_putc ('b', port
);
2456 case scm_tc7_string
:
2457 scm_putc ('a', port
);
2459 case scm_tc7_byvect
:
2460 scm_putc ('y', port
);
2463 scm_putc ('u', port
);
2466 scm_putc ('e', port
);
2469 scm_putc ('h', port
);
2471 #ifdef HAVE_LONG_LONGS
2472 case scm_tc7_llvect
:
2473 scm_putc ('l', port
);
2477 scm_putc ('s', port
);
2480 scm_putc ('i', port
);
2483 scm_putc ('c', port
);
2486 scm_putc ('(', port
);
2487 rapr1 (exp
, base
, 0, port
, pstate
);
2488 scm_putc (')', port
);
2492 SCM_DEFINE (scm_array_prototype
, "array-prototype", 1, 0, 0,
2494 "Returns an object that would produce an array of the same type as\n"
2495 "@var{array}, if used as the @var{prototype} for\n"
2496 "@code{make-uniform-array}.")
2497 #define FUNC_NAME s_scm_array_prototype
2500 SCM_ASRTGO (SCM_NIMP (ra
), badarg
);
2506 badarg
:SCM_WTA (1,ra
);
2508 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
2510 return SCM_UNSPECIFIED
;
2511 ra
= SCM_ARRAY_V (ra
);
2513 case scm_tc7_vector
:
2518 case scm_tc7_string
:
2519 return SCM_MAKE_CHAR ('a');
2520 case scm_tc7_byvect
:
2521 return SCM_MAKE_CHAR ('\0');
2523 return SCM_MAKINUM (1L);
2525 return SCM_MAKINUM (-1L);
2527 return SCM_CDR (scm_intern ("s", 1));
2528 #ifdef HAVE_LONG_LONGS
2529 case scm_tc7_llvect
:
2530 return SCM_CDR (scm_intern ("l", 1));
2533 return scm_make_real (1.0);
2535 return scm_make_real (1.0 / 3.0);
2537 return scm_make_complex (0.0, 1.0);
2546 return SCM_ARRAY_V (ptr
);
2553 scm_must_free (SCM_CHARS (ptr
));
2554 return sizeof (scm_array
) + SCM_ARRAY_NDIM (ptr
) * sizeof (scm_array_dim
);
2560 scm_tc16_array
= scm_make_smob_type_mfpe ("array", 0,
2565 scm_add_feature ("array");