1 /* Copyright (C) 1995,1996,1997,1998 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 */
56 #include "scm_validate.h"
65 /* The set of uniform scm_vector types is:
67 * unsigned char string
74 * complex double cvect
81 /* return the size of an element in a uniform array or 0 if type not
84 scm_uniform_element_size (SCM obj
)
88 switch (SCM_TYP7 (obj
))
93 result
= sizeof (long);
97 result
= sizeof (char);
101 result
= sizeof (short);
104 #ifdef HAVE_LONG_LONGS
106 result
= sizeof (long_long
);
113 result
= sizeof (float);
118 result
= sizeof (double);
122 result
= 2 * sizeof (double);
145 SCM_SETCAR (z
, scm_tc_flo
);
155 scm_make_uve (long k
, SCM prot
)
159 if (SCM_BOOL_T
== prot
)
161 i
= sizeof (long) * ((k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
);
162 type
= scm_tc7_bvect
;
164 else if (SCM_ICHRP (prot
) && (prot
== SCM_MAKICHR ('\0')))
166 i
= sizeof (char) * k
;
167 type
= scm_tc7_byvect
;
169 else if (SCM_ICHRP (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
);
206 if (SCM_IMP (prot
) || !SCM_INEXP (prot
))
208 /* Huge non-unif vectors are NOT supported. */
209 /* no special scm_vector */
210 return scm_make_vector (SCM_MAKINUM (k
), SCM_UNDEFINED
);
213 else if (SCM_SINGP (prot
))
216 i
= sizeof (float) * k
;
217 type
= scm_tc7_fvect
;
220 else if (SCM_CPLXP (prot
))
222 i
= 2 * sizeof (double) * k
;
223 type
= scm_tc7_cvect
;
227 i
= sizeof (double) * k
;
228 type
= scm_tc7_dvect
;
234 SCM_SETCHARS (v
, (char *) scm_must_malloc (i
? i
: 1, "vector"));
235 SCM_SETLENGTH (v
, (k
< SCM_LENGTH_MAX
? k
: SCM_LENGTH_MAX
), type
);
240 SCM_DEFINE (scm_uniform_vector_length
, "uniform-vector-length", 1, 0, 0,
242 "Returns the number of elements in @var{uve}.")
243 #define FUNC_NAME s_scm_uniform_vector_length
245 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
250 badarg1
:SCM_WTA(1,v
);
262 #ifdef HAVE_LONG_LONGS
265 return SCM_MAKINUM (SCM_LENGTH (v
));
270 SCM_DEFINE (scm_array_p
, "array?", 1, 1, 0,
272 "Returns @code{#t} if the @var{obj} is an array, and @code{#f} if not.
274 The @var{prototype} argument is used with uniform arrays and is described
276 #define FUNC_NAME s_scm_array_p
280 nprot
= SCM_UNBNDP (prot
);
285 switch (SCM_TYP7 (v
))
297 return nprot
|| SCM_BOOL(SCM_BOOL_T
==prot
);
299 return nprot
|| SCM_BOOL(SCM_ICHRP(prot
) && (prot
!= SCM_MAKICHR('\0')));
301 return nprot
|| SCM_BOOL(prot
== SCM_MAKICHR('\0'));
303 return nprot
|| SCM_BOOL(SCM_INUMP(prot
) && SCM_INUM(prot
)>0);
305 return nprot
|| SCM_BOOL(SCM_INUMP(prot
) && SCM_INUM(prot
)<=0);
308 || (SCM_SYMBOLP (prot
)
309 && (1 == SCM_LENGTH (prot
))
310 && ('s' == SCM_CHARS (prot
)[0])));
311 #ifdef HAVE_LONG_LONGS
314 || (SCM_SYMBOLP (prot
)
315 && (1 == SCM_LENGTH (prot
))
316 && ('s' == SCM_CHARS (prot
)[0])));
321 return nprot
|| SCM_BOOL(SCM_SINGP(prot
));
324 return nprot
|| SCM_BOOL(SCM_REALP(prot
));
326 return nprot
|| SCM_BOOL(SCM_CPLXP(prot
));
330 return nprot
|| SCM_BOOL(SCM_NULLP(prot
));
338 SCM_DEFINE (scm_array_rank
, "array-rank", 1, 0, 0,
340 "Returns the number of dimensions of @var{obj}. If @var{obj} is not an
341 array, @code{0} is returned.")
342 #define FUNC_NAME s_scm_array_rank
346 switch (SCM_TYP7 (ra
))
359 #ifdef HAVE_LONG_LONGS
363 return SCM_MAKINUM (1L);
366 return SCM_MAKINUM (SCM_ARRAY_NDIM (ra
));
373 SCM_DEFINE (scm_array_dimensions
, "array-dimensions", 1, 0, 0,
375 "@code{Array-dimensions} is similar to @code{array-shape} but replaces
376 elements with a @code{0} minimum with one greater than the maximum. So:
378 (array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5)
380 #define FUNC_NAME s_scm_array_dimensions
387 switch (SCM_TYP7 (ra
))
402 #ifdef HAVE_LONG_LONGS
405 return scm_cons (SCM_MAKINUM (SCM_LENGTH (ra
)), SCM_EOL
);
407 if (!SCM_ARRAYP (ra
))
409 k
= SCM_ARRAY_NDIM (ra
);
410 s
= SCM_ARRAY_DIMS (ra
);
412 res
= scm_cons (s
[k
].lbnd
? scm_cons2 (SCM_MAKINUM (s
[k
].lbnd
), SCM_MAKINUM (s
[k
].ubnd
), SCM_EOL
) :
413 SCM_MAKINUM (1 + (s
[k
].ubnd
))
421 static char s_bad_ind
[] = "Bad scm_array index";
425 scm_aind (SCM ra
, SCM args
, const char *what
)
429 register scm_sizet pos
= SCM_ARRAY_BASE (ra
);
430 register scm_sizet k
= SCM_ARRAY_NDIM (ra
);
431 scm_array_dim
*s
= SCM_ARRAY_DIMS (ra
);
432 if (SCM_INUMP (args
))
434 SCM_ASSERT (1 == k
, scm_makfrom0str (what
), SCM_WNA
, NULL
);
435 return pos
+ (SCM_INUM (args
) - s
->lbnd
) * (s
->inc
);
437 while (k
&& SCM_NIMP (args
))
439 ind
= SCM_CAR (args
);
440 args
= SCM_CDR (args
);
441 SCM_ASSERT (SCM_INUMP (ind
), ind
, s_bad_ind
, what
);
443 SCM_ASSERT (j
>= (s
->lbnd
) && j
<= (s
->ubnd
), ind
, SCM_OUTOFRANGE
, what
);
444 pos
+= (j
- s
->lbnd
) * (s
->inc
);
448 SCM_ASSERT (0 == k
&& SCM_NULLP (args
), scm_makfrom0str (what
), SCM_WNA
,
456 scm_make_ra (int ndim
)
461 SCM_NEWSMOB(ra
, ((long) ndim
<< 17) + scm_tc16_array
,
462 scm_must_malloc ((long) (sizeof (scm_array
) + ndim
* sizeof (scm_array_dim
)),
464 SCM_ARRAY_V (ra
) = scm_nullvect
;
469 static char s_bad_spec
[] = "Bad scm_array dimension";
470 /* Increments will still need to be set. */
474 scm_shap2ra (SCM args
, const char *what
)
478 int ndim
= scm_ilength (args
);
479 SCM_ASSERT (0 <= ndim
, args
, s_bad_spec
, what
);
480 ra
= scm_make_ra (ndim
);
481 SCM_ARRAY_BASE (ra
) = 0;
482 s
= SCM_ARRAY_DIMS (ra
);
483 for (; SCM_NIMP (args
); s
++, args
= SCM_CDR (args
))
485 spec
= SCM_CAR (args
);
489 SCM_ASSERT (SCM_INUMP (spec
) && SCM_INUM (spec
) >= 0, spec
,
492 s
->ubnd
= SCM_INUM (spec
) - 1;
497 SCM_ASSERT (SCM_CONSP (spec
) && SCM_INUMP (SCM_CAR (spec
)), spec
,
499 s
->lbnd
= SCM_INUM (SCM_CAR (spec
));
501 SCM_ASSERT (SCM_CONSP (sp
)
502 && SCM_INUMP (SCM_CAR (sp
)) && SCM_NULLP (SCM_CDR (sp
)),
503 spec
, s_bad_spec
, what
);
504 s
->ubnd
= SCM_INUM (SCM_CAR (sp
));
511 SCM_DEFINE (scm_dimensions_to_uniform_array
, "dimensions->uniform-array", 2, 1, 0,
512 (SCM dims
, SCM prot
, SCM fill
),
513 "@deffnx primitive make-uniform-vector length prototype [fill]
514 Creates and returns a uniform array or vector of type corresponding to
515 @var{prototype} with dimensions @var{dims} or length @var{length}. If
516 @var{fill} is supplied, it's used to fill the array, otherwise
517 @var{prototype} is used.")
518 #define FUNC_NAME s_scm_dimensions_to_uniform_array
520 scm_sizet k
, vlen
= 1;
524 if (SCM_INUMP (dims
))
526 if (SCM_INUM (dims
) < SCM_LENGTH_MAX
)
528 SCM answer
= scm_make_uve (SCM_INUM (dims
), prot
);
530 if (!SCM_UNBNDP (fill
))
531 scm_array_fill_x (answer
, fill
);
532 else if (SCM_SYMBOLP (prot
))
533 scm_array_fill_x (answer
, SCM_MAKINUM (0));
535 scm_array_fill_x (answer
, prot
);
539 dims
= scm_cons (dims
, SCM_EOL
);
541 SCM_ASSERT (SCM_NULLP (dims
) || SCM_CONSP (dims
),
542 dims
, SCM_ARG1
, FUNC_NAME
);
543 ra
= scm_shap2ra (dims
, FUNC_NAME
);
544 SCM_SETOR_CAR (ra
, SCM_ARRAY_CONTIGUOUS
);
545 s
= SCM_ARRAY_DIMS (ra
);
546 k
= SCM_ARRAY_NDIM (ra
);
549 s
[k
].inc
= (rlen
> 0 ? rlen
: 0);
550 rlen
= (s
[k
].ubnd
- s
[k
].lbnd
+ 1) * s
[k
].inc
;
551 vlen
*= (s
[k
].ubnd
- s
[k
].lbnd
+ 1);
553 if (rlen
< SCM_LENGTH_MAX
)
554 SCM_ARRAY_V (ra
) = scm_make_uve ((rlen
> 0 ? rlen
: 0L), prot
);
558 switch (SCM_TYP7 (scm_make_uve (0L, prot
)))
570 bit
= sizeof (float) * SCM_CHAR_BIT
/ sizeof (char);
573 bit
= sizeof (double) * SCM_CHAR_BIT
/ sizeof (char);
576 bit
= 2 * sizeof (double) * SCM_CHAR_BIT
/ sizeof (char);
579 SCM_ARRAY_BASE (ra
) = (SCM_LONG_BIT
+ bit
- 1) / bit
;
580 rlen
+= SCM_ARRAY_BASE (ra
);
581 SCM_ARRAY_V (ra
) = scm_make_uve (rlen
, prot
);
582 *((long *) SCM_VELTS (SCM_ARRAY_V (ra
))) = rlen
;
584 if (!SCM_UNBNDP (fill
))
586 scm_array_fill_x (ra
, fill
);
588 else if (SCM_SYMBOLP (prot
))
589 scm_array_fill_x (ra
, SCM_MAKINUM (0));
591 scm_array_fill_x (ra
, prot
);
592 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
593 if (s
->ubnd
< s
->lbnd
|| (0 == s
->lbnd
&& 1 == s
->inc
))
594 return SCM_ARRAY_V (ra
);
601 scm_ra_set_contp (SCM ra
)
603 scm_sizet k
= SCM_ARRAY_NDIM (ra
);
606 long inc
= SCM_ARRAY_DIMS (ra
)[k
- 1].inc
;
609 if (inc
!= SCM_ARRAY_DIMS (ra
)[k
].inc
)
611 SCM_SETAND_CAR (ra
, ~SCM_ARRAY_CONTIGUOUS
);
614 inc
*= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
615 - SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
618 SCM_SETOR_CAR (ra
, SCM_ARRAY_CONTIGUOUS
);
622 SCM_DEFINE (scm_make_shared_array
, "make-shared-array", 2, 0, 1,
623 (SCM oldra
, SCM mapfunc
, SCM dims
),
624 "@code{make-shared-array} can be used to create shared subarrays of other
625 arrays. The @var{mapper} is a function that translates coordinates in
626 the new array into coordinates in the old array. A @var{mapper} must be
627 linear, and its range must stay within the bounds of the old array, but
628 it can be otherwise arbitrary. A simple example:
630 (define fred (make-array #f 8 8))
631 (define freds-diagonal
632 (make-shared-array fred (lambda (i) (list i i)) 8))
633 (array-set! freds-diagonal 'foo 3)
634 (array-ref fred 3 3) @result{} foo
636 (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))
637 (array-ref freds-center 0 0) @result{} foo
639 #define FUNC_NAME s_scm_make_shared_array
645 long old_min
, new_min
, old_max
, new_max
;
647 SCM_VALIDATE_ARRAY (1,oldra
);
648 SCM_VALIDATE_PROC (2,mapfunc
);
649 ra
= scm_shap2ra (dims
, FUNC_NAME
);
650 if (SCM_ARRAYP (oldra
))
652 SCM_ARRAY_V (ra
) = SCM_ARRAY_V (oldra
);
653 old_min
= old_max
= SCM_ARRAY_BASE (oldra
);
654 s
= SCM_ARRAY_DIMS (oldra
);
655 k
= SCM_ARRAY_NDIM (oldra
);
659 old_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
661 old_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
666 SCM_ARRAY_V (ra
) = oldra
;
668 old_max
= (long) SCM_LENGTH (oldra
) - 1;
671 s
= SCM_ARRAY_DIMS (ra
);
672 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
674 inds
= scm_cons (SCM_MAKINUM (s
[k
].lbnd
), inds
);
675 if (s
[k
].ubnd
< s
[k
].lbnd
)
677 if (1 == SCM_ARRAY_NDIM (ra
))
678 ra
= scm_make_uve (0L, scm_array_prototype (ra
));
680 SCM_ARRAY_V (ra
) = scm_make_uve (0L, scm_array_prototype (ra
));
684 imap
= scm_apply (mapfunc
, scm_reverse (inds
), SCM_EOL
);
685 if (SCM_ARRAYP (oldra
))
686 i
= (scm_sizet
) scm_aind (oldra
, imap
, FUNC_NAME
);
689 if (SCM_NINUMP (imap
))
692 SCM_ASSERT (1 == scm_ilength (imap
) && SCM_INUMP (SCM_CAR (imap
)),
693 imap
, s_bad_ind
, FUNC_NAME
);
694 imap
= SCM_CAR (imap
);
698 SCM_ARRAY_BASE (ra
) = new_min
= new_max
= i
;
700 k
= SCM_ARRAY_NDIM (ra
);
703 if (s
[k
].ubnd
> s
[k
].lbnd
)
705 SCM_SETCAR (indptr
, SCM_MAKINUM (SCM_INUM (SCM_CAR (indptr
)) + 1));
706 imap
= scm_apply (mapfunc
, scm_reverse (inds
), SCM_EOL
);
707 if (SCM_ARRAYP (oldra
))
709 s
[k
].inc
= scm_aind (oldra
, imap
, FUNC_NAME
) - i
;
712 if (SCM_NINUMP (imap
))
715 SCM_ASSERT (1 == scm_ilength (imap
) && SCM_INUMP (SCM_CAR (imap
)),
716 imap
, s_bad_ind
, FUNC_NAME
);
717 imap
= SCM_CAR (imap
);
719 s
[k
].inc
= (long) SCM_INUM (imap
) - i
;
723 new_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
725 new_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
728 s
[k
].inc
= new_max
- new_min
+ 1; /* contiguous by default */
729 indptr
= SCM_CDR (indptr
);
731 SCM_ASSERT (old_min
<= new_min
&& old_max
>= new_max
, SCM_UNDEFINED
,
732 "mapping out of range", FUNC_NAME
);
733 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
735 if (1 == s
->inc
&& 0 == s
->lbnd
736 && SCM_LENGTH (SCM_ARRAY_V (ra
)) == 1 + s
->ubnd
)
737 return SCM_ARRAY_V (ra
);
738 if (s
->ubnd
< s
->lbnd
)
739 return scm_make_uve (0L, scm_array_prototype (ra
));
741 scm_ra_set_contp (ra
);
747 /* args are RA . DIMS */
748 SCM_DEFINE (scm_transpose_array
, "transpose-array", 0, 0, 1,
750 "Returns an array sharing contents with @var{array}, but with dimensions
751 arranged in a different order. There must be one @var{dim} argument for
752 each dimension of @var{array}. @var{dim0}, @var{dim1}, @dots{} should
753 be integers between 0 and the rank of the array to be returned. Each
754 integer in that range must appear at least once in the argument list.
756 The values of @var{dim0}, @var{dim1}, @dots{} correspond to dimensions
757 in the array to be returned, their positions in the argument list to
758 dimensions of @var{array}. Several @var{dim}s may have the same value,
759 in which case the returned array will have smaller rank than
764 (transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))
765 (transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)
766 (transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}
767 #2((a 4) (b 5) (c 6))
769 #define FUNC_NAME s_scm_transpose_array
771 SCM ra
, res
, vargs
, *ve
= &vargs
;
772 scm_array_dim
*s
, *r
;
774 SCM_ASSERT (SCM_NNULLP (args
), scm_makfrom0str (FUNC_NAME
),
777 SCM_ASSERT (SCM_NIMP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
778 args
= SCM_CDR (args
);
779 switch (SCM_TYP7 (ra
))
782 badarg
:SCM_WTA (1,ra
);
792 #ifdef HAVE_LONG_LONGS
795 SCM_ASSERT (SCM_NIMP (args
) && SCM_NULLP (SCM_CDR (args
)),
796 scm_makfrom0str (FUNC_NAME
), SCM_WNA
, NULL
);
797 SCM_ASSERT (SCM_INUMP (SCM_CAR (args
)), SCM_CAR (args
), SCM_ARG2
,
799 SCM_ASSERT (SCM_INUM0
== SCM_CAR (args
), SCM_CAR (args
), SCM_OUTOFRANGE
,
803 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
804 vargs
= scm_vector (args
);
805 SCM_ASSERT (SCM_LENGTH (vargs
) == SCM_ARRAY_NDIM (ra
),
806 scm_makfrom0str (FUNC_NAME
), SCM_WNA
, NULL
);
807 ve
= SCM_VELTS (vargs
);
809 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
811 SCM_ASSERT (SCM_INUMP (ve
[k
]), ve
[k
], (SCM_ARG2
+ k
),
813 i
= SCM_INUM (ve
[k
]);
814 SCM_ASSERT (i
>= 0 && i
< SCM_ARRAY_NDIM (ra
), ve
[k
],
815 SCM_OUTOFRANGE
, FUNC_NAME
);
820 res
= scm_make_ra (ndim
);
821 SCM_ARRAY_V (res
) = SCM_ARRAY_V (ra
);
822 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra
);
825 SCM_ARRAY_DIMS (res
)[k
].lbnd
= 0;
826 SCM_ARRAY_DIMS (res
)[k
].ubnd
= -1;
828 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
830 i
= SCM_INUM (ve
[k
]);
831 s
= &(SCM_ARRAY_DIMS (ra
)[k
]);
832 r
= &(SCM_ARRAY_DIMS (res
)[i
]);
833 if (r
->ubnd
< r
->lbnd
)
842 if (r
->ubnd
> s
->ubnd
)
844 if (r
->lbnd
< s
->lbnd
)
846 SCM_ARRAY_BASE (res
) += (s
->lbnd
- r
->lbnd
) * r
->inc
;
852 SCM_ASSERT (ndim
<= 0, args
, "bad argument list", FUNC_NAME
);
853 scm_ra_set_contp (res
);
859 /* args are RA . AXES */
860 SCM_DEFINE (scm_enclose_array
, "enclose-array", 0, 0, 1,
862 "@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than
863 the rank of @var{array}. @var{enclose-array} returns an array
864 resembling an array of shared arrays. The dimensions of each shared
865 array are the same as the @var{dim}th dimensions of the original array,
866 the dimensions of the outer array are the same as those of the original
867 array that did not match a @var{dim}.
869 An enclosed array is not a general Scheme array. Its elements may not
870 be set using @code{array-set!}. Two references to the same element of
871 an enclosed array will be @code{equal?} but will not in general be
872 @code{eq?}. The value returned by @var{array-prototype} when given an
873 enclosed array is unspecified.
877 (enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) @result{}
878 #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>
880 (enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{}
881 #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>
883 #define FUNC_NAME s_scm_enclose_array
885 SCM axv
, ra
, res
, ra_inr
;
886 scm_array_dim vdim
, *s
= &vdim
;
887 int ndim
, j
, k
, ninr
, noutr
;
888 SCM_ASSERT (SCM_NIMP (axes
), scm_makfrom0str (FUNC_NAME
), SCM_WNA
,
891 axes
= SCM_CDR (axes
);
892 if (SCM_NULLP (axes
))
893 axes
= scm_cons ((SCM_ARRAYP (ra
) ? SCM_MAKINUM (SCM_ARRAY_NDIM (ra
) - 1) : SCM_INUM0
), SCM_EOL
);
894 ninr
= scm_ilength (axes
);
895 ra_inr
= scm_make_ra (ninr
);
896 SCM_ASRTGO (SCM_NIMP (ra
), badarg1
);
901 badarg1
:SCM_WTA (1,ra
);
913 #ifdef HAVE_LONG_LONGS
917 s
->ubnd
= SCM_LENGTH (ra
) - 1;
919 SCM_ARRAY_V (ra_inr
) = ra
;
920 SCM_ARRAY_BASE (ra_inr
) = 0;
924 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg1
);
925 s
= SCM_ARRAY_DIMS (ra
);
926 SCM_ARRAY_V (ra_inr
) = SCM_ARRAY_V (ra
);
927 SCM_ARRAY_BASE (ra_inr
) = SCM_ARRAY_BASE (ra
);
928 ndim
= SCM_ARRAY_NDIM (ra
);
932 axv
= scm_make_string (SCM_MAKINUM (ndim
), SCM_MAKICHR (0));
933 SCM_ASSERT (0 <= noutr
&& 0 <= ninr
, scm_makfrom0str (FUNC_NAME
),
935 res
= scm_make_ra (noutr
);
936 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra_inr
);
937 SCM_ARRAY_V (res
) = ra_inr
;
938 for (k
= 0; k
< ninr
; k
++, axes
= SCM_CDR (axes
))
940 SCM_ASSERT (SCM_INUMP (SCM_CAR (axes
)), SCM_CAR (axes
), "bad axis", FUNC_NAME
);
941 j
= SCM_INUM (SCM_CAR (axes
));
942 SCM_ARRAY_DIMS (ra_inr
)[k
].lbnd
= s
[j
].lbnd
;
943 SCM_ARRAY_DIMS (ra_inr
)[k
].ubnd
= s
[j
].ubnd
;
944 SCM_ARRAY_DIMS (ra_inr
)[k
].inc
= s
[j
].inc
;
945 SCM_CHARS (axv
)[j
] = 1;
947 for (j
= 0, k
= 0; k
< noutr
; k
++, j
++)
949 while (SCM_CHARS (axv
)[j
])
951 SCM_ARRAY_DIMS (res
)[k
].lbnd
= s
[j
].lbnd
;
952 SCM_ARRAY_DIMS (res
)[k
].ubnd
= s
[j
].ubnd
;
953 SCM_ARRAY_DIMS (res
)[k
].inc
= s
[j
].inc
;
955 scm_ra_set_contp (ra_inr
);
956 scm_ra_set_contp (res
);
963 SCM_DEFINE (scm_array_in_bounds_p
, "array-in-bounds?", 0, 0, 1,
965 "Returns @code{#t} if its arguments would be acceptable to array-ref.")
966 #define FUNC_NAME s_scm_array_in_bounds_p
968 SCM v
, ind
= SCM_EOL
;
970 register scm_sizet k
;
973 SCM_ASSERT (SCM_NIMP (args
), scm_makfrom0str (FUNC_NAME
),
976 args
= SCM_CDR (args
);
977 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
981 ind
= SCM_CAR (args
);
982 args
= SCM_CDR (args
);
983 SCM_ASSERT (SCM_INUMP (ind
), ind
, SCM_ARG2
, FUNC_NAME
);
984 pos
= SCM_INUM (ind
);
991 badarg1
:SCM_WTA (1,v
);
992 wna
: scm_wrong_num_args (scm_makfrom0str (FUNC_NAME
));
994 k
= SCM_ARRAY_NDIM (v
);
995 s
= SCM_ARRAY_DIMS (v
);
996 pos
= SCM_ARRAY_BASE (v
);
999 SCM_ASRTGO (SCM_NULLP (ind
), wna
);
1006 if (!(j
>= (s
->lbnd
) && j
<= (s
->ubnd
)))
1008 SCM_ASRTGO (--k
== scm_ilength (args
), wna
);
1011 pos
+= (j
- s
->lbnd
) * (s
->inc
);
1012 if (!(--k
&& SCM_NIMP (args
)))
1014 ind
= SCM_CAR (args
);
1015 args
= SCM_CDR (args
);
1017 SCM_ASSERT (SCM_INUMP (ind
), ind
, s_bad_ind
, FUNC_NAME
);
1019 SCM_ASRTGO (0 == k
, wna
);
1020 v
= SCM_ARRAY_V (v
);
1023 case scm_tc7_string
:
1024 case scm_tc7_byvect
:
1031 #ifdef HAVE_LONG_LONGS
1032 case scm_tc7_llvect
:
1034 case scm_tc7_vector
:
1036 SCM_ASRTGO (SCM_NULLP (args
) && SCM_INUMP (ind
), wna
);
1037 return SCM_BOOL(pos
>= 0 && pos
< SCM_LENGTH (v
));
1043 SCM_REGISTER_PROC(s_array_ref
, "array-ref", 1, 0, 1, scm_uniform_vector_ref
);
1046 SCM_DEFINE (scm_uniform_vector_ref
, "uniform-vector-ref", 2, 0, 0,
1048 "Returns the element at the @code{(index1, index2)} element in @var{array}.")
1049 #define FUNC_NAME s_scm_uniform_vector_ref
1055 SCM_ASRTGO (SCM_NULLP (args
), badarg
);
1058 else if (SCM_ARRAYP (v
))
1060 pos
= scm_aind (v
, args
, FUNC_NAME
);
1061 v
= SCM_ARRAY_V (v
);
1065 if (SCM_NIMP (args
))
1068 SCM_ASSERT (SCM_CONSP (args
) && SCM_INUMP (SCM_CAR (args
)), args
, SCM_ARG2
, FUNC_NAME
);
1069 pos
= SCM_INUM (SCM_CAR (args
));
1070 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1074 SCM_VALIDATE_INUM (2,args
);
1075 pos
= SCM_INUM (args
);
1077 SCM_ASRTGO (pos
>= 0 && pos
< SCM_LENGTH (v
), outrng
);
1083 if (SCM_NULLP (args
))
1088 outrng
:scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (pos
));
1089 wna
: scm_wrong_num_args (SCM_FUNC_NAME
);
1092 int k
= SCM_ARRAY_NDIM (v
);
1093 SCM res
= scm_make_ra (k
);
1094 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1095 SCM_ARRAY_BASE (res
) = pos
;
1098 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1099 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1100 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1105 if (SCM_VELTS (v
)[pos
/ SCM_LONG_BIT
] & (1L << (pos
% SCM_LONG_BIT
)))
1109 case scm_tc7_string
:
1110 return SCM_MAKICHR (SCM_UCHARS (v
)[pos
]);
1111 case scm_tc7_byvect
:
1112 return SCM_MAKINUM (((char *)SCM_CHARS (v
))[pos
]);
1113 # ifdef SCM_INUMS_ONLY
1116 return SCM_MAKINUM (SCM_VELTS (v
)[pos
]);
1119 return scm_ulong2num(SCM_VELTS(v
)[pos
]);
1121 return scm_long2num(SCM_VELTS(v
)[pos
]);
1125 return SCM_MAKINUM (((short *) SCM_CDR (v
))[pos
]);
1126 #ifdef HAVE_LONG_LONGS
1127 case scm_tc7_llvect
:
1128 return scm_long_long2num (((long_long
*) SCM_CDR (v
))[pos
]);
1134 return scm_makflo (((float *) SCM_CDR (v
))[pos
]);
1137 return scm_makdbl (((double *) SCM_CDR (v
))[pos
], 0.0);
1139 return scm_makdbl (((double *) SCM_CDR (v
))[2 * pos
],
1140 ((double *) SCM_CDR (v
))[2 * pos
+ 1]);
1142 case scm_tc7_vector
:
1144 return SCM_VELTS (v
)[pos
];
1149 /* Internal version of scm_uniform_vector_ref for uves that does no error checking and
1150 tries to recycle conses. (Make *sure* you want them recycled.) */
1153 scm_cvref (SCM v
, scm_sizet pos
, SCM last
)
1158 scm_wta (v
, (char *) SCM_ARG1
, "PROGRAMMING ERROR: scm_cvref");
1160 if (SCM_VELTS (v
)[pos
/ SCM_LONG_BIT
] & (1L << (pos
% SCM_LONG_BIT
)))
1164 case scm_tc7_string
:
1165 return SCM_MAKICHR (SCM_UCHARS (v
)[pos
]);
1166 case scm_tc7_byvect
:
1167 return SCM_MAKINUM (((char *)SCM_CHARS (v
))[pos
]);
1168 # ifdef SCM_INUMS_ONLY
1171 return SCM_MAKINUM (SCM_VELTS (v
)[pos
]);
1174 return scm_ulong2num(SCM_VELTS(v
)[pos
]);
1176 return scm_long2num(SCM_VELTS(v
)[pos
]);
1179 return SCM_MAKINUM (((short *) SCM_CDR (v
))[pos
]);
1180 #ifdef HAVE_LONG_LONGS
1181 case scm_tc7_llvect
:
1182 return scm_long_long2num (((long_long
*) SCM_CDR (v
))[pos
]);
1187 if (SCM_NIMP (last
) && (last
!= scm_flo0
) && (scm_tc_flo
== SCM_CAR (last
)))
1189 SCM_FLO (last
) = ((float *) SCM_CDR (v
))[pos
];
1192 return scm_makflo (((float *) SCM_CDR (v
))[pos
]);
1196 if (SCM_NIMP (last
) && scm_tc_dblr
== SCM_CAR (last
))
1198 if (SCM_NIMP (last
) && (last
!= scm_flo0
) && (scm_tc_dblr
== SCM_CAR (last
)))
1201 SCM_REAL (last
) = ((double *) SCM_CDR (v
))[pos
];
1204 return scm_makdbl (((double *) SCM_CDR (v
))[pos
], 0.0);
1206 if (SCM_NIMP (last
) && scm_tc_dblc
== SCM_CAR (last
))
1208 SCM_REAL (last
) = ((double *) SCM_CDR (v
))[2 * pos
];
1209 SCM_IMAG (last
) = ((double *) SCM_CDR (v
))[2 * pos
+ 1];
1212 return scm_makdbl (((double *) SCM_CDR (v
))[2 * pos
],
1213 ((double *) SCM_CDR (v
))[2 * pos
+ 1]);
1215 case scm_tc7_vector
:
1217 return SCM_VELTS (v
)[pos
];
1219 { /* enclosed scm_array */
1220 int k
= SCM_ARRAY_NDIM (v
);
1221 SCM res
= scm_make_ra (k
);
1222 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1223 SCM_ARRAY_BASE (res
) = pos
;
1226 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1227 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1228 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1235 SCM_REGISTER_PROC(s_uniform_array_set1_x
, "uniform-array-set1!", 3, 0, 0, scm_array_set_x
);
1238 /* Note that args may be a list or an immediate object, depending which
1239 PROC is used (and it's called from C too). */
1240 SCM_DEFINE (scm_array_set_x
, "array-set!", 2, 0, 1,
1241 (SCM v
, SCM obj
, SCM args
),
1242 "Sets the element at the @code{(index1, index2)} element in @var{array} to
1243 @var{new-value}. The value returned by array-set! is unspecified.")
1244 #define FUNC_NAME s_scm_array_set_x
1247 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1250 pos
= scm_aind (v
, args
, FUNC_NAME
);
1251 v
= SCM_ARRAY_V (v
);
1255 if (SCM_NIMP (args
))
1257 SCM_ASSERT (SCM_CONSP(args
) && SCM_INUMP (SCM_CAR (args
)), args
,
1258 SCM_ARG3
, FUNC_NAME
);
1259 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1260 pos
= SCM_INUM (SCM_CAR (args
));
1264 SCM_VALIDATE_INUM_COPY (3,args
,pos
);
1266 SCM_ASRTGO (pos
>= 0 && pos
< SCM_LENGTH (v
), outrng
);
1268 switch (SCM_TYP7 (v
))
1273 outrng
:scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (pos
));
1274 wna
: scm_wrong_num_args (SCM_FUNC_NAME
);
1275 case scm_tc7_smob
: /* enclosed */
1278 if (SCM_BOOL_F
== obj
)
1279 SCM_VELTS (v
)[pos
/ SCM_LONG_BIT
] &= ~(1L << (pos
% SCM_LONG_BIT
));
1280 else if (SCM_BOOL_T
== obj
)
1281 SCM_VELTS (v
)[pos
/ SCM_LONG_BIT
] |= (1L << (pos
% SCM_LONG_BIT
));
1283 badobj
:SCM_WTA (2,obj
);
1285 case scm_tc7_string
:
1286 SCM_ASRTGO (SCM_ICHRP (obj
), badobj
);
1287 SCM_UCHARS (v
)[pos
] = SCM_ICHR (obj
);
1289 case scm_tc7_byvect
:
1290 if (SCM_ICHRP (obj
))
1291 obj
= SCM_MAKINUM ((char) SCM_ICHR (obj
));
1292 SCM_ASRTGO (SCM_INUMP (obj
), badobj
);
1293 ((char *)SCM_CHARS (v
))[pos
] = SCM_INUM (obj
);
1295 # ifdef SCM_INUMS_ONLY
1297 SCM_ASRTGO (SCM_INUM (obj
) >= 0, badobj
);
1300 SCM_ASRTGO(SCM_INUMP(obj
), badobj
); SCM_VELTS(v
)[pos
] = SCM_INUM(obj
); break;
1303 SCM_VELTS(v
)[pos
] = scm_num2ulong(obj
, (char *)SCM_ARG2
, FUNC_NAME
); break;
1305 SCM_VELTS(v
)[pos
] = scm_num2long(obj
, (char *)SCM_ARG2
, FUNC_NAME
); break;
1308 SCM_ASRTGO (SCM_INUMP (obj
), badobj
);
1309 ((short *) SCM_CDR (v
))[pos
] = SCM_INUM (obj
);
1311 #ifdef HAVE_LONG_LONGS
1312 case scm_tc7_llvect
:
1313 ((long_long
*) SCM_CDR (v
))[pos
] = scm_num2long_long (obj
, (char *)SCM_ARG2
, FUNC_NAME
);
1321 ((float *) SCM_CDR (v
))[pos
] = (float)scm_num2dbl(obj
, FUNC_NAME
); break;
1325 ((double *) SCM_CDR (v
))[pos
] = scm_num2dbl(obj
, FUNC_NAME
); break;
1328 SCM_ASRTGO (SCM_INEXP (obj
), badobj
);
1329 ((double *) SCM_CDR (v
))[2 * pos
] = SCM_REALPART (obj
);
1330 ((double *) SCM_CDR (v
))[2 * pos
+ 1] = SCM_CPLXP (obj
) ? SCM_IMAG (obj
) : 0.0;
1333 case scm_tc7_vector
:
1335 SCM_VELTS (v
)[pos
] = obj
;
1338 return SCM_UNSPECIFIED
;
1342 /* attempts to unroll an array into a one-dimensional array.
1343 returns the unrolled array or #f if it can't be done. */
1344 /* if strict is not SCM_UNDEFINED, return #f if returned array
1345 wouldn't have contiguous elements. */
1346 SCM_DEFINE (scm_array_contents
, "array-contents", 1, 1, 0,
1347 (SCM ra
, SCM strict
),
1348 "@deffnx primitive array-contents array strict
1349 If @var{array} may be @dfn{unrolled} into a one dimensional shared array
1350 without changing their order (last subscript changing fastest), then
1351 @code{array-contents} returns that shared array, otherwise it returns
1352 @code{#f}. All arrays made by @var{make-array} and
1353 @var{make-uniform-array} may be unrolled, some arrays made by
1354 @var{make-shared-array} may not be.
1356 If the optional argument @var{strict} is provided, a shared array will
1357 be returned only if its elements are stored internally contiguous in
1359 #define FUNC_NAME s_scm_array_contents
1364 switch SCM_TYP7 (ra
)
1368 case scm_tc7_vector
:
1370 case scm_tc7_string
:
1372 case scm_tc7_byvect
:
1379 #ifdef HAVE_LONG_LONGS
1380 case scm_tc7_llvect
:
1385 scm_sizet k
, ndim
= SCM_ARRAY_NDIM (ra
), len
= 1;
1386 if (!SCM_ARRAYP (ra
) || !SCM_ARRAY_CONTP (ra
))
1388 for (k
= 0; k
< ndim
; k
++)
1389 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1390 if (!SCM_UNBNDP (strict
))
1392 if (ndim
&& (1 != SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
))
1394 if (scm_tc7_bvect
== SCM_TYP7 (SCM_ARRAY_V (ra
)))
1396 if (len
!= SCM_LENGTH (SCM_ARRAY_V (ra
)) ||
1397 SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
||
1402 if ((len
== SCM_LENGTH (SCM_ARRAY_V (ra
))) && 0 == SCM_ARRAY_BASE (ra
) && SCM_ARRAY_DIMS (ra
)->inc
)
1403 return SCM_ARRAY_V (ra
);
1404 sra
= scm_make_ra (1);
1405 SCM_ARRAY_DIMS (sra
)->lbnd
= 0;
1406 SCM_ARRAY_DIMS (sra
)->ubnd
= len
- 1;
1407 SCM_ARRAY_V (sra
) = SCM_ARRAY_V (ra
);
1408 SCM_ARRAY_BASE (sra
) = SCM_ARRAY_BASE (ra
);
1409 SCM_ARRAY_DIMS (sra
)->inc
= (ndim
? SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
: 1);
1418 scm_ra2contig (SCM ra
, int copy
)
1422 scm_sizet k
, len
= 1;
1423 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
1424 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1425 k
= SCM_ARRAY_NDIM (ra
);
1426 if (SCM_ARRAY_CONTP (ra
) && ((0 == k
) || (1 == SCM_ARRAY_DIMS (ra
)[k
- 1].inc
)))
1428 if (scm_tc7_bvect
!= SCM_TYP7 (ra
))
1430 if ((len
== SCM_LENGTH (SCM_ARRAY_V (ra
)) &&
1431 0 == SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
&&
1432 0 == len
% SCM_LONG_BIT
))
1435 ret
= scm_make_ra (k
);
1436 SCM_ARRAY_BASE (ret
) = 0;
1439 SCM_ARRAY_DIMS (ret
)[k
].lbnd
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
;
1440 SCM_ARRAY_DIMS (ret
)[k
].ubnd
= SCM_ARRAY_DIMS (ra
)[k
].ubnd
;
1441 SCM_ARRAY_DIMS (ret
)[k
].inc
= inc
;
1442 inc
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1444 SCM_ARRAY_V (ret
) = scm_make_uve ((inc
- 1), scm_array_prototype (ra
));
1446 scm_array_copy_x (ra
, ret
);
1452 SCM_DEFINE (scm_uniform_array_read_x
, "uniform-array-read!", 1, 3, 0,
1453 (SCM ra
, SCM port_or_fd
, SCM start
, SCM end
),
1454 "@deffnx primitive uniform-vector-read! uve [port-or-fdes] [start] [end]
1455 Attempts to read all elements of @var{ura}, in lexicographic order, as
1456 binary objects from @var{port-or-fdes}.
1457 If an end of file is encountered during
1458 uniform-array-read! the objects up to that point only are put into @var{ura}
1459 (starting at the beginning) and the remainder of the array is
1462 The optional arguments @var{start} and @var{end} allow
1463 a specified region of a vector (or linearized array) to be read,
1464 leaving the remainder of the vector unchanged.
1466 @code{uniform-array-read!} returns the number of objects read.
1467 @var{port-or-fdes} may be omitted, in which case it defaults to the value
1468 returned by @code{(current-input-port)}.")
1469 #define FUNC_NAME s_scm_uniform_array_read_x
1471 SCM cra
= SCM_UNDEFINED
, v
= ra
;
1477 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1478 if (SCM_UNBNDP (port_or_fd
))
1479 port_or_fd
= scm_cur_inp
;
1481 SCM_ASSERT (SCM_INUMP (port_or_fd
)
1482 || (SCM_OPINPORTP (port_or_fd
)),
1483 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1484 vlen
= SCM_LENGTH (v
);
1490 badarg1
:scm_wta (v
, (char *) SCM_ARG1
, FUNC_NAME
);
1492 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1493 cra
= scm_ra2contig (ra
, 0);
1494 cstart
+= SCM_ARRAY_BASE (cra
);
1495 vlen
= SCM_ARRAY_DIMS (cra
)->inc
*
1496 (SCM_ARRAY_DIMS (cra
)->ubnd
- SCM_ARRAY_DIMS (cra
)->lbnd
+ 1);
1497 v
= SCM_ARRAY_V (cra
);
1499 case scm_tc7_string
:
1500 case scm_tc7_byvect
:
1504 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1505 cstart
/= SCM_LONG_BIT
;
1511 sz
= sizeof (short);
1513 #ifdef HAVE_LONG_LONGS
1514 case scm_tc7_llvect
:
1515 sz
= sizeof (long_long
);
1521 sz
= sizeof (float);
1525 sz
= sizeof (double);
1528 sz
= 2 * sizeof (double);
1534 if (!SCM_UNBNDP (start
))
1537 SCM_NUM2LONG (3, start
);
1539 if (offset
< 0 || offset
>= cend
)
1540 scm_out_of_range (FUNC_NAME
, start
);
1542 if (!SCM_UNBNDP (end
))
1545 SCM_NUM2LONG (4, end
);
1547 if (tend
<= offset
|| tend
> cend
)
1548 scm_out_of_range (FUNC_NAME
, end
);
1553 if (SCM_NIMP (port_or_fd
))
1555 scm_port
*pt
= SCM_PTAB_ENTRY (port_or_fd
);
1556 int remaining
= (cend
- offset
) * sz
;
1557 char *dest
= SCM_CHARS (v
) + (cstart
+ offset
) * sz
;
1559 if (pt
->rw_active
== SCM_PORT_WRITE
)
1560 scm_flush (port_or_fd
);
1562 ans
= cend
- offset
;
1563 while (remaining
> 0)
1565 if (pt
->read_pos
< pt
->read_end
)
1567 int to_copy
= min (pt
->read_end
- pt
->read_pos
,
1570 memcpy (dest
, pt
->read_pos
, to_copy
);
1571 pt
->read_pos
+= to_copy
;
1572 remaining
-= to_copy
;
1577 if (scm_fill_input (port_or_fd
) == EOF
)
1579 if (remaining
% sz
!= 0)
1581 scm_misc_error (FUNC_NAME
,
1585 ans
-= remaining
/ sz
;
1592 pt
->rw_active
= SCM_PORT_READ
;
1594 else /* file descriptor. */
1596 SCM_SYSCALL (ans
= read (SCM_INUM (port_or_fd
),
1597 SCM_CHARS (v
) + (cstart
+ offset
) * sz
,
1598 (scm_sizet
) (sz
* (cend
- offset
))));
1602 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1603 ans
*= SCM_LONG_BIT
;
1605 if (v
!= ra
&& cra
!= ra
)
1606 scm_array_copy_x (cra
, ra
);
1608 return SCM_MAKINUM (ans
);
1612 SCM_DEFINE (scm_uniform_array_write
, "uniform-array-write", 1, 3, 0,
1613 (SCM v
, SCM port_or_fd
, SCM start
, SCM end
),
1614 "@deffnx primitive uniform-vector-write uve [port-or-fdes] [start] [end]
1615 Writes all elements of @var{ura} as binary objects to
1618 The optional arguments @var{start}
1620 a specified region of a vector (or linearized array) to be written.
1622 The number of objects actually written is returned.
1623 @var{port-or-fdes} may be
1624 omitted, in which case it defaults to the value returned by
1625 @code{(current-output-port)}.")
1626 #define FUNC_NAME s_scm_uniform_array_write
1633 port_or_fd
= SCM_COERCE_OUTPORT (port_or_fd
);
1635 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1636 if (SCM_UNBNDP (port_or_fd
))
1637 port_or_fd
= scm_cur_outp
;
1639 SCM_ASSERT (SCM_INUMP (port_or_fd
)
1640 || (SCM_OPOUTPORTP (port_or_fd
)),
1641 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1642 vlen
= SCM_LENGTH (v
);
1648 badarg1
:SCM_WTA (1, v
);
1650 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1651 v
= scm_ra2contig (v
, 1);
1652 cstart
= SCM_ARRAY_BASE (v
);
1653 vlen
= SCM_ARRAY_DIMS (v
)->inc
1654 * (SCM_ARRAY_DIMS (v
)->ubnd
- SCM_ARRAY_DIMS (v
)->lbnd
+ 1);
1655 v
= SCM_ARRAY_V (v
);
1657 case scm_tc7_string
:
1658 case scm_tc7_byvect
:
1662 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1663 cstart
/= SCM_LONG_BIT
;
1669 sz
= sizeof (short);
1671 #ifdef HAVE_LONG_LONGS
1672 case scm_tc7_llvect
:
1673 sz
= sizeof (long_long
);
1679 sz
= sizeof (float);
1683 sz
= sizeof (double);
1686 sz
= 2 * sizeof (double);
1692 if (!SCM_UNBNDP (start
))
1695 SCM_NUM2LONG (3, start
);
1697 if (offset
< 0 || offset
>= cend
)
1698 scm_out_of_range (FUNC_NAME
, start
);
1700 if (!SCM_UNBNDP (end
))
1703 SCM_NUM2LONG (4, end
);
1705 if (tend
<= offset
|| tend
> cend
)
1706 scm_out_of_range (FUNC_NAME
, end
);
1711 if (SCM_NIMP (port_or_fd
))
1713 char *source
= SCM_CHARS (v
) + (cstart
+ offset
) * sz
;
1715 ans
= cend
- offset
;
1716 scm_lfwrite (source
, ans
* sz
, port_or_fd
);
1718 else /* file descriptor. */
1720 SCM_SYSCALL (ans
= write (SCM_INUM (port_or_fd
),
1721 SCM_CHARS (v
) + (cstart
+ offset
) * sz
,
1722 (scm_sizet
) (sz
* (cend
- offset
))));
1726 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1727 ans
*= SCM_LONG_BIT
;
1729 return SCM_MAKINUM (ans
);
1734 static char cnt_tab
[16] =
1735 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1737 SCM_DEFINE (scm_bit_count
, "bit-count", 2, 0, 0,
1738 (SCM item
, SCM seq
),
1739 "Returns the number occurrences of @var{bool} in @var{bv}.")
1740 #define FUNC_NAME s_scm_bit_count
1743 register unsigned long cnt
= 0, w
;
1744 SCM_VALIDATE_INUM (2,seq
);
1745 switch SCM_TYP7 (seq
)
1750 if (0 == SCM_LENGTH (seq
))
1752 i
= (SCM_LENGTH (seq
) - 1) / SCM_LONG_BIT
;
1753 w
= SCM_VELTS (seq
)[i
];
1754 if (SCM_FALSEP (item
))
1756 w
<<= SCM_LONG_BIT
- 1 - ((SCM_LENGTH (seq
) - 1) % SCM_LONG_BIT
);
1760 cnt
+= cnt_tab
[w
& 0x0f];
1762 return SCM_MAKINUM (cnt
);
1763 w
= SCM_VELTS (seq
)[i
];
1764 if (SCM_FALSEP (item
))
1772 SCM_DEFINE (scm_bit_position
, "bit-position", 3, 0, 0,
1773 (SCM item
, SCM v
, SCM k
),
1774 "Returns the minimum index of an occurrence of @var{bool} in @var{bv}
1775 which is at least @var{k}. If no @var{bool} occurs within the specified
1776 range @code{#f} is returned.")
1777 #define FUNC_NAME s_scm_bit_position
1779 long i
, lenw
, xbits
, pos
;
1780 register unsigned long w
;
1781 SCM_VALIDATE_NIM (2,v
);
1782 SCM_VALIDATE_INUM_COPY (3,k
,pos
);
1783 SCM_ASSERT ((pos
<= SCM_LENGTH (v
)) && (pos
>= 0),
1784 k
, SCM_OUTOFRANGE
, FUNC_NAME
);
1785 if (pos
== SCM_LENGTH (v
))
1792 if (0 == SCM_LENGTH (v
))
1793 return SCM_MAKINUM (-1L);
1794 lenw
= (SCM_LENGTH (v
) - 1) / SCM_LONG_BIT
; /* watch for part words */
1795 i
= pos
/ SCM_LONG_BIT
;
1796 w
= SCM_VELTS (v
)[i
];
1797 if (SCM_FALSEP (item
))
1799 xbits
= (pos
% SCM_LONG_BIT
);
1801 w
= ((w
>> xbits
) << xbits
);
1802 xbits
= SCM_LONG_BIT
- 1 - (SCM_LENGTH (v
) - 1) % SCM_LONG_BIT
;
1805 if (w
&& (i
== lenw
))
1806 w
= ((w
<< xbits
) >> xbits
);
1812 return SCM_MAKINUM (pos
);
1817 return SCM_MAKINUM (pos
+ 1);
1820 return SCM_MAKINUM (pos
+ 2);
1822 return SCM_MAKINUM (pos
+ 3);
1829 pos
+= SCM_LONG_BIT
;
1830 w
= SCM_VELTS (v
)[i
];
1831 if (SCM_FALSEP (item
))
1840 SCM_DEFINE (scm_bit_set_star_x
, "bit-set*!", 3, 0, 0,
1841 (SCM v
, SCM kv
, SCM obj
),
1842 "If uve is a bit-vector @var{bv} and uve must be of the same length. If
1843 @var{bool} is @code{#t}, uve is OR'ed into @var{bv}; If @var{bool} is @code{#f}, the
1844 inversion of uve is AND'ed into @var{bv}.
1846 If uve is a unsigned integer vector all the elements of uve must be
1847 between 0 and the @code{LENGTH} of @var{bv}. The bits of @var{bv}
1848 corresponding to the indexes in uve are set to @var{bool}.
1850 The return value is unspecified.")
1851 #define FUNC_NAME s_scm_bit_set_star_x
1853 register long i
, k
, vlen
;
1854 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1855 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1856 switch SCM_TYP7 (kv
)
1859 badarg2
:SCM_WTA (2,kv
);
1864 badarg1
:SCM_WTA (1,v
);
1866 vlen
= SCM_LENGTH (v
);
1867 if (SCM_BOOL_F
== obj
)
1868 for (i
= SCM_LENGTH (kv
); i
;)
1870 k
= SCM_VELTS (kv
)[--i
];
1871 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1872 SCM_VELTS (v
)[k
/ SCM_LONG_BIT
] &= ~(1L << (k
% SCM_LONG_BIT
));
1874 else if (SCM_BOOL_T
== obj
)
1875 for (i
= SCM_LENGTH (kv
); i
;)
1877 k
= SCM_VELTS (kv
)[--i
];
1878 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1879 SCM_VELTS (v
)[k
/ SCM_LONG_BIT
] |= (1L << (k
% SCM_LONG_BIT
));
1882 badarg3
:SCM_WTA (3,obj
);
1886 SCM_ASRTGO (SCM_TYP7 (v
) == scm_tc7_bvect
&& SCM_LENGTH (v
) == SCM_LENGTH (kv
), badarg1
);
1887 if (SCM_BOOL_F
== obj
)
1888 for (k
= (SCM_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1889 SCM_VELTS (v
)[k
] &= ~(SCM_VELTS (kv
)[k
]);
1890 else if (SCM_BOOL_T
== obj
)
1891 for (k
= (SCM_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1892 SCM_VELTS (v
)[k
] |= SCM_VELTS (kv
)[k
];
1897 return SCM_UNSPECIFIED
;
1902 SCM_DEFINE (scm_bit_count_star
, "bit-count*", 3, 0, 0,
1903 (SCM v
, SCM kv
, SCM obj
),
1906 (bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t).
1908 @var{bv} is not modified.")
1909 #define FUNC_NAME s_scm_bit_count_star
1911 register long i
, vlen
, count
= 0;
1912 register unsigned long k
;
1913 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1914 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1915 switch SCM_TYP7 (kv
)
1918 badarg2
:SCM_WTA (2,kv
);
1924 badarg1
:SCM_WTA (1,v
);
1926 vlen
= SCM_LENGTH (v
);
1927 if (SCM_BOOL_F
== obj
)
1928 for (i
= SCM_LENGTH (kv
); i
;)
1930 k
= SCM_VELTS (kv
)[--i
];
1931 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1932 if (!(SCM_VELTS (v
)[k
/ SCM_LONG_BIT
] & (1L << (k
% SCM_LONG_BIT
))))
1935 else if (SCM_BOOL_T
== obj
)
1936 for (i
= SCM_LENGTH (kv
); i
;)
1938 k
= SCM_VELTS (kv
)[--i
];
1939 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1940 if (SCM_VELTS (v
)[k
/ SCM_LONG_BIT
] & (1L << (k
% SCM_LONG_BIT
)))
1944 badarg3
:SCM_WTA (3,obj
);
1948 SCM_ASRTGO (SCM_TYP7 (v
) == scm_tc7_bvect
&& SCM_LENGTH (v
) == SCM_LENGTH (kv
), badarg1
);
1949 if (0 == SCM_LENGTH (v
))
1951 SCM_ASRTGO (SCM_BOOL_T
== obj
|| SCM_BOOL_F
== obj
, badarg3
);
1952 obj
= (SCM_BOOL_T
== obj
);
1953 i
= (SCM_LENGTH (v
) - 1) / SCM_LONG_BIT
;
1954 k
= SCM_VELTS (kv
)[i
] & (obj
? SCM_VELTS (v
)[i
] : ~SCM_VELTS (v
)[i
]);
1955 k
<<= SCM_LONG_BIT
- 1 - ((SCM_LENGTH (v
) - 1) % SCM_LONG_BIT
);
1959 count
+= cnt_tab
[k
& 0x0f];
1961 return SCM_MAKINUM (count
);
1962 k
= SCM_VELTS (kv
)[i
] & (obj
? SCM_VELTS (v
)[i
] : ~SCM_VELTS (v
)[i
]);
1965 return SCM_MAKINUM (count
);
1970 SCM_DEFINE (scm_bit_invert_x
, "bit-invert!", 1, 0, 0,
1972 "Modifies @var{bv} by replacing each element with its negation.")
1973 #define FUNC_NAME s_scm_bit_invert_x
1976 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1982 for (k
= (k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1983 SCM_VELTS (v
)[k
] = ~SCM_VELTS (v
)[k
];
1986 badarg1
:SCM_WTA (1,v
);
1988 return SCM_UNSPECIFIED
;
1994 scm_istr2bve (char *str
, long len
)
1996 SCM v
= scm_make_uve (len
, SCM_BOOL_T
);
1997 long *data
= (long *) SCM_VELTS (v
);
1998 register unsigned long mask
;
2001 for (k
= 0; k
< (len
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
++)
2004 j
= len
- k
* SCM_LONG_BIT
;
2005 if (j
> SCM_LONG_BIT
)
2007 for (mask
= 1L; j
--; mask
<<= 1)
2025 ra2l (SCM ra
,scm_sizet base
,scm_sizet k
)
2027 register SCM res
= SCM_EOL
;
2028 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2029 register scm_sizet i
;
2030 if (SCM_ARRAY_DIMS (ra
)[k
].ubnd
< SCM_ARRAY_DIMS (ra
)[k
].lbnd
)
2032 i
= base
+ (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
) * inc
;
2033 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2038 res
= scm_cons (ra2l (ra
, i
, k
+ 1), res
);
2046 res
= scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra
), SCM_MAKINUM (i
)), res
);
2053 SCM_DEFINE (scm_array_to_list
, "array->list", 1, 0, 0,
2055 "Returns a list consisting of all the elements, in order, of @var{array}.")
2056 #define FUNC_NAME s_scm_array_to_list
2060 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
2065 badarg1
:SCM_WTA (1,v
);
2067 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
2068 return ra2l (v
, SCM_ARRAY_BASE (v
), 0);
2069 case scm_tc7_vector
:
2071 return scm_vector_to_list (v
);
2072 case scm_tc7_string
:
2073 return scm_string_to_list (v
);
2076 long *data
= (long *) SCM_VELTS (v
);
2077 register unsigned long mask
;
2078 for (k
= (SCM_LENGTH (v
) - 1) / SCM_LONG_BIT
; k
> 0; k
--)
2079 for (mask
= 1UL << (SCM_LONG_BIT
- 1); mask
; mask
>>= 1)
2080 res
= scm_cons (SCM_BOOL(((long *) data
)[k
] & mask
), res
);
2081 for (mask
= 1L << ((SCM_LENGTH (v
) % SCM_LONG_BIT
) - 1); mask
; mask
>>= 1)
2082 res
= scm_cons (SCM_BOOL(((long *) data
)[k
] & mask
), res
);
2085 # ifdef SCM_INUMS_ONLY
2089 long *data
= (long *) SCM_VELTS (v
);
2090 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2091 res
= scm_cons (SCM_MAKINUM (data
[k
]), res
);
2095 case scm_tc7_uvect
: {
2096 long *data
= (long *)SCM_VELTS(v
);
2097 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2098 res
= scm_cons(scm_ulong2num(data
[k
]), res
);
2101 case scm_tc7_ivect
: {
2102 long *data
= (long *)SCM_VELTS(v
);
2103 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2104 res
= scm_cons(scm_long2num(data
[k
]), res
);
2108 case scm_tc7_svect
: {
2110 data
= (short *)SCM_VELTS(v
);
2111 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2112 res
= scm_cons(SCM_MAKINUM (data
[k
]), res
);
2115 #ifdef HAVE_LONG_LONGS
2116 case scm_tc7_llvect
: {
2118 data
= (long_long
*)SCM_VELTS(v
);
2119 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2120 res
= scm_cons(scm_long_long2num(data
[k
]), res
);
2130 float *data
= (float *) SCM_VELTS (v
);
2131 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2132 res
= scm_cons (scm_makflo (data
[k
]), res
);
2135 #endif /*SCM_SINGLES*/
2138 double *data
= (double *) SCM_VELTS (v
);
2139 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2140 res
= scm_cons (scm_makdbl (data
[k
], 0.0), res
);
2145 double (*data
)[2] = (double (*)[2]) SCM_VELTS (v
);
2146 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2147 res
= scm_cons (scm_makdbl (data
[k
][0], data
[k
][1]), res
);
2150 #endif /*SCM_FLOATS*/
2156 static char s_bad_ralst
[] = "Bad scm_array contents list";
2158 static int l2ra(SCM lst
, SCM ra
, scm_sizet base
, scm_sizet k
);
2160 SCM_DEFINE (scm_list_to_uniform_array
, "list->uniform-array", 3, 0, 0,
2161 (SCM ndim
, SCM prot
, SCM lst
),
2162 "@deffnx procedure list->uniform-vector prot lst
2163 Returns a uniform array of the type indicated by prototype @var{prot}
2164 with elements the same as those of @var{lst}. Elements must be of the
2165 appropriate type, no coercions are done.")
2166 #define FUNC_NAME s_scm_list_to_uniform_array
2173 SCM_VALIDATE_INUM_COPY (1,ndim
,k
);
2176 n
= scm_ilength (row
);
2177 SCM_ASSERT (n
>= 0, lst
, SCM_ARG3
, FUNC_NAME
);
2178 shp
= scm_cons (SCM_MAKINUM (n
), shp
);
2180 row
= SCM_CAR (row
);
2182 ra
= scm_dimensions_to_uniform_array (scm_reverse (shp
), prot
,
2184 if (SCM_NULLP (shp
))
2187 SCM_ASRTGO (1 == scm_ilength (lst
), badlst
);
2188 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_EOL
);
2191 if (!SCM_ARRAYP (ra
))
2193 for (k
= 0; k
< SCM_LENGTH (ra
); k
++, lst
= SCM_CDR (lst
))
2194 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_MAKINUM (k
));
2197 if (l2ra (lst
, ra
, SCM_ARRAY_BASE (ra
), 0))
2200 badlst
:scm_wta (lst
, s_bad_ralst
, FUNC_NAME
);
2206 l2ra (SCM lst
, SCM ra
, scm_sizet base
, scm_sizet k
)
2208 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2209 register long n
= (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
);
2212 return (SCM_EOL
== lst
);
2213 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2217 if (SCM_IMP (lst
) || SCM_NCONSP (lst
))
2219 ok
= ok
&& l2ra (SCM_CAR (lst
), ra
, base
, k
+ 1);
2221 lst
= SCM_CDR (lst
);
2223 if (SCM_NNULLP (lst
))
2230 if (SCM_IMP (lst
) || SCM_NCONSP (lst
))
2232 ok
= ok
&& scm_array_set_x (SCM_ARRAY_V (ra
), SCM_CAR (lst
), SCM_MAKINUM (base
));
2234 lst
= SCM_CDR (lst
);
2236 if (SCM_NNULLP (lst
))
2244 rapr1 (SCM ra
,scm_sizet j
,scm_sizet k
,SCM port
,scm_print_state
*pstate
)
2247 long n
= SCM_LENGTH (ra
);
2250 switch SCM_TYP7 (ra
)
2255 SCM_ARRAY_BASE (ra
) = j
;
2257 scm_iprin1 (ra
, port
, pstate
);
2258 for (j
+= inc
; n
-- > 0; j
+= inc
)
2260 scm_putc (' ', port
);
2261 SCM_ARRAY_BASE (ra
) = j
;
2262 scm_iprin1 (ra
, port
, pstate
);
2266 if (k
+ 1 < SCM_ARRAY_NDIM (ra
))
2269 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2270 for (i
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
; i
< SCM_ARRAY_DIMS (ra
)[k
].ubnd
; i
++)
2272 scm_putc ('(', port
);
2273 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2274 scm_puts (") ", port
);
2277 if (i
== SCM_ARRAY_DIMS (ra
)[k
].ubnd
)
2278 { /* could be zero size. */
2279 scm_putc ('(', port
);
2280 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2281 scm_putc (')', port
);
2287 { /* Could be zero-dimensional */
2288 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2289 n
= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
2293 ra
= SCM_ARRAY_V (ra
);
2296 /* scm_tc7_bvect and scm_tc7_llvect only? */
2298 scm_iprin1 (scm_uniform_vector_ref (ra
, SCM_MAKINUM (j
)), port
, pstate
);
2299 for (j
+= inc
; n
-- > 0; j
+= inc
)
2301 scm_putc (' ', port
);
2302 scm_iprin1 (scm_cvref (ra
, j
, SCM_UNDEFINED
), port
, pstate
);
2305 case scm_tc7_string
:
2307 scm_iprin1 (SCM_MAKICHR (SCM_UCHARS (ra
)[j
]), port
, pstate
);
2308 if (SCM_WRITINGP (pstate
))
2309 for (j
+= inc
; n
-- > 0; j
+= inc
)
2311 scm_putc (' ', port
);
2312 scm_iprin1 (SCM_MAKICHR (SCM_UCHARS (ra
)[j
]), port
, pstate
);
2315 for (j
+= inc
; n
-- > 0; j
+= inc
)
2316 scm_putc (SCM_CHARS (ra
)[j
], port
);
2318 case scm_tc7_byvect
:
2320 scm_intprint (((char *)SCM_CDR (ra
))[j
], 10, port
);
2321 for (j
+= inc
; n
-- > 0; j
+= inc
)
2323 scm_putc (' ', port
);
2324 scm_intprint (((char *)SCM_CDR (ra
))[j
], 10, port
);
2334 /* intprint can't handle >= 2^31. */
2335 sprintf (str
, "%lu", (unsigned long) SCM_VELTS (ra
)[j
]);
2336 scm_puts (str
, port
);
2338 for (j
+= inc
; n
-- > 0; j
+= inc
)
2340 scm_putc (' ', port
);
2341 sprintf (str
, "%lu", (unsigned long) SCM_VELTS (ra
)[j
]);
2342 scm_puts (str
, port
);
2347 scm_intprint (SCM_VELTS (ra
)[j
], 10, port
);
2348 for (j
+= inc
; n
-- > 0; j
+= inc
)
2350 scm_putc (' ', port
);
2351 scm_intprint (SCM_VELTS (ra
)[j
], 10, port
);
2357 scm_intprint (((short *)SCM_CDR (ra
))[j
], 10, port
);
2358 for (j
+= inc
; n
-- > 0; j
+= inc
)
2360 scm_putc (' ', port
);
2361 scm_intprint (((short *)SCM_CDR (ra
))[j
], 10, port
);
2370 SCM z
= scm_makflo (1.0);
2371 SCM_FLO (z
) = ((float *) SCM_VELTS (ra
))[j
];
2372 scm_floprint (z
, port
, pstate
);
2373 for (j
+= inc
; n
-- > 0; j
+= inc
)
2375 scm_putc (' ', port
);
2376 SCM_FLO (z
) = ((float *) SCM_VELTS (ra
))[j
];
2377 scm_floprint (z
, port
, pstate
);
2381 #endif /*SCM_SINGLES*/
2385 SCM z
= scm_makdbl (1.0 / 3.0, 0.0);
2386 SCM_REAL (z
) = ((double *) SCM_VELTS (ra
))[j
];
2387 scm_floprint (z
, port
, pstate
);
2388 for (j
+= inc
; n
-- > 0; j
+= inc
)
2390 scm_putc (' ', port
);
2391 SCM_REAL (z
) = ((double *) SCM_VELTS (ra
))[j
];
2392 scm_floprint (z
, port
, pstate
);
2399 SCM cz
= scm_makdbl (0.0, 1.0), z
= scm_makdbl (1.0 / 3.0, 0.0);
2400 SCM_REAL (z
) = SCM_REAL (cz
) = (((double *) SCM_VELTS (ra
))[2 * j
]);
2401 SCM_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2402 scm_floprint ((0.0 == SCM_IMAG (cz
) ? z
: cz
), port
, pstate
);
2403 for (j
+= inc
; n
-- > 0; j
+= inc
)
2405 scm_putc (' ', port
);
2406 SCM_REAL (z
) = SCM_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2407 SCM_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2408 scm_floprint ((0.0 == SCM_IMAG (cz
) ? z
: cz
), port
, pstate
);
2412 #endif /*SCM_FLOATS*/
2419 scm_raprin1 (SCM exp
, SCM port
, scm_print_state
*pstate
)
2423 scm_putc ('#', port
);
2429 long ndim
= SCM_ARRAY_NDIM (v
);
2430 base
= SCM_ARRAY_BASE (v
);
2431 v
= SCM_ARRAY_V (v
);
2435 scm_puts ("<enclosed-array ", port
);
2436 rapr1 (exp
, base
, 0, port
, pstate
);
2437 scm_putc ('>', port
);
2442 scm_intprint (ndim
, 10, port
);
2448 { /* a uve, not an scm_array */
2449 register long i
, j
, w
;
2450 scm_putc ('*', port
);
2451 for (i
= 0; i
< (SCM_LENGTH (exp
)) / SCM_LONG_BIT
; i
++)
2453 w
= SCM_VELTS (exp
)[i
];
2454 for (j
= SCM_LONG_BIT
; j
; j
--)
2456 scm_putc (w
& 1 ? '1' : '0', port
);
2460 j
= SCM_LENGTH (exp
) % SCM_LONG_BIT
;
2463 w
= SCM_VELTS (exp
)[SCM_LENGTH (exp
) / SCM_LONG_BIT
];
2466 scm_putc (w
& 1 ? '1' : '0', port
);
2473 scm_putc ('b', port
);
2475 case scm_tc7_string
:
2476 scm_putc ('a', port
);
2478 case scm_tc7_byvect
:
2479 scm_putc ('y', port
);
2482 scm_putc ('u', port
);
2485 scm_putc ('e', port
);
2488 scm_putc ('h', port
);
2490 #ifdef HAVE_LONG_LONGS
2491 case scm_tc7_llvect
:
2492 scm_putc ('l', port
);
2498 scm_putc ('s', port
);
2500 #endif /*SCM_SINGLES*/
2502 scm_putc ('i', port
);
2505 scm_putc ('c', port
);
2507 #endif /*SCM_FLOATS*/
2509 scm_putc ('(', port
);
2510 rapr1 (exp
, base
, 0, port
, pstate
);
2511 scm_putc (')', port
);
2515 SCM_DEFINE (scm_array_prototype
, "array-prototype", 1, 0, 0,
2517 "Returns an object that would produce an array of the same type as
2518 @var{array}, if used as the @var{prototype} for
2519 @code{make-uniform-array}.")
2520 #define FUNC_NAME s_scm_array_prototype
2523 SCM_ASRTGO (SCM_NIMP (ra
), badarg
);
2529 badarg
:SCM_WTA (1,ra
);
2531 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
2533 return SCM_UNSPECIFIED
;
2534 ra
= SCM_ARRAY_V (ra
);
2536 case scm_tc7_vector
:
2541 case scm_tc7_string
:
2542 return SCM_MAKICHR ('a');
2543 case scm_tc7_byvect
:
2544 return SCM_MAKICHR ('\0');
2546 return SCM_MAKINUM (1L);
2548 return SCM_MAKINUM (-1L);
2550 return SCM_CDR (scm_intern ("s", 1));
2551 #ifdef HAVE_LONG_LONGS
2552 case scm_tc7_llvect
:
2553 return SCM_CDR (scm_intern ("l", 1));
2558 return scm_makflo (1.0);
2561 return scm_makdbl (1.0 / 3.0, 0.0);
2563 return scm_makdbl (0.0, 1.0);
2573 return SCM_ARRAY_V (ptr
);
2580 scm_must_free (SCM_CHARS (ptr
));
2581 return sizeof (scm_array
) + SCM_ARRAY_NDIM (ptr
) * sizeof (scm_array_dim
);
2587 scm_tc16_array
= scm_make_smob_type_mfpe ("array", 0,
2592 scm_add_feature ("array");