1 /* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library 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 GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 This file has code for arrays in lots of variants (double, integer,
21 unsigned etc. ). It suffers from hugely repetitive code because
22 there is similar (but different) code for every variant included. (urg.)
36 #include "libguile/_scm.h"
37 #include "libguile/chars.h"
38 #include "libguile/eval.h"
39 #include "libguile/fports.h"
40 #include "libguile/smob.h"
41 #include "libguile/strop.h"
42 #include "libguile/feature.h"
43 #include "libguile/root.h"
44 #include "libguile/strings.h"
45 #include "libguile/vectors.h"
47 #include "libguile/validate.h"
48 #include "libguile/unif.h"
49 #include "libguile/ramap.h"
60 /* The set of uniform scm_vector types is:
62 * unsigned char string
69 * complex double cvect
74 scm_t_bits scm_tc16_array
;
75 static SCM exactly_one_third
;
77 /* return the size of an element in a uniform array or 0 if type not
80 scm_uniform_element_size (SCM obj
)
84 switch (SCM_TYP7 (obj
))
89 result
= sizeof (long);
93 result
= sizeof (char);
97 result
= sizeof (short);
100 #if SCM_SIZEOF_LONG_LONG != 0
102 result
= sizeof (long long);
107 result
= sizeof (float);
111 result
= sizeof (double);
115 result
= 2 * sizeof (double);
124 /* Silly function used not to modify the semantics of the silly
125 * prototype system in order to be backward compatible.
130 if (!SCM_REALP (obj
))
134 double x
= SCM_REAL_VALUE (obj
);
136 return (- SCM_FLTMAX
< x
) && (x
< SCM_FLTMAX
) && (fx
== x
);
140 static const char s_scm_make_uve
[];
143 make_uve (long type
, long k
, size_t size
)
144 #define FUNC_NAME "scm_make_uve"
146 SCM_ASSERT_RANGE (1, scm_long2num (k
), k
<= SCM_UVECTOR_MAX_LENGTH
);
148 return scm_cell (SCM_MAKE_UVECTOR_TAG (k
, type
),
149 (scm_t_bits
) scm_gc_malloc (k
* size
, "vector"));
154 scm_make_uve (long k
, SCM prot
)
155 #define FUNC_NAME "scm_make_uve"
157 if (SCM_EQ_P (prot
, SCM_BOOL_T
))
163 scm_long2num (k
), k
<= SCM_BITVECTOR_MAX_LENGTH
);
164 i
= sizeof (long) * ((k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
);
165 return scm_cell (SCM_MAKE_BITVECTOR_TAG (k
),
166 (scm_t_bits
) scm_gc_malloc (i
, "vector"));
169 return scm_cell (SCM_MAKE_BITVECTOR_TAG (0), 0);
171 else if (SCM_CHARP (prot
) && (SCM_CHAR (prot
) == '\0'))
172 return make_uve (scm_tc7_byvect
, k
, sizeof (char));
173 else if (SCM_CHARP (prot
))
174 return scm_allocate_string (sizeof (char) * k
);
175 else if (SCM_INUMP (prot
))
176 return make_uve (SCM_INUM (prot
) > 0 ? scm_tc7_uvect
: scm_tc7_ivect
,
179 else if (SCM_FRACTIONP (prot
))
181 if (scm_num_eq_p (exactly_one_third
, prot
))
184 else if (SCM_SYMBOLP (prot
) && (1 == SCM_SYMBOL_LENGTH (prot
)))
188 s
= SCM_SYMBOL_CHARS (prot
)[0];
190 return make_uve (scm_tc7_svect
, k
, sizeof (short));
191 #if SCM_SIZEOF_LONG_LONG != 0
193 return make_uve (scm_tc7_llvect
, k
, sizeof (long long));
196 return scm_c_make_vector (k
, SCM_UNDEFINED
);
198 else if (!SCM_INEXACTP (prot
))
199 /* Huge non-unif vectors are NOT supported. */
200 /* no special scm_vector */
201 return scm_c_make_vector (k
, SCM_UNDEFINED
);
202 else if (singp (prot
))
203 return make_uve (scm_tc7_fvect
, k
, sizeof (float));
204 else if (SCM_COMPLEXP (prot
))
205 return make_uve (scm_tc7_cvect
, k
, 2 * sizeof (double));
207 return make_uve (scm_tc7_dvect
, k
, sizeof (double));
211 SCM_DEFINE (scm_uniform_vector_length
, "uniform-vector-length", 1, 0, 0,
213 "Return the number of elements in @var{uve}.")
214 #define FUNC_NAME s_scm_uniform_vector_length
216 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
220 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
223 return SCM_MAKINUM (SCM_VECTOR_LENGTH (v
));
225 return SCM_MAKINUM (SCM_STRING_LENGTH (v
));
227 return SCM_MAKINUM (SCM_BITVECTOR_LENGTH (v
));
235 #if SCM_SIZEOF_LONG_LONG != 0
238 return SCM_MAKINUM (SCM_UVECTOR_LENGTH (v
));
243 SCM_DEFINE (scm_array_p
, "array?", 1, 1, 0,
245 "Return @code{#t} if the @var{obj} is an array, and @code{#f} if\n"
246 "not. The @var{prototype} argument is used with uniform arrays\n"
247 "and is described elsewhere.")
248 #define FUNC_NAME s_scm_array_p
252 nprot
= SCM_UNBNDP (prot
);
257 while (SCM_TYP7 (v
) == scm_tc7_smob
)
268 return SCM_BOOL(nprot
);
273 switch (SCM_TYP7 (v
))
276 protp
= (SCM_EQ_P (prot
, SCM_BOOL_T
));
279 protp
= SCM_CHARP(prot
) && (SCM_CHAR (prot
) != '\0');
282 protp
= SCM_EQ_P (prot
, SCM_MAKE_CHAR ('\0'));
285 protp
= SCM_INUMP(prot
) && SCM_INUM(prot
)>0;
288 protp
= SCM_INUMP(prot
) && SCM_INUM(prot
)<=0;
291 protp
= SCM_SYMBOLP (prot
)
292 && (1 == SCM_SYMBOL_LENGTH (prot
))
293 && ('s' == SCM_SYMBOL_CHARS (prot
)[0]);
295 #if SCM_SIZEOF_LONG_LONG != 0
297 protp
= SCM_SYMBOLP (prot
)
298 && (1 == SCM_SYMBOL_LENGTH (prot
))
299 && ('l' == SCM_SYMBOL_CHARS (prot
)[0]);
303 protp
= singp (prot
);
306 protp
= ((SCM_REALP(prot
) && ! singp (prot
))
307 || (SCM_FRACTIONP (prot
)
308 && scm_num_eq_p (exactly_one_third
, prot
)));
311 protp
= SCM_COMPLEXP(prot
);
315 protp
= SCM_NULLP(prot
);
321 return SCM_BOOL(protp
);
327 SCM_DEFINE (scm_array_rank
, "array-rank", 1, 0, 0,
329 "Return the number of dimensions of @var{obj}. If @var{obj} is\n"
330 "not an array, @code{0} is returned.")
331 #define FUNC_NAME s_scm_array_rank
335 switch (SCM_TYP7 (ra
))
348 #if SCM_SIZEOF_LONG_LONG != 0
352 return SCM_MAKINUM (1L);
355 return SCM_MAKINUM (SCM_ARRAY_NDIM (ra
));
362 SCM_DEFINE (scm_array_dimensions
, "array-dimensions", 1, 0, 0,
364 "@code{Array-dimensions} is similar to @code{array-shape} but replaces\n"
365 "elements with a @code{0} minimum with one greater than the maximum. So:\n"
367 "(array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5)\n"
369 #define FUNC_NAME s_scm_array_dimensions
376 switch (SCM_TYP7 (ra
))
391 #if SCM_SIZEOF_LONG_LONG != 0
394 return scm_cons (scm_uniform_vector_length (ra
), SCM_EOL
);
396 if (!SCM_ARRAYP (ra
))
398 k
= SCM_ARRAY_NDIM (ra
);
399 s
= SCM_ARRAY_DIMS (ra
);
401 res
= scm_cons (s
[k
].lbnd
402 ? scm_cons2 (SCM_MAKINUM (s
[k
].lbnd
),
403 SCM_MAKINUM (s
[k
].ubnd
),
405 : SCM_MAKINUM (1 + s
[k
].ubnd
),
413 SCM_DEFINE (scm_shared_array_root
, "shared-array-root", 1, 0, 0,
415 "Return the root vector of a shared array.")
416 #define FUNC_NAME s_scm_shared_array_root
418 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
419 return SCM_ARRAY_V (ra
);
424 SCM_DEFINE (scm_shared_array_offset
, "shared-array-offset", 1, 0, 0,
426 "Return the root vector index of the first element in the array.")
427 #define FUNC_NAME s_scm_shared_array_offset
429 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
430 return SCM_MAKINUM (SCM_ARRAY_BASE (ra
));
435 SCM_DEFINE (scm_shared_array_increments
, "shared-array-increments", 1, 0, 0,
437 "For each dimension, return the distance between elements in the root vector.")
438 #define FUNC_NAME s_scm_shared_array_increments
443 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
444 k
= SCM_ARRAY_NDIM (ra
);
445 s
= SCM_ARRAY_DIMS (ra
);
447 res
= scm_cons (SCM_MAKINUM (s
[k
].inc
), res
);
453 static char s_bad_ind
[] = "Bad scm_array index";
457 scm_aind (SCM ra
, SCM args
, const char *what
)
458 #define FUNC_NAME what
462 register unsigned long pos
= SCM_ARRAY_BASE (ra
);
463 register unsigned long k
= SCM_ARRAY_NDIM (ra
);
464 scm_t_array_dim
*s
= SCM_ARRAY_DIMS (ra
);
465 if (SCM_INUMP (args
))
468 scm_error_num_args_subr (what
);
469 return pos
+ (SCM_INUM (args
) - s
->lbnd
) * (s
->inc
);
471 while (k
&& SCM_CONSP (args
))
473 ind
= SCM_CAR (args
);
474 args
= SCM_CDR (args
);
475 if (!SCM_INUMP (ind
))
476 scm_misc_error (what
, s_bad_ind
, SCM_EOL
);
478 if (j
< s
->lbnd
|| j
> s
->ubnd
)
479 scm_out_of_range (what
, ind
);
480 pos
+= (j
- s
->lbnd
) * (s
->inc
);
484 if (k
!= 0 || !SCM_NULLP (args
))
485 scm_error_num_args_subr (what
);
493 scm_make_ra (int ndim
)
497 SCM_NEWSMOB(ra
, ((scm_t_bits
) ndim
<< 17) + scm_tc16_array
,
498 scm_gc_malloc ((sizeof (scm_t_array
) +
499 ndim
* sizeof (scm_t_array_dim
)),
501 SCM_ARRAY_V (ra
) = scm_nullvect
;
506 static char s_bad_spec
[] = "Bad scm_array dimension";
507 /* Increments will still need to be set. */
511 scm_shap2ra (SCM args
, const char *what
)
515 int ndim
= scm_ilength (args
);
517 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
519 ra
= scm_make_ra (ndim
);
520 SCM_ARRAY_BASE (ra
) = 0;
521 s
= SCM_ARRAY_DIMS (ra
);
522 for (; !SCM_NULLP (args
); s
++, args
= SCM_CDR (args
))
524 spec
= SCM_CAR (args
);
525 if (SCM_INUMP (spec
))
527 if (SCM_INUM (spec
) < 0)
528 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
530 s
->ubnd
= SCM_INUM (spec
) - 1;
535 if (!SCM_CONSP (spec
) || !SCM_INUMP (SCM_CAR (spec
)))
536 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
537 s
->lbnd
= SCM_INUM (SCM_CAR (spec
));
540 || !SCM_INUMP (SCM_CAR (sp
))
541 || !SCM_NULLP (SCM_CDR (sp
)))
542 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
543 s
->ubnd
= SCM_INUM (SCM_CAR (sp
));
550 SCM_DEFINE (scm_dimensions_to_uniform_array
, "dimensions->uniform-array", 2, 1, 0,
551 (SCM dims
, SCM prot
, SCM fill
),
552 "@deffnx {Scheme Procedure} make-uniform-vector length prototype [fill]\n"
553 "Create and return a uniform array or vector of type\n"
554 "corresponding to @var{prototype} with dimensions @var{dims} or\n"
555 "length @var{length}. If @var{fill} is supplied, it's used to\n"
556 "fill the array, otherwise @var{prototype} is used.")
557 #define FUNC_NAME s_scm_dimensions_to_uniform_array
560 unsigned long rlen
= 1;
564 if (SCM_INUMP (dims
))
566 SCM answer
= scm_make_uve (SCM_INUM (dims
), prot
);
567 if (!SCM_UNBNDP (fill
))
568 scm_array_fill_x (answer
, fill
);
569 else if (SCM_SYMBOLP (prot
))
570 scm_array_fill_x (answer
, SCM_MAKINUM (0));
572 scm_array_fill_x (answer
, prot
);
576 SCM_ASSERT (SCM_NULLP (dims
) || SCM_CONSP (dims
),
577 dims
, SCM_ARG1
, FUNC_NAME
);
578 ra
= scm_shap2ra (dims
, FUNC_NAME
);
579 SCM_SET_ARRAY_CONTIGUOUS_FLAG (ra
);
580 s
= SCM_ARRAY_DIMS (ra
);
581 k
= SCM_ARRAY_NDIM (ra
);
586 SCM_ASSERT_RANGE (1, dims
, s
[k
].lbnd
<= s
[k
].ubnd
);
587 rlen
= (s
[k
].ubnd
- s
[k
].lbnd
+ 1) * s
[k
].inc
;
590 SCM_ARRAY_V (ra
) = scm_make_uve (rlen
, prot
);
592 if (!SCM_UNBNDP (fill
))
593 scm_array_fill_x (ra
, fill
);
594 else if (SCM_SYMBOLP (prot
))
595 scm_array_fill_x (ra
, SCM_MAKINUM (0));
597 scm_array_fill_x (ra
, prot
);
599 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
600 if (s
->ubnd
< s
->lbnd
|| (0 == s
->lbnd
&& 1 == s
->inc
))
601 return SCM_ARRAY_V (ra
);
608 scm_ra_set_contp (SCM ra
)
610 size_t k
= SCM_ARRAY_NDIM (ra
);
613 long inc
= SCM_ARRAY_DIMS (ra
)[k
- 1].inc
;
616 if (inc
!= SCM_ARRAY_DIMS (ra
)[k
].inc
)
618 SCM_CLR_ARRAY_CONTIGUOUS_FLAG (ra
);
621 inc
*= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
622 - SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
625 SCM_SET_ARRAY_CONTIGUOUS_FLAG (ra
);
629 SCM_DEFINE (scm_make_shared_array
, "make-shared-array", 2, 0, 1,
630 (SCM oldra
, SCM mapfunc
, SCM dims
),
631 "@code{make-shared-array} can be used to create shared subarrays of other\n"
632 "arrays. The @var{mapper} is a function that translates coordinates in\n"
633 "the new array into coordinates in the old array. A @var{mapper} must be\n"
634 "linear, and its range must stay within the bounds of the old array, but\n"
635 "it can be otherwise arbitrary. A simple example:\n"
637 "(define fred (make-array #f 8 8))\n"
638 "(define freds-diagonal\n"
639 " (make-shared-array fred (lambda (i) (list i i)) 8))\n"
640 "(array-set! freds-diagonal 'foo 3)\n"
641 "(array-ref fred 3 3) @result{} foo\n"
642 "(define freds-center\n"
643 " (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))\n"
644 "(array-ref freds-center 0 0) @result{} foo\n"
646 #define FUNC_NAME s_scm_make_shared_array
652 long old_min
, new_min
, old_max
, new_max
;
655 SCM_VALIDATE_REST_ARGUMENT (dims
);
656 SCM_VALIDATE_ARRAY (1, oldra
);
657 SCM_VALIDATE_PROC (2, mapfunc
);
658 ra
= scm_shap2ra (dims
, FUNC_NAME
);
659 if (SCM_ARRAYP (oldra
))
661 SCM_ARRAY_V (ra
) = SCM_ARRAY_V (oldra
);
662 old_min
= old_max
= SCM_ARRAY_BASE (oldra
);
663 s
= SCM_ARRAY_DIMS (oldra
);
664 k
= SCM_ARRAY_NDIM (oldra
);
668 old_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
670 old_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
675 SCM_ARRAY_V (ra
) = oldra
;
677 old_max
= SCM_INUM (scm_uniform_vector_length (oldra
)) - 1;
680 s
= SCM_ARRAY_DIMS (ra
);
681 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
683 inds
= scm_cons (SCM_MAKINUM (s
[k
].lbnd
), inds
);
684 if (s
[k
].ubnd
< s
[k
].lbnd
)
686 if (1 == SCM_ARRAY_NDIM (ra
))
687 ra
= scm_make_uve (0L, scm_array_prototype (ra
));
689 SCM_ARRAY_V (ra
) = scm_make_uve (0L, scm_array_prototype (ra
));
693 imap
= scm_apply_0 (mapfunc
, scm_reverse (inds
));
694 if (SCM_ARRAYP (oldra
))
695 i
= (size_t) scm_aind (oldra
, imap
, FUNC_NAME
);
698 if (SCM_NINUMP (imap
))
701 if (scm_ilength (imap
) != 1 || !SCM_INUMP (SCM_CAR (imap
)))
702 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
703 imap
= SCM_CAR (imap
);
707 SCM_ARRAY_BASE (ra
) = new_min
= new_max
= i
;
709 k
= SCM_ARRAY_NDIM (ra
);
712 if (s
[k
].ubnd
> s
[k
].lbnd
)
714 SCM_SETCAR (indptr
, SCM_MAKINUM (SCM_INUM (SCM_CAR (indptr
)) + 1));
715 imap
= scm_apply_0 (mapfunc
, scm_reverse (inds
));
716 if (SCM_ARRAYP (oldra
))
718 s
[k
].inc
= scm_aind (oldra
, imap
, FUNC_NAME
) - i
;
721 if (SCM_NINUMP (imap
))
723 if (scm_ilength (imap
) != 1 || !SCM_INUMP (SCM_CAR (imap
)))
724 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
725 imap
= SCM_CAR (imap
);
727 s
[k
].inc
= (long) SCM_INUM (imap
) - i
;
731 new_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
733 new_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
736 s
[k
].inc
= new_max
- new_min
+ 1; /* contiguous by default */
737 indptr
= SCM_CDR (indptr
);
739 if (old_min
> new_min
|| old_max
< new_max
)
740 SCM_MISC_ERROR ("mapping out of range", SCM_EOL
);
741 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
743 SCM v
= SCM_ARRAY_V (ra
);
744 unsigned long int length
= SCM_INUM (scm_uniform_vector_length (v
));
745 if (1 == s
->inc
&& 0 == s
->lbnd
&& length
== 1 + s
->ubnd
)
747 if (s
->ubnd
< s
->lbnd
)
748 return scm_make_uve (0L, scm_array_prototype (ra
));
750 scm_ra_set_contp (ra
);
756 /* args are RA . DIMS */
757 SCM_DEFINE (scm_transpose_array
, "transpose-array", 1, 0, 1,
759 "Return an array sharing contents with @var{array}, but with\n"
760 "dimensions arranged in a different order. There must be one\n"
761 "@var{dim} argument for each dimension of @var{array}.\n"
762 "@var{dim0}, @var{dim1}, @dots{} should be integers between 0\n"
763 "and the rank of the array to be returned. Each integer in that\n"
764 "range must appear at least once in the argument list.\n"
766 "The values of @var{dim0}, @var{dim1}, @dots{} correspond to\n"
767 "dimensions in the array to be returned, their positions in the\n"
768 "argument list to dimensions of @var{array}. Several @var{dim}s\n"
769 "may have the same value, in which case the returned array will\n"
770 "have smaller rank than @var{array}.\n"
773 "(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))\n"
774 "(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)\n"
775 "(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}\n"
776 " #2((a 4) (b 5) (c 6))\n"
778 #define FUNC_NAME s_scm_transpose_array
781 SCM
const *ve
= &vargs
;
782 scm_t_array_dim
*s
, *r
;
785 SCM_VALIDATE_REST_ARGUMENT (args
);
786 SCM_ASSERT (SCM_NIMP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
787 switch (SCM_TYP7 (ra
))
790 badarg
:SCM_WRONG_TYPE_ARG (1, ra
);
800 #if SCM_SIZEOF_LONG_LONG != 0
803 if (SCM_NULLP (args
) || !SCM_NULLP (SCM_CDR (args
)))
804 SCM_WRONG_NUM_ARGS ();
805 SCM_VALIDATE_INUM (SCM_ARG2
, SCM_CAR (args
));
806 SCM_ASSERT_RANGE (SCM_ARG2
, SCM_CAR (args
),
807 SCM_EQ_P (SCM_INUM0
, SCM_CAR (args
)));
810 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
811 vargs
= scm_vector (args
);
812 if (SCM_VECTOR_LENGTH (vargs
) != SCM_ARRAY_NDIM (ra
))
813 SCM_WRONG_NUM_ARGS ();
814 ve
= SCM_VELTS (vargs
);
816 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
818 SCM_ASSERT (SCM_INUMP (ve
[k
]), ve
[k
], (SCM_ARG2
+ k
),
820 i
= SCM_INUM (ve
[k
]);
821 if (i
< 0 || i
>= SCM_ARRAY_NDIM (ra
))
822 scm_out_of_range (FUNC_NAME
, ve
[k
]);
827 res
= scm_make_ra (ndim
);
828 SCM_ARRAY_V (res
) = SCM_ARRAY_V (ra
);
829 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra
);
832 SCM_ARRAY_DIMS (res
)[k
].lbnd
= 0;
833 SCM_ARRAY_DIMS (res
)[k
].ubnd
= -1;
835 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
837 i
= SCM_INUM (ve
[k
]);
838 s
= &(SCM_ARRAY_DIMS (ra
)[k
]);
839 r
= &(SCM_ARRAY_DIMS (res
)[i
]);
840 if (r
->ubnd
< r
->lbnd
)
849 if (r
->ubnd
> s
->ubnd
)
851 if (r
->lbnd
< s
->lbnd
)
853 SCM_ARRAY_BASE (res
) += (s
->lbnd
- r
->lbnd
) * r
->inc
;
860 SCM_MISC_ERROR ("bad argument list", SCM_EOL
);
861 scm_ra_set_contp (res
);
867 /* args are RA . AXES */
868 SCM_DEFINE (scm_enclose_array
, "enclose-array", 1, 0, 1,
870 "@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than\n"
871 "the rank of @var{array}. @var{enclose-array} returns an array\n"
872 "resembling an array of shared arrays. The dimensions of each shared\n"
873 "array are the same as the @var{dim}th dimensions of the original array,\n"
874 "the dimensions of the outer array are the same as those of the original\n"
875 "array that did not match a @var{dim}.\n\n"
876 "An enclosed array is not a general Scheme array. Its elements may not\n"
877 "be set using @code{array-set!}. Two references to the same element of\n"
878 "an enclosed array will be @code{equal?} but will not in general be\n"
879 "@code{eq?}. The value returned by @var{array-prototype} when given an\n"
880 "enclosed array is unspecified.\n\n"
883 "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) @result{}\n"
884 " #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>\n\n"
885 "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{}\n"
886 " #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>\n"
888 #define FUNC_NAME s_scm_enclose_array
890 SCM axv
, res
, ra_inr
;
891 scm_t_array_dim vdim
, *s
= &vdim
;
892 int ndim
, j
, k
, ninr
, noutr
;
894 SCM_VALIDATE_REST_ARGUMENT (axes
);
895 if (SCM_NULLP (axes
))
896 axes
= scm_cons ((SCM_ARRAYP (ra
) ? SCM_MAKINUM (SCM_ARRAY_NDIM (ra
) - 1) : SCM_INUM0
), SCM_EOL
);
897 ninr
= scm_ilength (axes
);
899 SCM_WRONG_NUM_ARGS ();
900 ra_inr
= scm_make_ra (ninr
);
901 SCM_ASRTGO (SCM_NIMP (ra
), badarg1
);
905 badarg1
:SCM_WRONG_TYPE_ARG (1, ra
);
917 #if SCM_SIZEOF_LONG_LONG != 0
921 s
->ubnd
= SCM_INUM (scm_uniform_vector_length (ra
)) - 1;
923 SCM_ARRAY_V (ra_inr
) = ra
;
924 SCM_ARRAY_BASE (ra_inr
) = 0;
928 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg1
);
929 s
= SCM_ARRAY_DIMS (ra
);
930 SCM_ARRAY_V (ra_inr
) = SCM_ARRAY_V (ra
);
931 SCM_ARRAY_BASE (ra_inr
) = SCM_ARRAY_BASE (ra
);
932 ndim
= SCM_ARRAY_NDIM (ra
);
937 SCM_WRONG_NUM_ARGS ();
938 axv
= scm_make_string (SCM_MAKINUM (ndim
), SCM_MAKE_CHAR (0));
939 res
= scm_make_ra (noutr
);
940 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra_inr
);
941 SCM_ARRAY_V (res
) = ra_inr
;
942 for (k
= 0; k
< ninr
; k
++, axes
= SCM_CDR (axes
))
944 if (!SCM_INUMP (SCM_CAR (axes
)))
945 SCM_MISC_ERROR ("bad axis", SCM_EOL
);
946 j
= SCM_INUM (SCM_CAR (axes
));
947 SCM_ARRAY_DIMS (ra_inr
)[k
].lbnd
= s
[j
].lbnd
;
948 SCM_ARRAY_DIMS (ra_inr
)[k
].ubnd
= s
[j
].ubnd
;
949 SCM_ARRAY_DIMS (ra_inr
)[k
].inc
= s
[j
].inc
;
950 SCM_STRING_CHARS (axv
)[j
] = 1;
952 for (j
= 0, k
= 0; k
< noutr
; k
++, j
++)
954 while (SCM_STRING_CHARS (axv
)[j
])
956 SCM_ARRAY_DIMS (res
)[k
].lbnd
= s
[j
].lbnd
;
957 SCM_ARRAY_DIMS (res
)[k
].ubnd
= s
[j
].ubnd
;
958 SCM_ARRAY_DIMS (res
)[k
].inc
= s
[j
].inc
;
960 scm_ra_set_contp (ra_inr
);
961 scm_ra_set_contp (res
);
968 SCM_DEFINE (scm_array_in_bounds_p
, "array-in-bounds?", 1, 0, 1,
970 "Return @code{#t} if its arguments would be acceptable to\n"
972 #define FUNC_NAME s_scm_array_in_bounds_p
980 SCM_VALIDATE_REST_ARGUMENT (args
);
981 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
985 ind
= SCM_CAR (args
);
986 args
= SCM_CDR (args
);
987 SCM_ASSERT (SCM_INUMP (ind
), ind
, SCM_ARG2
, FUNC_NAME
);
988 pos
= SCM_INUM (ind
);
994 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
995 wna
: SCM_WRONG_NUM_ARGS ();
997 k
= SCM_ARRAY_NDIM (v
);
998 s
= SCM_ARRAY_DIMS (v
);
999 pos
= SCM_ARRAY_BASE (v
);
1002 SCM_ASRTGO (SCM_NULLP (ind
), wna
);
1009 if (!(j
>= (s
->lbnd
) && j
<= (s
->ubnd
)))
1011 SCM_ASRTGO (--k
== scm_ilength (args
), wna
);
1014 pos
+= (j
- s
->lbnd
) * (s
->inc
);
1015 if (!(--k
&& SCM_NIMP (args
)))
1017 ind
= SCM_CAR (args
);
1018 args
= SCM_CDR (args
);
1020 if (!SCM_INUMP (ind
))
1021 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
1023 SCM_ASRTGO (0 == k
, wna
);
1024 v
= SCM_ARRAY_V (v
);
1027 case scm_tc7_string
:
1028 case scm_tc7_byvect
:
1035 #if SCM_SIZEOF_LONG_LONG != 0
1036 case scm_tc7_llvect
:
1038 case scm_tc7_vector
:
1041 unsigned long int length
= SCM_INUM (scm_uniform_vector_length (v
));
1042 SCM_ASRTGO (SCM_NULLP (args
) && SCM_INUMP (ind
), wna
);
1043 return SCM_BOOL(pos
>= 0 && pos
< length
);
1050 SCM_REGISTER_PROC(s_array_ref
, "array-ref", 1, 0, 1, scm_uniform_vector_ref
);
1053 SCM_DEFINE (scm_uniform_vector_ref
, "uniform-vector-ref", 2, 0, 0,
1055 "@deffnx {Scheme Procedure} array-ref v . args\n"
1056 "Return the element at the @code{(index1, index2)} element in\n"
1058 #define FUNC_NAME s_scm_uniform_vector_ref
1064 SCM_ASRTGO (SCM_NULLP (args
), badarg
);
1067 else if (SCM_ARRAYP (v
))
1069 pos
= scm_aind (v
, args
, FUNC_NAME
);
1070 v
= SCM_ARRAY_V (v
);
1074 unsigned long int length
;
1075 if (SCM_NIMP (args
))
1077 SCM_ASSERT (SCM_CONSP (args
) && SCM_INUMP (SCM_CAR (args
)), args
, SCM_ARG2
, FUNC_NAME
);
1078 pos
= SCM_INUM (SCM_CAR (args
));
1079 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1083 SCM_VALIDATE_INUM (2, args
);
1084 pos
= SCM_INUM (args
);
1086 length
= SCM_INUM (scm_uniform_vector_length (v
));
1087 SCM_ASRTGO (pos
>= 0 && pos
< length
, outrng
);
1092 if (SCM_NULLP (args
))
1095 SCM_WRONG_TYPE_ARG (1, v
);
1099 scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (pos
));
1101 SCM_WRONG_NUM_ARGS ();
1104 int k
= SCM_ARRAY_NDIM (v
);
1105 SCM res
= scm_make_ra (k
);
1106 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1107 SCM_ARRAY_BASE (res
) = pos
;
1110 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1111 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1112 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1117 if (SCM_BITVEC_REF (v
, pos
))
1121 case scm_tc7_string
:
1122 return SCM_MAKE_CHAR (SCM_STRING_UCHARS (v
)[pos
]);
1123 case scm_tc7_byvect
:
1124 return SCM_MAKINUM (((char *) SCM_UVECTOR_BASE (v
))[pos
]);
1126 return scm_ulong2num (((unsigned long *) SCM_VELTS (v
))[pos
]);
1128 return scm_long2num (((signed long *) SCM_VELTS (v
))[pos
]);
1131 return SCM_MAKINUM (((short *) SCM_CELL_WORD_1 (v
))[pos
]);
1132 #if SCM_SIZEOF_LONG_LONG != 0
1133 case scm_tc7_llvect
:
1134 return scm_long_long2num (((long long *) SCM_CELL_WORD_1 (v
))[pos
]);
1138 return scm_make_real (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1140 return scm_make_real (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1142 return scm_make_complex (((double *) SCM_CELL_WORD_1 (v
))[2 * pos
],
1143 ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1]);
1144 case scm_tc7_vector
:
1146 return SCM_VELTS (v
)[pos
];
1151 /* Internal version of scm_uniform_vector_ref for uves that does no error checking and
1152 tries to recycle conses. (Make *sure* you want them recycled.) */
1155 scm_cvref (SCM v
, unsigned long pos
, SCM last
)
1156 #define FUNC_NAME "scm_cvref"
1161 SCM_WRONG_TYPE_ARG (SCM_ARG1
, v
);
1163 if (SCM_BITVEC_REF(v
, pos
))
1167 case scm_tc7_string
:
1168 return SCM_MAKE_CHAR (SCM_STRING_UCHARS (v
)[pos
]);
1169 case scm_tc7_byvect
:
1170 return SCM_MAKINUM (((char *) SCM_UVECTOR_BASE (v
))[pos
]);
1172 return scm_ulong2num(((unsigned long *) SCM_VELTS (v
))[pos
]);
1174 return scm_long2num(((signed long *) SCM_VELTS (v
))[pos
]);
1176 return SCM_MAKINUM (((short *) SCM_CELL_WORD_1 (v
))[pos
]);
1177 #if SCM_SIZEOF_LONG_LONG != 0
1178 case scm_tc7_llvect
:
1179 return scm_long_long2num (((long long *) SCM_CELL_WORD_1 (v
))[pos
]);
1182 if (SCM_REALP (last
) && !SCM_EQ_P (last
, scm_flo0
))
1184 SCM_REAL_VALUE (last
) = ((float *) SCM_CELL_WORD_1 (v
))[pos
];
1187 return scm_make_real (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1189 if (SCM_REALP (last
) && !SCM_EQ_P (last
, scm_flo0
))
1191 SCM_REAL_VALUE (last
) = ((double *) SCM_CELL_WORD_1 (v
))[pos
];
1194 return scm_make_real (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1196 if (SCM_COMPLEXP (last
))
1198 SCM_COMPLEX_REAL (last
) = ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
];
1199 SCM_COMPLEX_IMAG (last
) = ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1];
1202 return scm_make_complex (((double *) SCM_CELL_WORD_1 (v
))[2 * pos
],
1203 ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1]);
1204 case scm_tc7_vector
:
1206 return SCM_VELTS (v
)[pos
];
1208 { /* enclosed scm_array */
1209 int k
= SCM_ARRAY_NDIM (v
);
1210 SCM res
= scm_make_ra (k
);
1211 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1212 SCM_ARRAY_BASE (res
) = pos
;
1215 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1216 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1217 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1226 SCM_REGISTER_PROC(s_uniform_array_set1_x
, "uniform-array-set1!", 3, 0, 0, scm_array_set_x
);
1229 /* Note that args may be a list or an immediate object, depending which
1230 PROC is used (and it's called from C too). */
1231 SCM_DEFINE (scm_array_set_x
, "array-set!", 2, 0, 1,
1232 (SCM v
, SCM obj
, SCM args
),
1233 "@deffnx {Scheme Procedure} uniform-array-set1! v obj args\n"
1234 "Set the element at the @code{(index1, index2)} element in @var{array} to\n"
1235 "@var{new-value}. The value returned by array-set! is unspecified.")
1236 #define FUNC_NAME s_scm_array_set_x
1240 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1243 pos
= scm_aind (v
, args
, FUNC_NAME
);
1244 v
= SCM_ARRAY_V (v
);
1248 unsigned long int length
;
1249 if (SCM_CONSP (args
))
1251 SCM_ASSERT (SCM_INUMP (SCM_CAR (args
)), args
, SCM_ARG3
, FUNC_NAME
);
1252 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1253 pos
= SCM_INUM (SCM_CAR (args
));
1257 SCM_VALIDATE_INUM_COPY (3, args
, pos
);
1259 length
= SCM_INUM (scm_uniform_vector_length (v
));
1260 SCM_ASRTGO (pos
>= 0 && pos
< length
, outrng
);
1262 switch (SCM_TYP7 (v
))
1265 SCM_WRONG_TYPE_ARG (1, v
);
1268 scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (pos
));
1270 SCM_WRONG_NUM_ARGS ();
1271 case scm_tc7_smob
: /* enclosed */
1274 if (SCM_FALSEP (obj
))
1275 SCM_BITVEC_CLR(v
, pos
);
1276 else if (SCM_EQ_P (obj
, SCM_BOOL_T
))
1277 SCM_BITVEC_SET(v
, pos
);
1279 badobj
:SCM_WRONG_TYPE_ARG (2, obj
);
1281 case scm_tc7_string
:
1282 SCM_ASRTGO (SCM_CHARP (obj
), badobj
);
1283 SCM_STRING_UCHARS (v
)[pos
] = SCM_CHAR (obj
);
1285 case scm_tc7_byvect
:
1286 if (SCM_CHARP (obj
))
1287 obj
= SCM_MAKINUM ((char) SCM_CHAR (obj
));
1288 SCM_ASRTGO (SCM_INUMP (obj
), badobj
);
1289 ((char *) SCM_UVECTOR_BASE (v
))[pos
] = SCM_INUM (obj
);
1292 ((unsigned long *) SCM_UVECTOR_BASE (v
))[pos
]
1293 = scm_num2ulong (obj
, SCM_ARG2
, FUNC_NAME
);
1296 ((long *) SCM_UVECTOR_BASE (v
))[pos
]
1297 = scm_num2long (obj
, SCM_ARG2
, FUNC_NAME
);
1300 SCM_ASRTGO (SCM_INUMP (obj
), badobj
);
1301 ((short *) SCM_UVECTOR_BASE (v
))[pos
] = SCM_INUM (obj
);
1303 #if SCM_SIZEOF_LONG_LONG != 0
1304 case scm_tc7_llvect
:
1305 ((long long *) SCM_UVECTOR_BASE (v
))[pos
]
1306 = scm_num2long_long (obj
, SCM_ARG2
, FUNC_NAME
);
1310 ((float *) SCM_UVECTOR_BASE (v
))[pos
]
1311 = (float) scm_num2dbl (obj
, FUNC_NAME
);
1314 ((double *) SCM_UVECTOR_BASE (v
))[pos
]
1315 = scm_num2dbl (obj
, FUNC_NAME
);
1318 SCM_ASRTGO (SCM_INEXACTP (obj
), badobj
);
1319 if (SCM_REALP (obj
)) {
1320 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
] = SCM_REAL_VALUE (obj
);
1321 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
+ 1] = 0.0;
1323 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
] = SCM_COMPLEX_REAL (obj
);
1324 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
+ 1] = SCM_COMPLEX_IMAG (obj
);
1327 case scm_tc7_vector
:
1329 SCM_VECTOR_SET (v
, pos
, obj
);
1332 return SCM_UNSPECIFIED
;
1336 /* attempts to unroll an array into a one-dimensional array.
1337 returns the unrolled array or #f if it can't be done. */
1338 /* if strict is not SCM_UNDEFINED, return #f if returned array
1339 wouldn't have contiguous elements. */
1340 SCM_DEFINE (scm_array_contents
, "array-contents", 1, 1, 0,
1341 (SCM ra
, SCM strict
),
1342 "If @var{array} may be @dfn{unrolled} into a one dimensional shared array\n"
1343 "without changing their order (last subscript changing fastest), then\n"
1344 "@code{array-contents} returns that shared array, otherwise it returns\n"
1345 "@code{#f}. All arrays made by @var{make-array} and\n"
1346 "@var{make-uniform-array} may be unrolled, some arrays made by\n"
1347 "@var{make-shared-array} may not be.\n\n"
1348 "If the optional argument @var{strict} is provided, a shared array will\n"
1349 "be returned only if its elements are stored internally contiguous in\n"
1351 #define FUNC_NAME s_scm_array_contents
1356 switch SCM_TYP7 (ra
)
1360 case scm_tc7_vector
:
1362 case scm_tc7_string
:
1364 case scm_tc7_byvect
:
1371 #if SCM_SIZEOF_LONG_LONG != 0
1372 case scm_tc7_llvect
:
1377 size_t k
, ndim
= SCM_ARRAY_NDIM (ra
), len
= 1;
1378 if (!SCM_ARRAYP (ra
) || !SCM_ARRAY_CONTP (ra
))
1380 for (k
= 0; k
< ndim
; k
++)
1381 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1382 if (!SCM_UNBNDP (strict
))
1384 if (ndim
&& (1 != SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
))
1386 if (scm_tc7_bvect
== SCM_TYP7 (SCM_ARRAY_V (ra
)))
1388 if (len
!= SCM_BITVECTOR_LENGTH (SCM_ARRAY_V (ra
)) ||
1389 SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
||
1396 SCM v
= SCM_ARRAY_V (ra
);
1397 unsigned long int length
= SCM_INUM (scm_uniform_vector_length (v
));
1398 if ((len
== length
) && 0 == SCM_ARRAY_BASE (ra
) && SCM_ARRAY_DIMS (ra
)->inc
)
1402 sra
= scm_make_ra (1);
1403 SCM_ARRAY_DIMS (sra
)->lbnd
= 0;
1404 SCM_ARRAY_DIMS (sra
)->ubnd
= len
- 1;
1405 SCM_ARRAY_V (sra
) = SCM_ARRAY_V (ra
);
1406 SCM_ARRAY_BASE (sra
) = SCM_ARRAY_BASE (ra
);
1407 SCM_ARRAY_DIMS (sra
)->inc
= (ndim
? SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
: 1);
1416 scm_ra2contig (SCM ra
, int copy
)
1421 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
1422 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1423 k
= SCM_ARRAY_NDIM (ra
);
1424 if (SCM_ARRAY_CONTP (ra
) && ((0 == k
) || (1 == SCM_ARRAY_DIMS (ra
)[k
- 1].inc
)))
1426 if (scm_tc7_bvect
!= SCM_TYP7 (SCM_ARRAY_V (ra
)))
1428 if ((len
== SCM_BITVECTOR_LENGTH (SCM_ARRAY_V (ra
)) &&
1429 0 == SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
&&
1430 0 == len
% SCM_LONG_BIT
))
1433 ret
= scm_make_ra (k
);
1434 SCM_ARRAY_BASE (ret
) = 0;
1437 SCM_ARRAY_DIMS (ret
)[k
].lbnd
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
;
1438 SCM_ARRAY_DIMS (ret
)[k
].ubnd
= SCM_ARRAY_DIMS (ra
)[k
].ubnd
;
1439 SCM_ARRAY_DIMS (ret
)[k
].inc
= inc
;
1440 inc
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1442 SCM_ARRAY_V (ret
) = scm_make_uve (inc
, scm_array_prototype (ra
));
1444 scm_array_copy_x (ra
, ret
);
1450 SCM_DEFINE (scm_uniform_array_read_x
, "uniform-array-read!", 1, 3, 0,
1451 (SCM ra
, SCM port_or_fd
, SCM start
, SCM end
),
1452 "@deffnx {Scheme Procedure} uniform-vector-read! uve [port-or-fdes] [start] [end]\n"
1453 "Attempt to read all elements of @var{ura}, in lexicographic order, as\n"
1454 "binary objects from @var{port-or-fdes}.\n"
1455 "If an end of file is encountered,\n"
1456 "the objects up to that point are put into @var{ura}\n"
1457 "(starting at the beginning) and the remainder of the array is\n"
1459 "The optional arguments @var{start} and @var{end} allow\n"
1460 "a specified region of a vector (or linearized array) to be read,\n"
1461 "leaving the remainder of the vector unchanged.\n\n"
1462 "@code{uniform-array-read!} returns the number of objects read.\n"
1463 "@var{port-or-fdes} may be omitted, in which case it defaults to the value\n"
1464 "returned by @code{(current-input-port)}.")
1465 #define FUNC_NAME s_scm_uniform_array_read_x
1467 SCM cra
= SCM_UNDEFINED
, v
= ra
;
1474 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1475 if (SCM_UNBNDP (port_or_fd
))
1476 port_or_fd
= scm_cur_inp
;
1478 SCM_ASSERT (SCM_INUMP (port_or_fd
)
1479 || (SCM_OPINPORTP (port_or_fd
)),
1480 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1481 vlen
= (SCM_TYP7 (v
) == scm_tc7_smob
1483 : SCM_INUM (scm_uniform_vector_length (v
)));
1489 badarg1
:SCM_WRONG_TYPE_ARG (SCM_ARG1
, v
);
1491 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1492 cra
= scm_ra2contig (ra
, 0);
1493 cstart
+= SCM_ARRAY_BASE (cra
);
1494 vlen
= SCM_ARRAY_DIMS (cra
)->inc
*
1495 (SCM_ARRAY_DIMS (cra
)->ubnd
- SCM_ARRAY_DIMS (cra
)->lbnd
+ 1);
1496 v
= SCM_ARRAY_V (cra
);
1498 case scm_tc7_string
:
1499 base
= SCM_STRING_CHARS (v
);
1503 base
= (char *) SCM_BITVECTOR_BASE (v
);
1504 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1505 cstart
/= SCM_LONG_BIT
;
1508 case scm_tc7_byvect
:
1509 base
= (char *) SCM_UVECTOR_BASE (v
);
1514 base
= (char *) SCM_UVECTOR_BASE (v
);
1518 base
= (char *) SCM_UVECTOR_BASE (v
);
1519 sz
= sizeof (short);
1521 #if SCM_SIZEOF_LONG_LONG != 0
1522 case scm_tc7_llvect
:
1523 base
= (char *) SCM_UVECTOR_BASE (v
);
1524 sz
= sizeof (long long);
1528 base
= (char *) SCM_UVECTOR_BASE (v
);
1529 sz
= sizeof (float);
1532 base
= (char *) SCM_UVECTOR_BASE (v
);
1533 sz
= sizeof (double);
1536 base
= (char *) SCM_UVECTOR_BASE (v
);
1537 sz
= 2 * sizeof (double);
1542 if (!SCM_UNBNDP (start
))
1545 SCM_NUM2LONG (3, start
);
1547 if (offset
< 0 || offset
>= cend
)
1548 scm_out_of_range (FUNC_NAME
, start
);
1550 if (!SCM_UNBNDP (end
))
1553 SCM_NUM2LONG (4, end
);
1555 if (tend
<= offset
|| tend
> cend
)
1556 scm_out_of_range (FUNC_NAME
, end
);
1561 if (SCM_NIMP (port_or_fd
))
1563 scm_t_port
*pt
= SCM_PTAB_ENTRY (port_or_fd
);
1564 int remaining
= (cend
- offset
) * sz
;
1565 char *dest
= base
+ (cstart
+ offset
) * sz
;
1567 if (pt
->rw_active
== SCM_PORT_WRITE
)
1568 scm_flush (port_or_fd
);
1570 ans
= cend
- offset
;
1571 while (remaining
> 0)
1573 if (pt
->read_pos
< pt
->read_end
)
1575 int to_copy
= min (pt
->read_end
- pt
->read_pos
,
1578 memcpy (dest
, pt
->read_pos
, to_copy
);
1579 pt
->read_pos
+= to_copy
;
1580 remaining
-= to_copy
;
1585 if (scm_fill_input (port_or_fd
) == EOF
)
1587 if (remaining
% sz
!= 0)
1589 SCM_MISC_ERROR ("unexpected EOF", SCM_EOL
);
1591 ans
-= remaining
/ sz
;
1598 pt
->rw_active
= SCM_PORT_READ
;
1600 else /* file descriptor. */
1602 SCM_SYSCALL (ans
= read (SCM_INUM (port_or_fd
),
1603 base
+ (cstart
+ offset
) * sz
,
1604 (sz
* (cend
- offset
))));
1608 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1609 ans
*= SCM_LONG_BIT
;
1611 if (!SCM_EQ_P (v
, ra
) && !SCM_EQ_P (cra
, ra
))
1612 scm_array_copy_x (cra
, ra
);
1614 return SCM_MAKINUM (ans
);
1618 SCM_DEFINE (scm_uniform_array_write
, "uniform-array-write", 1, 3, 0,
1619 (SCM v
, SCM port_or_fd
, SCM start
, SCM end
),
1620 "@deffnx {Scheme Procedure} uniform-vector-write uve [port-or-fdes] [start] [end]\n"
1621 "Writes all elements of @var{ura} as binary objects to\n"
1622 "@var{port-or-fdes}.\n\n"
1623 "The optional arguments @var{start}\n"
1624 "and @var{end} allow\n"
1625 "a specified region of a vector (or linearized array) to be written.\n\n"
1626 "The number of objects actually written is returned.\n"
1627 "@var{port-or-fdes} may be\n"
1628 "omitted, in which case it defaults to the value returned by\n"
1629 "@code{(current-output-port)}.")
1630 #define FUNC_NAME s_scm_uniform_array_write
1638 port_or_fd
= SCM_COERCE_OUTPORT (port_or_fd
);
1640 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1641 if (SCM_UNBNDP (port_or_fd
))
1642 port_or_fd
= scm_cur_outp
;
1644 SCM_ASSERT (SCM_INUMP (port_or_fd
)
1645 || (SCM_OPOUTPORTP (port_or_fd
)),
1646 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1647 vlen
= (SCM_TYP7 (v
) == scm_tc7_smob
1649 : SCM_INUM (scm_uniform_vector_length (v
)));
1655 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
1657 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1658 v
= scm_ra2contig (v
, 1);
1659 cstart
= SCM_ARRAY_BASE (v
);
1660 vlen
= (SCM_ARRAY_DIMS (v
)->inc
1661 * (SCM_ARRAY_DIMS (v
)->ubnd
- SCM_ARRAY_DIMS (v
)->lbnd
+ 1));
1662 v
= SCM_ARRAY_V (v
);
1664 case scm_tc7_string
:
1665 base
= SCM_STRING_CHARS (v
);
1669 base
= (char *) SCM_BITVECTOR_BASE (v
);
1670 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1671 cstart
/= SCM_LONG_BIT
;
1674 case scm_tc7_byvect
:
1675 base
= (char *) SCM_UVECTOR_BASE (v
);
1680 base
= (char *) SCM_UVECTOR_BASE (v
);
1684 base
= (char *) SCM_UVECTOR_BASE (v
);
1685 sz
= sizeof (short);
1687 #if SCM_SIZEOF_LONG_LONG != 0
1688 case scm_tc7_llvect
:
1689 base
= (char *) SCM_UVECTOR_BASE (v
);
1690 sz
= sizeof (long long);
1694 base
= (char *) SCM_UVECTOR_BASE (v
);
1695 sz
= sizeof (float);
1698 base
= (char *) SCM_UVECTOR_BASE (v
);
1699 sz
= sizeof (double);
1702 base
= (char *) SCM_UVECTOR_BASE (v
);
1703 sz
= 2 * sizeof (double);
1708 if (!SCM_UNBNDP (start
))
1711 SCM_NUM2LONG (3, start
);
1713 if (offset
< 0 || offset
>= cend
)
1714 scm_out_of_range (FUNC_NAME
, start
);
1716 if (!SCM_UNBNDP (end
))
1719 SCM_NUM2LONG (4, end
);
1721 if (tend
<= offset
|| tend
> cend
)
1722 scm_out_of_range (FUNC_NAME
, end
);
1727 if (SCM_NIMP (port_or_fd
))
1729 char *source
= base
+ (cstart
+ offset
) * sz
;
1731 ans
= cend
- offset
;
1732 scm_lfwrite (source
, ans
* sz
, port_or_fd
);
1734 else /* file descriptor. */
1736 SCM_SYSCALL (ans
= write (SCM_INUM (port_or_fd
),
1737 base
+ (cstart
+ offset
) * sz
,
1738 (sz
* (cend
- offset
))));
1742 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1743 ans
*= SCM_LONG_BIT
;
1745 return SCM_MAKINUM (ans
);
1750 static char cnt_tab
[16] =
1751 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1753 SCM_DEFINE (scm_bit_count
, "bit-count", 2, 0, 0,
1754 (SCM b
, SCM bitvector
),
1755 "Return the number of occurrences of the boolean @var{b} in\n"
1757 #define FUNC_NAME s_scm_bit_count
1759 SCM_VALIDATE_BOOL (1, b
);
1760 SCM_ASSERT (SCM_BITVECTOR_P (bitvector
), bitvector
, 2, FUNC_NAME
);
1761 if (SCM_BITVECTOR_LENGTH (bitvector
) == 0) {
1764 unsigned long int count
= 0;
1765 unsigned long int i
= (SCM_BITVECTOR_LENGTH (bitvector
) - 1) / SCM_LONG_BIT
;
1766 unsigned long int w
= SCM_UNPACK (SCM_VELTS (bitvector
)[i
]);
1767 if (SCM_FALSEP (b
)) {
1770 w
<<= SCM_LONG_BIT
- 1 - ((SCM_BITVECTOR_LENGTH (bitvector
) - 1) % SCM_LONG_BIT
);
1773 count
+= cnt_tab
[w
& 0x0f];
1777 return SCM_MAKINUM (count
);
1780 w
= SCM_UNPACK (SCM_VELTS (bitvector
)[i
]);
1781 if (SCM_FALSEP (b
)) {
1791 SCM_DEFINE (scm_bit_position
, "bit-position", 3, 0, 0,
1792 (SCM item
, SCM v
, SCM k
),
1793 "Return the index of the first occurrance of @var{item} in bit\n"
1794 "vector @var{v}, starting from @var{k}. If there is no\n"
1795 "@var{item} entry between @var{k} and the end of\n"
1796 "@var{bitvector}, then return @code{#f}. For example,\n"
1799 "(bit-position #t #*000101 0) @result{} 3\n"
1800 "(bit-position #f #*0001111 3) @result{} #f\n"
1802 #define FUNC_NAME s_scm_bit_position
1804 long i
, lenw
, xbits
, pos
;
1805 register unsigned long w
;
1807 SCM_VALIDATE_BOOL (1, item
);
1808 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG2
, FUNC_NAME
);
1809 SCM_VALIDATE_INUM_COPY (3, k
, pos
);
1810 SCM_ASSERT_RANGE (3, k
, (pos
<= SCM_BITVECTOR_LENGTH (v
)) && (pos
>= 0));
1812 if (pos
== SCM_BITVECTOR_LENGTH (v
))
1815 lenw
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
; /* watch for part words */
1816 i
= pos
/ SCM_LONG_BIT
;
1817 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1818 if (SCM_FALSEP (item
))
1820 xbits
= (pos
% SCM_LONG_BIT
);
1822 w
= ((w
>> xbits
) << xbits
);
1823 xbits
= SCM_LONG_BIT
- 1 - (SCM_BITVECTOR_LENGTH (v
) - 1) % SCM_LONG_BIT
;
1826 if (w
&& (i
== lenw
))
1827 w
= ((w
<< xbits
) >> xbits
);
1833 return SCM_MAKINUM (pos
);
1838 return SCM_MAKINUM (pos
+ 1);
1841 return SCM_MAKINUM (pos
+ 2);
1843 return SCM_MAKINUM (pos
+ 3);
1850 pos
+= SCM_LONG_BIT
;
1851 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1852 if (SCM_FALSEP (item
))
1860 SCM_DEFINE (scm_bit_set_star_x
, "bit-set*!", 3, 0, 0,
1861 (SCM v
, SCM kv
, SCM obj
),
1862 "Set entries of bit vector @var{v} to @var{obj}, with @var{kv}\n"
1863 "selecting the entries to change. The return value is\n"
1866 "If @var{kv} is a bit vector, then those entries where it has\n"
1867 "@code{#t} are the ones in @var{v} which are set to @var{obj}.\n"
1868 "@var{kv} and @var{v} must be the same length. When @var{obj}\n"
1869 "is @code{#t} it's like @var{kv} is OR'ed into @var{v}. Or when\n"
1870 "@var{obj} is @code{#f} it can be seen as an ANDNOT.\n"
1873 "(define bv #*01000010)\n"
1874 "(bit-set*! bv #*10010001 #t)\n"
1876 "@result{} #*11010011\n"
1879 "If @var{kv} is a uniform vector of unsigned long integers, then\n"
1880 "they're indexes into @var{v} which are set to @var{obj}.\n"
1883 "(define bv #*01000010)\n"
1884 "(bit-set*! bv #u(5 2 7) #t)\n"
1886 "@result{} #*01100111\n"
1888 #define FUNC_NAME s_scm_bit_set_star_x
1890 register long i
, k
, vlen
;
1891 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
1892 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1893 switch SCM_TYP7 (kv
)
1896 badarg2
:SCM_WRONG_TYPE_ARG (2, kv
);
1898 vlen
= SCM_BITVECTOR_LENGTH (v
);
1899 if (SCM_FALSEP (obj
))
1900 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1902 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1904 scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (k
));
1905 SCM_BITVEC_CLR(v
, k
);
1907 else if (SCM_EQ_P (obj
, SCM_BOOL_T
))
1908 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1910 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1912 scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (k
));
1913 SCM_BITVEC_SET(v
, k
);
1916 badarg3
:SCM_WRONG_TYPE_ARG (3, obj
);
1919 SCM_ASSERT (SCM_BITVECTOR_LENGTH (v
) == SCM_BITVECTOR_LENGTH (kv
), v
, SCM_ARG1
, FUNC_NAME
);
1920 if (SCM_FALSEP (obj
))
1921 for (k
= (SCM_BITVECTOR_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1922 SCM_BITVECTOR_BASE (v
) [k
] &= ~SCM_BITVECTOR_BASE (kv
) [k
];
1923 else if (SCM_EQ_P (obj
, SCM_BOOL_T
))
1924 for (k
= (SCM_BITVECTOR_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1925 SCM_BITVECTOR_BASE (v
) [k
] |= SCM_BITVECTOR_BASE (kv
) [k
];
1930 return SCM_UNSPECIFIED
;
1935 SCM_DEFINE (scm_bit_count_star
, "bit-count*", 3, 0, 0,
1936 (SCM v
, SCM kv
, SCM obj
),
1937 "Return a count of how many entries in bit vector @var{v} are\n"
1938 "equal to @var{obj}, with @var{kv} selecting the entries to\n"
1941 "If @var{kv} is a bit vector, then those entries where it has\n"
1942 "@code{#t} are the ones in @var{v} which are considered.\n"
1943 "@var{kv} and @var{v} must be the same length.\n"
1945 "If @var{kv} is a uniform vector of unsigned long integers, then\n"
1946 "it's the indexes in @var{v} to consider.\n"
1951 "(bit-count* #*01110111 #*11001101 #t) @result{} 3\n"
1952 "(bit-count* #*01110111 #u(7 0 4) #f) @result{} 2\n"
1954 #define FUNC_NAME s_scm_bit_count_star
1956 register long i
, vlen
, count
= 0;
1957 register unsigned long k
;
1960 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
1961 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1962 switch SCM_TYP7 (kv
)
1966 SCM_WRONG_TYPE_ARG (2, kv
);
1968 vlen
= SCM_BITVECTOR_LENGTH (v
);
1969 if (SCM_FALSEP (obj
))
1970 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1972 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1974 scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (k
));
1975 if (!SCM_BITVEC_REF(v
, k
))
1978 else if (SCM_EQ_P (obj
, SCM_BOOL_T
))
1979 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1981 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1983 scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (k
));
1984 if (SCM_BITVEC_REF (v
, k
))
1988 badarg3
:SCM_WRONG_TYPE_ARG (3, obj
);
1991 SCM_ASSERT (SCM_BITVECTOR_LENGTH (v
) == SCM_BITVECTOR_LENGTH (kv
), v
, SCM_ARG1
, FUNC_NAME
);
1992 if (0 == SCM_BITVECTOR_LENGTH (v
))
1994 SCM_ASRTGO (SCM_BOOLP (obj
), badarg3
);
1995 fObj
= SCM_EQ_P (obj
, SCM_BOOL_T
);
1996 i
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
;
1997 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK (SCM_VELTS (v
)[i
]) : ~ SCM_UNPACK (SCM_VELTS (v
)[i
]));
1998 k
<<= SCM_LONG_BIT
- 1 - ((SCM_BITVECTOR_LENGTH (v
) - 1) % SCM_LONG_BIT
);
2002 count
+= cnt_tab
[k
& 0x0f];
2004 return SCM_MAKINUM (count
);
2006 /* urg. repetitive (see above.) */
2007 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK(SCM_VELTS (v
)[i
]) : ~SCM_UNPACK (SCM_VELTS (v
)[i
]));
2010 return SCM_MAKINUM (count
);
2015 SCM_DEFINE (scm_bit_invert_x
, "bit-invert!", 1, 0, 0,
2017 "Modify the bit vector @var{v} by replacing each element with\n"
2019 #define FUNC_NAME s_scm_bit_invert_x
2023 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
2025 k
= SCM_BITVECTOR_LENGTH (v
);
2026 for (k
= (k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
2027 SCM_BITVECTOR_BASE (v
) [k
] = ~SCM_BITVECTOR_BASE (v
) [k
];
2029 return SCM_UNSPECIFIED
;
2035 scm_istr2bve (char *str
, long len
)
2037 SCM v
= scm_make_uve (len
, SCM_BOOL_T
);
2038 long *data
= (long *) SCM_VELTS (v
);
2039 register unsigned long mask
;
2042 for (k
= 0; k
< (len
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
++)
2045 j
= len
- k
* SCM_LONG_BIT
;
2046 if (j
> SCM_LONG_BIT
)
2048 for (mask
= 1L; j
--; mask
<<= 1)
2066 ra2l (SCM ra
, unsigned long base
, unsigned long k
)
2068 register SCM res
= SCM_EOL
;
2069 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2071 if (SCM_ARRAY_DIMS (ra
)[k
].ubnd
< SCM_ARRAY_DIMS (ra
)[k
].lbnd
)
2073 i
= base
+ (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
) * inc
;
2074 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2079 res
= scm_cons (ra2l (ra
, i
, k
+ 1), res
);
2087 res
= scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra
), SCM_MAKINUM (i
)), res
);
2094 SCM_DEFINE (scm_array_to_list
, "array->list", 1, 0, 0,
2096 "Return a list consisting of all the elements, in order, of\n"
2098 #define FUNC_NAME s_scm_array_to_list
2102 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
2106 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
2108 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
2109 return ra2l (v
, SCM_ARRAY_BASE (v
), 0);
2110 case scm_tc7_vector
:
2112 return scm_vector_to_list (v
);
2113 case scm_tc7_string
:
2114 return scm_string_to_list (v
);
2117 long *data
= (long *) SCM_VELTS (v
);
2118 register unsigned long mask
;
2119 for (k
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
; k
> 0; k
--)
2120 for (mask
= 1UL << (SCM_LONG_BIT
- 1); mask
; mask
>>= 1)
2121 res
= scm_cons (SCM_BOOL(((long *) data
)[k
] & mask
), res
);
2122 for (mask
= 1L << ((SCM_BITVECTOR_LENGTH (v
) % SCM_LONG_BIT
) - 1); mask
; mask
>>= 1)
2123 res
= scm_cons (SCM_BOOL(((long *) data
)[k
] & mask
), res
);
2126 case scm_tc7_byvect
:
2128 signed char *data
= (signed char *) SCM_VELTS (v
);
2129 unsigned long k
= SCM_UVECTOR_LENGTH (v
);
2131 res
= scm_cons (SCM_MAKINUM (data
[--k
]), res
);
2136 long *data
= (long *)SCM_VELTS(v
);
2137 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2138 res
= scm_cons(scm_ulong2num(data
[k
]), res
);
2143 long *data
= (long *)SCM_VELTS(v
);
2144 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2145 res
= scm_cons(scm_long2num(data
[k
]), res
);
2150 short *data
= (short *)SCM_VELTS(v
);
2151 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2152 res
= scm_cons(scm_short2num (data
[k
]), res
);
2155 #if SCM_SIZEOF_LONG_LONG != 0
2156 case scm_tc7_llvect
:
2158 long long *data
= (long long *)SCM_VELTS(v
);
2159 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2160 res
= scm_cons(scm_long_long2num(data
[k
]), res
);
2166 float *data
= (float *) SCM_VELTS (v
);
2167 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2168 res
= scm_cons (scm_make_real (data
[k
]), res
);
2173 double *data
= (double *) SCM_VELTS (v
);
2174 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2175 res
= scm_cons (scm_make_real (data
[k
]), res
);
2180 double (*data
)[2] = (double (*)[2]) SCM_VELTS (v
);
2181 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2182 res
= scm_cons (scm_make_complex (data
[k
][0], data
[k
][1]), res
);
2190 static int l2ra(SCM lst
, SCM ra
, unsigned long base
, unsigned long k
);
2192 SCM_DEFINE (scm_list_to_uniform_array
, "list->uniform-array", 3, 0, 0,
2193 (SCM ndim
, SCM prot
, SCM lst
),
2194 "@deffnx {Scheme Procedure} list->uniform-vector prot lst\n"
2195 "Return a uniform array of the type indicated by prototype\n"
2196 "@var{prot} with elements the same as those of @var{lst}.\n"
2197 "Elements must be of the appropriate type, no coercions are\n"
2199 #define FUNC_NAME s_scm_list_to_uniform_array
2206 SCM_VALIDATE_INUM_COPY (1, ndim
, k
);
2209 n
= scm_ilength (row
);
2210 SCM_ASSERT (n
>= 0, lst
, SCM_ARG3
, FUNC_NAME
);
2211 shp
= scm_cons (SCM_MAKINUM (n
), shp
);
2213 row
= SCM_CAR (row
);
2215 ra
= scm_dimensions_to_uniform_array (scm_reverse (shp
), prot
,
2217 if (SCM_NULLP (shp
))
2219 SCM_ASRTGO (1 == scm_ilength (lst
), badlst
);
2220 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_EOL
);
2223 if (!SCM_ARRAYP (ra
))
2225 unsigned long int length
= SCM_INUM (scm_uniform_vector_length (ra
));
2226 for (k
= 0; k
< length
; k
++, lst
= SCM_CDR (lst
))
2227 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_MAKINUM (k
));
2230 if (l2ra (lst
, ra
, SCM_ARRAY_BASE (ra
), 0))
2233 badlst
:SCM_MISC_ERROR ("Bad scm_array contents list: ~S",
2239 l2ra (SCM lst
, SCM ra
, unsigned long base
, unsigned long k
)
2241 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2242 register long n
= (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
);
2245 return (SCM_NULLP (lst
));
2246 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2250 if (!SCM_CONSP (lst
))
2252 ok
= ok
&& l2ra (SCM_CAR (lst
), ra
, base
, k
+ 1);
2254 lst
= SCM_CDR (lst
);
2256 if (!SCM_NULLP (lst
))
2263 if (!SCM_CONSP (lst
))
2265 scm_array_set_x (SCM_ARRAY_V (ra
), SCM_CAR (lst
), SCM_MAKINUM (base
));
2267 lst
= SCM_CDR (lst
);
2269 if (!SCM_NULLP (lst
))
2277 rapr1 (SCM ra
, unsigned long j
, unsigned long k
, SCM port
, scm_print_state
*pstate
)
2280 long n
= (SCM_TYP7 (ra
) == scm_tc7_smob
2282 : SCM_INUM (scm_uniform_vector_length (ra
)));
2285 switch SCM_TYP7 (ra
)
2290 SCM_ARRAY_BASE (ra
) = j
;
2292 scm_iprin1 (ra
, port
, pstate
);
2293 for (j
+= inc
; n
-- > 0; j
+= inc
)
2295 scm_putc (' ', port
);
2296 SCM_ARRAY_BASE (ra
) = j
;
2297 scm_iprin1 (ra
, port
, pstate
);
2301 if (k
+ 1 < SCM_ARRAY_NDIM (ra
))
2304 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2305 for (i
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
; i
< SCM_ARRAY_DIMS (ra
)[k
].ubnd
; i
++)
2307 scm_putc ('(', port
);
2308 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2309 scm_puts (") ", port
);
2312 if (i
== SCM_ARRAY_DIMS (ra
)[k
].ubnd
)
2313 { /* could be zero size. */
2314 scm_putc ('(', port
);
2315 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2316 scm_putc (')', port
);
2320 if (SCM_ARRAY_NDIM (ra
) > 0)
2321 { /* Could be zero-dimensional */
2322 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2323 n
= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
2327 ra
= SCM_ARRAY_V (ra
);
2330 /* scm_tc7_bvect and scm_tc7_llvect only? */
2332 scm_iprin1 (scm_uniform_vector_ref (ra
, SCM_MAKINUM (j
)), port
, pstate
);
2333 for (j
+= inc
; n
-- > 0; j
+= inc
)
2335 scm_putc (' ', port
);
2336 scm_iprin1 (scm_cvref (ra
, j
, SCM_UNDEFINED
), port
, pstate
);
2339 case scm_tc7_string
:
2341 scm_iprin1 (SCM_MAKE_CHAR (SCM_STRING_UCHARS (ra
)[j
]), port
, pstate
);
2342 if (SCM_WRITINGP (pstate
))
2343 for (j
+= inc
; n
-- > 0; j
+= inc
)
2345 scm_putc (' ', port
);
2346 scm_iprin1 (SCM_MAKE_CHAR (SCM_STRING_UCHARS (ra
)[j
]), port
, pstate
);
2349 for (j
+= inc
; n
-- > 0; j
+= inc
)
2350 scm_putc (SCM_STRING_CHARS (ra
)[j
], port
);
2352 case scm_tc7_byvect
:
2354 scm_intprint (((char *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2355 for (j
+= inc
; n
-- > 0; j
+= inc
)
2357 scm_putc (' ', port
);
2358 scm_intprint (((char *)SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2368 /* intprint can't handle >= 2^31. */
2369 sprintf (str
, "%lu", ((unsigned long *) SCM_VELTS (ra
))[j
]);
2370 scm_puts (str
, port
);
2372 for (j
+= inc
; n
-- > 0; j
+= inc
)
2374 scm_putc (' ', port
);
2375 sprintf (str
, "%lu", ((unsigned long *) SCM_VELTS (ra
))[j
]);
2376 scm_puts (str
, port
);
2381 scm_intprint (((signed long *) SCM_VELTS (ra
))[j
], 10, port
);
2382 for (j
+= inc
; n
-- > 0; j
+= inc
)
2384 scm_putc (' ', port
);
2385 scm_intprint (((signed long *) SCM_VELTS (ra
))[j
], 10, port
);
2391 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2392 for (j
+= inc
; n
-- > 0; j
+= inc
)
2394 scm_putc (' ', port
);
2395 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2402 SCM z
= scm_make_real (1.0);
2403 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2404 scm_print_real (z
, port
, pstate
);
2405 for (j
+= inc
; n
-- > 0; j
+= inc
)
2407 scm_putc (' ', port
);
2408 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2409 scm_print_real (z
, port
, pstate
);
2416 SCM z
= scm_make_real (1.0 / 3.0);
2417 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2418 scm_print_real (z
, port
, pstate
);
2419 for (j
+= inc
; n
-- > 0; j
+= inc
)
2421 scm_putc (' ', port
);
2422 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2423 scm_print_real (z
, port
, pstate
);
2430 SCM cz
= scm_make_complex (0.0, 1.0), z
= scm_make_real (1.0 / 3.0);
2431 SCM_REAL_VALUE (z
) =
2432 SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2433 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2434 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2436 for (j
+= inc
; n
-- > 0; j
+= inc
)
2438 scm_putc (' ', port
);
2440 = SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2441 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2442 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2453 scm_raprin1 (SCM exp
, SCM port
, scm_print_state
*pstate
)
2456 unsigned long base
= 0;
2457 scm_putc ('#', port
);
2463 long ndim
= SCM_ARRAY_NDIM (v
);
2464 base
= SCM_ARRAY_BASE (v
);
2465 v
= SCM_ARRAY_V (v
);
2469 scm_puts ("<enclosed-array ", port
);
2470 rapr1 (exp
, base
, 0, port
, pstate
);
2471 scm_putc ('>', port
);
2476 scm_intprint (ndim
, 10, port
);
2481 if (SCM_EQ_P (exp
, v
))
2482 { /* a uve, not an scm_array */
2483 register long i
, j
, w
;
2484 scm_putc ('*', port
);
2485 for (i
= 0; i
< (SCM_BITVECTOR_LENGTH (exp
)) / SCM_LONG_BIT
; i
++)
2487 scm_t_bits w
= SCM_UNPACK (SCM_VELTS (exp
)[i
]);
2488 for (j
= SCM_LONG_BIT
; j
; j
--)
2490 scm_putc (w
& 1 ? '1' : '0', port
);
2494 j
= SCM_BITVECTOR_LENGTH (exp
) % SCM_LONG_BIT
;
2497 w
= SCM_UNPACK (SCM_VELTS (exp
)[SCM_BITVECTOR_LENGTH (exp
) / SCM_LONG_BIT
]);
2500 scm_putc (w
& 1 ? '1' : '0', port
);
2507 scm_putc ('b', port
);
2509 case scm_tc7_string
:
2510 scm_putc ('a', port
);
2512 case scm_tc7_byvect
:
2513 scm_putc ('y', port
);
2516 scm_putc ('u', port
);
2519 scm_putc ('e', port
);
2522 scm_putc ('h', port
);
2524 #if SCM_SIZEOF_LONG_LONG != 0
2525 case scm_tc7_llvect
:
2526 scm_putc ('l', port
);
2530 scm_putc ('s', port
);
2533 scm_putc ('i', port
);
2536 scm_putc ('c', port
);
2539 scm_putc ('(', port
);
2540 rapr1 (exp
, base
, 0, port
, pstate
);
2541 scm_putc (')', port
);
2545 SCM_DEFINE (scm_array_prototype
, "array-prototype", 1, 0, 0,
2547 "Return an object that would produce an array of the same type\n"
2548 "as @var{array}, if used as the @var{prototype} for\n"
2549 "@code{make-uniform-array}.")
2550 #define FUNC_NAME s_scm_array_prototype
2553 SCM_ASRTGO (SCM_NIMP (ra
), badarg
);
2555 switch SCM_TYP7 (ra
)
2558 badarg
:SCM_WRONG_TYPE_ARG (1, ra
);
2560 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
2562 return SCM_UNSPECIFIED
;
2563 ra
= SCM_ARRAY_V (ra
);
2565 case scm_tc7_vector
:
2570 case scm_tc7_string
:
2571 return SCM_MAKE_CHAR ('a');
2572 case scm_tc7_byvect
:
2573 return SCM_MAKE_CHAR ('\0');
2575 return SCM_MAKINUM (1L);
2577 return SCM_MAKINUM (-1L);
2579 return scm_str2symbol ("s");
2580 #if SCM_SIZEOF_LONG_LONG != 0
2581 case scm_tc7_llvect
:
2582 return scm_str2symbol ("l");
2585 return scm_make_real (1.0);
2587 return exactly_one_third
;
2589 return scm_make_complex (0.0, 1.0);
2596 array_mark (SCM ptr
)
2598 return SCM_ARRAY_V (ptr
);
2603 array_free (SCM ptr
)
2605 scm_gc_free (SCM_ARRAY_MEM (ptr
),
2606 (sizeof (scm_t_array
)
2607 + SCM_ARRAY_NDIM (ptr
) * sizeof (scm_t_array_dim
)),
2615 scm_tc16_array
= scm_make_smob_type ("array", 0);
2616 scm_set_smob_mark (scm_tc16_array
, array_mark
);
2617 scm_set_smob_free (scm_tc16_array
, array_free
);
2618 scm_set_smob_print (scm_tc16_array
, scm_raprin1
);
2619 scm_set_smob_equalp (scm_tc16_array
, scm_array_equal_p
);
2620 exactly_one_third
= scm_permanent_object (scm_make_ratio (SCM_MAKINUM (1),
2622 scm_add_feature ("array");
2623 #include "libguile/unif.x"