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/feature.h"
42 #include "libguile/root.h"
43 #include "libguile/strings.h"
44 #include "libguile/srfi-13.h"
45 #include "libguile/vectors.h"
47 #include "libguile/validate.h"
48 #include "libguile/unif.h"
49 #include "libguile/ramap.h"
50 #include "libguile/print.h"
61 /* The set of uniform scm_vector types is:
63 * unsigned char string
70 * complex double cvect
75 scm_t_bits scm_tc16_array
;
76 static SCM exactly_one_third
;
78 /* return the size of an element in a uniform array or 0 if type not
81 scm_uniform_element_size (SCM obj
)
85 switch (SCM_TYP7 (obj
))
90 result
= sizeof (long);
94 result
= sizeof (char);
98 result
= sizeof (short);
101 #if SCM_SIZEOF_LONG_LONG != 0
103 result
= sizeof (long long);
108 result
= sizeof (float);
112 result
= sizeof (double);
116 result
= 2 * sizeof (double);
125 /* Silly function used not to modify the semantics of the silly
126 * prototype system in order to be backward compatible.
131 if (!SCM_REALP (obj
))
135 double x
= SCM_REAL_VALUE (obj
);
137 return (- SCM_FLTMAX
< x
) && (x
< SCM_FLTMAX
) && (fx
== x
);
142 make_uve (long type
, long k
, size_t size
)
143 #define FUNC_NAME "scm_make_uve"
145 SCM_ASSERT_RANGE (1, scm_from_long (k
), k
<= SCM_UVECTOR_MAX_LENGTH
);
147 return scm_cell (SCM_MAKE_UVECTOR_TAG (k
, type
),
148 (scm_t_bits
) scm_gc_malloc (k
* size
, "vector"));
153 scm_make_uve (long k
, SCM prot
)
154 #define FUNC_NAME "scm_make_uve"
156 if (scm_is_eq (prot
, SCM_BOOL_T
))
161 SCM_ASSERT_RANGE (1, scm_from_long (k
),
162 k
<= SCM_BITVECTOR_MAX_LENGTH
);
163 i
= sizeof (long) * ((k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
);
164 return scm_cell (SCM_MAKE_BITVECTOR_TAG (k
),
165 (scm_t_bits
) scm_gc_malloc (i
, "vector"));
168 return scm_cell (SCM_MAKE_BITVECTOR_TAG (0), 0);
170 else if (SCM_CHARP (prot
) && (SCM_CHAR (prot
) == '\0'))
171 return make_uve (scm_tc7_byvect
, k
, sizeof (char));
172 else if (SCM_CHARP (prot
))
173 return scm_c_make_string (sizeof (char) * k
, SCM_UNDEFINED
);
174 else if (SCM_I_INUMP (prot
))
175 return make_uve (SCM_I_INUM (prot
) > 0 ? scm_tc7_uvect
: scm_tc7_ivect
,
178 else if (SCM_FRACTIONP (prot
))
180 if (scm_num_eq_p (exactly_one_third
, prot
))
183 else if (scm_is_symbol (prot
) && (1 == scm_i_symbol_length (prot
)))
187 s
= scm_i_symbol_chars (prot
)[0];
189 return make_uve (scm_tc7_svect
, k
, sizeof (short));
190 #if SCM_SIZEOF_LONG_LONG != 0
192 return make_uve (scm_tc7_llvect
, k
, sizeof (long long));
195 return scm_c_make_vector (k
, SCM_UNDEFINED
);
197 else if (!SCM_INEXACTP (prot
))
198 /* Huge non-unif vectors are NOT supported. */
199 /* no special scm_vector */
200 return scm_c_make_vector (k
, SCM_UNDEFINED
);
201 else if (singp (prot
))
202 return make_uve (scm_tc7_fvect
, k
, sizeof (float));
203 else if (SCM_COMPLEXP (prot
))
204 return make_uve (scm_tc7_cvect
, k
, 2 * sizeof (double));
206 return make_uve (scm_tc7_dvect
, k
, sizeof (double));
210 SCM_DEFINE (scm_uniform_vector_length
, "uniform-vector-length", 1, 0, 0,
212 "Return the number of elements in @var{uve}.")
213 #define FUNC_NAME s_scm_uniform_vector_length
215 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
219 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
222 return scm_from_size_t (SCM_VECTOR_LENGTH (v
));
224 return scm_from_size_t (scm_i_string_length (v
));
226 return scm_from_size_t (SCM_BITVECTOR_LENGTH (v
));
234 #if SCM_SIZEOF_LONG_LONG != 0
237 return scm_from_size_t (SCM_UVECTOR_LENGTH (v
));
242 SCM_DEFINE (scm_array_p
, "array?", 1, 1, 0,
244 "Return @code{#t} if the @var{obj} is an array, and @code{#f} if\n"
245 "not. The @var{prototype} argument is used with uniform arrays\n"
246 "and is described elsewhere.")
247 #define FUNC_NAME s_scm_array_p
251 nprot
= SCM_UNBNDP (prot
);
256 while (SCM_TYP7 (v
) == scm_tc7_smob
)
269 switch (SCM_TYP7 (v
))
277 #if SCM_SIZEOF_LONG_LONG != 0
294 switch (SCM_TYP7 (v
))
297 protp
= (scm_is_eq (prot
, SCM_BOOL_T
));
300 protp
= SCM_CHARP(prot
) && (SCM_CHAR (prot
) != '\0');
303 protp
= scm_is_eq (prot
, SCM_MAKE_CHAR ('\0'));
306 protp
= SCM_I_INUMP(prot
) && SCM_I_INUM(prot
)>0;
309 protp
= SCM_I_INUMP(prot
) && SCM_I_INUM(prot
)<=0;
312 protp
= scm_is_symbol (prot
)
313 && (1 == scm_i_symbol_length (prot
))
314 && ('s' == scm_i_symbol_chars (prot
)[0]);
316 #if SCM_SIZEOF_LONG_LONG != 0
318 protp
= scm_is_symbol (prot
)
319 && (1 == scm_i_symbol_length (prot
))
320 && ('l' == scm_i_symbol_chars (prot
)[0]);
324 protp
= singp (prot
);
327 protp
= ((SCM_REALP(prot
) && ! singp (prot
))
328 || (SCM_FRACTIONP (prot
)
329 && scm_num_eq_p (exactly_one_third
, prot
)));
332 protp
= SCM_COMPLEXP(prot
);
336 protp
= scm_is_null(prot
);
342 return scm_from_bool(protp
);
348 SCM_DEFINE (scm_array_rank
, "array-rank", 1, 0, 0,
350 "Return the number of dimensions of @var{obj}. If @var{obj} is\n"
351 "not an array, @code{0} is returned.")
352 #define FUNC_NAME s_scm_array_rank
356 switch (SCM_TYP7 (ra
))
369 #if SCM_SIZEOF_LONG_LONG != 0
373 return scm_from_int (1);
376 return scm_from_size_t (SCM_ARRAY_NDIM (ra
));
383 SCM_DEFINE (scm_array_dimensions
, "array-dimensions", 1, 0, 0,
385 "@code{Array-dimensions} is similar to @code{array-shape} but replaces\n"
386 "elements with a @code{0} minimum with one greater than the maximum. So:\n"
388 "(array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5)\n"
390 #define FUNC_NAME s_scm_array_dimensions
397 switch (SCM_TYP7 (ra
))
412 #if SCM_SIZEOF_LONG_LONG != 0
415 return scm_cons (scm_uniform_vector_length (ra
), SCM_EOL
);
417 if (!SCM_ARRAYP (ra
))
419 k
= SCM_ARRAY_NDIM (ra
);
420 s
= SCM_ARRAY_DIMS (ra
);
422 res
= scm_cons (s
[k
].lbnd
423 ? scm_cons2 (scm_from_long (s
[k
].lbnd
),
424 scm_from_long (s
[k
].ubnd
),
426 : scm_from_long (1 + s
[k
].ubnd
),
434 SCM_DEFINE (scm_shared_array_root
, "shared-array-root", 1, 0, 0,
436 "Return the root vector of a shared array.")
437 #define FUNC_NAME s_scm_shared_array_root
439 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
440 return SCM_ARRAY_V (ra
);
445 SCM_DEFINE (scm_shared_array_offset
, "shared-array-offset", 1, 0, 0,
447 "Return the root vector index of the first element in the array.")
448 #define FUNC_NAME s_scm_shared_array_offset
450 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
451 return scm_from_int (SCM_ARRAY_BASE (ra
));
456 SCM_DEFINE (scm_shared_array_increments
, "shared-array-increments", 1, 0, 0,
458 "For each dimension, return the distance between elements in the root vector.")
459 #define FUNC_NAME s_scm_shared_array_increments
464 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
465 k
= SCM_ARRAY_NDIM (ra
);
466 s
= SCM_ARRAY_DIMS (ra
);
468 res
= scm_cons (scm_from_long (s
[k
].inc
), res
);
474 static char s_bad_ind
[] = "Bad scm_array index";
478 scm_aind (SCM ra
, SCM args
, const char *what
)
479 #define FUNC_NAME what
483 register unsigned long pos
= SCM_ARRAY_BASE (ra
);
484 register unsigned long k
= SCM_ARRAY_NDIM (ra
);
485 scm_t_array_dim
*s
= SCM_ARRAY_DIMS (ra
);
486 if (scm_is_integer (args
))
489 scm_error_num_args_subr (what
);
490 return pos
+ (scm_to_long (args
) - s
->lbnd
) * (s
->inc
);
492 while (k
&& scm_is_pair (args
))
494 ind
= SCM_CAR (args
);
495 args
= SCM_CDR (args
);
496 if (!scm_is_integer (ind
))
497 scm_misc_error (what
, s_bad_ind
, SCM_EOL
);
498 j
= scm_to_long (ind
);
499 if (j
< s
->lbnd
|| j
> s
->ubnd
)
500 scm_out_of_range (what
, ind
);
501 pos
+= (j
- s
->lbnd
) * (s
->inc
);
505 if (k
!= 0 || !scm_is_null (args
))
506 scm_error_num_args_subr (what
);
514 scm_make_ra (int ndim
)
518 SCM_NEWSMOB(ra
, ((scm_t_bits
) ndim
<< 17) + scm_tc16_array
,
519 scm_gc_malloc ((sizeof (scm_t_array
) +
520 ndim
* sizeof (scm_t_array_dim
)),
522 SCM_ARRAY_V (ra
) = scm_nullvect
;
527 static char s_bad_spec
[] = "Bad scm_array dimension";
528 /* Increments will still need to be set. */
532 scm_shap2ra (SCM args
, const char *what
)
536 int ndim
= scm_ilength (args
);
538 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
540 ra
= scm_make_ra (ndim
);
541 SCM_ARRAY_BASE (ra
) = 0;
542 s
= SCM_ARRAY_DIMS (ra
);
543 for (; !scm_is_null (args
); s
++, args
= SCM_CDR (args
))
545 spec
= SCM_CAR (args
);
546 if (scm_is_integer (spec
))
548 if (scm_to_long (spec
) < 0)
549 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
551 s
->ubnd
= scm_to_long (spec
) - 1;
556 if (!scm_is_pair (spec
) || !scm_is_integer (SCM_CAR (spec
)))
557 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
558 s
->lbnd
= scm_to_long (SCM_CAR (spec
));
560 if (!scm_is_pair (sp
)
561 || !scm_is_integer (SCM_CAR (sp
))
562 || !scm_is_null (SCM_CDR (sp
)))
563 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
564 s
->ubnd
= scm_to_long (SCM_CAR (sp
));
571 SCM_DEFINE (scm_dimensions_to_uniform_array
, "dimensions->uniform-array", 2, 1, 0,
572 (SCM dims
, SCM prot
, SCM fill
),
573 "@deffnx {Scheme Procedure} make-uniform-vector length prototype [fill]\n"
574 "Create and return a uniform array or vector of type\n"
575 "corresponding to @var{prototype} with dimensions @var{dims} or\n"
576 "length @var{length}. If @var{fill} is supplied, it's used to\n"
577 "fill the array, otherwise @var{prototype} is used.")
578 #define FUNC_NAME s_scm_dimensions_to_uniform_array
581 unsigned long rlen
= 1;
585 if (scm_is_integer (dims
))
587 SCM answer
= scm_make_uve (scm_to_long (dims
), prot
);
588 if (!SCM_UNBNDP (fill
))
589 scm_array_fill_x (answer
, fill
);
590 else if (scm_is_symbol (prot
))
591 scm_array_fill_x (answer
, scm_from_int (0));
593 scm_array_fill_x (answer
, prot
);
597 SCM_ASSERT (scm_is_null (dims
) || scm_is_pair (dims
),
598 dims
, SCM_ARG1
, FUNC_NAME
);
599 ra
= scm_shap2ra (dims
, FUNC_NAME
);
600 SCM_SET_ARRAY_CONTIGUOUS_FLAG (ra
);
601 s
= SCM_ARRAY_DIMS (ra
);
602 k
= SCM_ARRAY_NDIM (ra
);
607 SCM_ASSERT_RANGE (1, dims
, s
[k
].lbnd
<= s
[k
].ubnd
);
608 rlen
= (s
[k
].ubnd
- s
[k
].lbnd
+ 1) * s
[k
].inc
;
611 SCM_ARRAY_V (ra
) = scm_make_uve (rlen
, prot
);
613 if (!SCM_UNBNDP (fill
))
614 scm_array_fill_x (ra
, fill
);
615 else if (scm_is_symbol (prot
))
616 scm_array_fill_x (ra
, scm_from_int (0));
618 scm_array_fill_x (ra
, prot
);
620 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
621 if (s
->ubnd
< s
->lbnd
|| (0 == s
->lbnd
&& 1 == s
->inc
))
622 return SCM_ARRAY_V (ra
);
629 scm_ra_set_contp (SCM ra
)
631 size_t k
= SCM_ARRAY_NDIM (ra
);
634 long inc
= SCM_ARRAY_DIMS (ra
)[k
- 1].inc
;
637 if (inc
!= SCM_ARRAY_DIMS (ra
)[k
].inc
)
639 SCM_CLR_ARRAY_CONTIGUOUS_FLAG (ra
);
642 inc
*= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
643 - SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
646 SCM_SET_ARRAY_CONTIGUOUS_FLAG (ra
);
650 SCM_DEFINE (scm_make_shared_array
, "make-shared-array", 2, 0, 1,
651 (SCM oldra
, SCM mapfunc
, SCM dims
),
652 "@code{make-shared-array} can be used to create shared subarrays of other\n"
653 "arrays. The @var{mapper} is a function that translates coordinates in\n"
654 "the new array into coordinates in the old array. A @var{mapper} must be\n"
655 "linear, and its range must stay within the bounds of the old array, but\n"
656 "it can be otherwise arbitrary. A simple example:\n"
658 "(define fred (make-array #f 8 8))\n"
659 "(define freds-diagonal\n"
660 " (make-shared-array fred (lambda (i) (list i i)) 8))\n"
661 "(array-set! freds-diagonal 'foo 3)\n"
662 "(array-ref fred 3 3) @result{} foo\n"
663 "(define freds-center\n"
664 " (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))\n"
665 "(array-ref freds-center 0 0) @result{} foo\n"
667 #define FUNC_NAME s_scm_make_shared_array
673 long old_min
, new_min
, old_max
, new_max
;
676 SCM_VALIDATE_REST_ARGUMENT (dims
);
677 SCM_VALIDATE_ARRAY (1, oldra
);
678 SCM_VALIDATE_PROC (2, mapfunc
);
679 ra
= scm_shap2ra (dims
, FUNC_NAME
);
680 if (SCM_ARRAYP (oldra
))
682 SCM_ARRAY_V (ra
) = SCM_ARRAY_V (oldra
);
683 old_min
= old_max
= SCM_ARRAY_BASE (oldra
);
684 s
= SCM_ARRAY_DIMS (oldra
);
685 k
= SCM_ARRAY_NDIM (oldra
);
689 old_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
691 old_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
696 SCM_ARRAY_V (ra
) = oldra
;
698 old_max
= scm_to_long (scm_uniform_vector_length (oldra
)) - 1;
701 s
= SCM_ARRAY_DIMS (ra
);
702 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
704 inds
= scm_cons (scm_from_long (s
[k
].lbnd
), inds
);
705 if (s
[k
].ubnd
< s
[k
].lbnd
)
707 if (1 == SCM_ARRAY_NDIM (ra
))
708 ra
= scm_make_uve (0L, scm_array_prototype (ra
));
710 SCM_ARRAY_V (ra
) = scm_make_uve (0L, scm_array_prototype (ra
));
714 imap
= scm_apply_0 (mapfunc
, scm_reverse (inds
));
715 if (SCM_ARRAYP (oldra
))
716 i
= (size_t) scm_aind (oldra
, imap
, FUNC_NAME
);
719 if (!scm_is_integer (imap
))
721 if (scm_ilength (imap
) != 1 || !scm_is_integer (SCM_CAR (imap
)))
722 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
723 imap
= SCM_CAR (imap
);
725 i
= scm_to_size_t (imap
);
727 SCM_ARRAY_BASE (ra
) = new_min
= new_max
= i
;
729 k
= SCM_ARRAY_NDIM (ra
);
732 if (s
[k
].ubnd
> s
[k
].lbnd
)
734 SCM_SETCAR (indptr
, scm_sum (SCM_CAR (indptr
), scm_from_int (1)));
735 imap
= scm_apply_0 (mapfunc
, scm_reverse (inds
));
736 if (SCM_ARRAYP (oldra
))
738 s
[k
].inc
= scm_aind (oldra
, imap
, FUNC_NAME
) - i
;
741 if (!scm_is_integer (imap
))
743 if (scm_ilength (imap
) != 1 || !scm_is_integer (SCM_CAR (imap
)))
744 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
745 imap
= SCM_CAR (imap
);
747 s
[k
].inc
= scm_to_long (imap
) - i
;
751 new_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
753 new_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
756 s
[k
].inc
= new_max
- new_min
+ 1; /* contiguous by default */
757 indptr
= SCM_CDR (indptr
);
759 if (old_min
> new_min
|| old_max
< new_max
)
760 SCM_MISC_ERROR ("mapping out of range", SCM_EOL
);
761 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
763 SCM v
= SCM_ARRAY_V (ra
);
764 unsigned long int length
= scm_to_ulong (scm_uniform_vector_length (v
));
765 if (1 == s
->inc
&& 0 == s
->lbnd
&& length
== 1 + s
->ubnd
)
767 if (s
->ubnd
< s
->lbnd
)
768 return scm_make_uve (0L, scm_array_prototype (ra
));
770 scm_ra_set_contp (ra
);
776 /* args are RA . DIMS */
777 SCM_DEFINE (scm_transpose_array
, "transpose-array", 1, 0, 1,
779 "Return an array sharing contents with @var{array}, but with\n"
780 "dimensions arranged in a different order. There must be one\n"
781 "@var{dim} argument for each dimension of @var{array}.\n"
782 "@var{dim0}, @var{dim1}, @dots{} should be integers between 0\n"
783 "and the rank of the array to be returned. Each integer in that\n"
784 "range must appear at least once in the argument list.\n"
786 "The values of @var{dim0}, @var{dim1}, @dots{} correspond to\n"
787 "dimensions in the array to be returned, their positions in the\n"
788 "argument list to dimensions of @var{array}. Several @var{dim}s\n"
789 "may have the same value, in which case the returned array will\n"
790 "have smaller rank than @var{array}.\n"
793 "(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))\n"
794 "(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)\n"
795 "(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}\n"
796 " #2((a 4) (b 5) (c 6))\n"
798 #define FUNC_NAME s_scm_transpose_array
801 SCM
const *ve
= &vargs
;
802 scm_t_array_dim
*s
, *r
;
805 SCM_VALIDATE_REST_ARGUMENT (args
);
806 SCM_ASSERT (SCM_NIMP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
807 switch (SCM_TYP7 (ra
))
810 badarg
:SCM_WRONG_TYPE_ARG (1, ra
);
820 #if SCM_SIZEOF_LONG_LONG != 0
823 if (scm_is_null (args
) || !scm_is_null (SCM_CDR (args
)))
824 SCM_WRONG_NUM_ARGS ();
825 SCM_VALIDATE_INT_COPY (SCM_ARG2
, SCM_CAR (args
), i
);
826 SCM_ASSERT_RANGE (SCM_ARG2
, SCM_CAR (args
), i
== 0);
829 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
830 vargs
= scm_vector (args
);
831 if (SCM_VECTOR_LENGTH (vargs
) != SCM_ARRAY_NDIM (ra
))
832 SCM_WRONG_NUM_ARGS ();
833 ve
= SCM_VELTS (vargs
);
835 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
837 i
= scm_to_signed_integer (ve
[k
], 0, SCM_ARRAY_NDIM(ra
));
842 res
= scm_make_ra (ndim
);
843 SCM_ARRAY_V (res
) = SCM_ARRAY_V (ra
);
844 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra
);
847 SCM_ARRAY_DIMS (res
)[k
].lbnd
= 0;
848 SCM_ARRAY_DIMS (res
)[k
].ubnd
= -1;
850 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
852 i
= scm_to_int (ve
[k
]);
853 s
= &(SCM_ARRAY_DIMS (ra
)[k
]);
854 r
= &(SCM_ARRAY_DIMS (res
)[i
]);
855 if (r
->ubnd
< r
->lbnd
)
864 if (r
->ubnd
> s
->ubnd
)
866 if (r
->lbnd
< s
->lbnd
)
868 SCM_ARRAY_BASE (res
) += (s
->lbnd
- r
->lbnd
) * r
->inc
;
875 SCM_MISC_ERROR ("bad argument list", SCM_EOL
);
876 scm_ra_set_contp (res
);
882 /* args are RA . AXES */
883 SCM_DEFINE (scm_enclose_array
, "enclose-array", 1, 0, 1,
885 "@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than\n"
886 "the rank of @var{array}. @var{enclose-array} returns an array\n"
887 "resembling an array of shared arrays. The dimensions of each shared\n"
888 "array are the same as the @var{dim}th dimensions of the original array,\n"
889 "the dimensions of the outer array are the same as those of the original\n"
890 "array that did not match a @var{dim}.\n\n"
891 "An enclosed array is not a general Scheme array. Its elements may not\n"
892 "be set using @code{array-set!}. Two references to the same element of\n"
893 "an enclosed array will be @code{equal?} but will not in general be\n"
894 "@code{eq?}. The value returned by @var{array-prototype} when given an\n"
895 "enclosed array is unspecified.\n\n"
898 "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) @result{}\n"
899 " #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>\n\n"
900 "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{}\n"
901 " #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>\n"
903 #define FUNC_NAME s_scm_enclose_array
905 SCM axv
, res
, ra_inr
;
907 scm_t_array_dim vdim
, *s
= &vdim
;
908 int ndim
, j
, k
, ninr
, noutr
;
910 SCM_VALIDATE_REST_ARGUMENT (axes
);
911 if (scm_is_null (axes
))
912 axes
= scm_cons ((SCM_ARRAYP (ra
) ? scm_from_size_t (SCM_ARRAY_NDIM (ra
) - 1) : SCM_INUM0
), SCM_EOL
);
913 ninr
= scm_ilength (axes
);
915 SCM_WRONG_NUM_ARGS ();
916 ra_inr
= scm_make_ra (ninr
);
917 SCM_ASRTGO (SCM_NIMP (ra
), badarg1
);
921 badarg1
:SCM_WRONG_TYPE_ARG (1, ra
);
933 #if SCM_SIZEOF_LONG_LONG != 0
937 s
->ubnd
= scm_to_long (scm_uniform_vector_length (ra
)) - 1;
939 SCM_ARRAY_V (ra_inr
) = ra
;
940 SCM_ARRAY_BASE (ra_inr
) = 0;
944 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg1
);
945 s
= SCM_ARRAY_DIMS (ra
);
946 SCM_ARRAY_V (ra_inr
) = SCM_ARRAY_V (ra
);
947 SCM_ARRAY_BASE (ra_inr
) = SCM_ARRAY_BASE (ra
);
948 ndim
= SCM_ARRAY_NDIM (ra
);
953 SCM_WRONG_NUM_ARGS ();
954 axv
= scm_make_string (scm_from_int (ndim
), SCM_MAKE_CHAR (0));
955 res
= scm_make_ra (noutr
);
956 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra_inr
);
957 SCM_ARRAY_V (res
) = ra_inr
;
958 for (k
= 0; k
< ninr
; k
++, axes
= SCM_CDR (axes
))
960 if (!scm_is_integer (SCM_CAR (axes
)))
961 SCM_MISC_ERROR ("bad axis", SCM_EOL
);
962 j
= scm_to_int (SCM_CAR (axes
));
963 SCM_ARRAY_DIMS (ra_inr
)[k
].lbnd
= s
[j
].lbnd
;
964 SCM_ARRAY_DIMS (ra_inr
)[k
].ubnd
= s
[j
].ubnd
;
965 SCM_ARRAY_DIMS (ra_inr
)[k
].inc
= s
[j
].inc
;
966 scm_c_string_set_x (axv
, j
, SCM_MAKE_CHAR (1));
968 c_axv
= scm_i_string_chars (axv
);
969 for (j
= 0, k
= 0; k
< noutr
; k
++, j
++)
973 SCM_ARRAY_DIMS (res
)[k
].lbnd
= s
[j
].lbnd
;
974 SCM_ARRAY_DIMS (res
)[k
].ubnd
= s
[j
].ubnd
;
975 SCM_ARRAY_DIMS (res
)[k
].inc
= s
[j
].inc
;
977 scm_remember_upto_here_1 (axv
);
978 scm_ra_set_contp (ra_inr
);
979 scm_ra_set_contp (res
);
986 SCM_DEFINE (scm_array_in_bounds_p
, "array-in-bounds?", 1, 0, 1,
988 "Return @code{#t} if its arguments would be acceptable to\n"
990 #define FUNC_NAME s_scm_array_in_bounds_p
998 SCM_VALIDATE_REST_ARGUMENT (args
);
999 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1000 if (SCM_NIMP (args
))
1003 ind
= SCM_CAR (args
);
1004 args
= SCM_CDR (args
);
1005 pos
= scm_to_long (ind
);
1011 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
1012 wna
: SCM_WRONG_NUM_ARGS ();
1014 k
= SCM_ARRAY_NDIM (v
);
1015 s
= SCM_ARRAY_DIMS (v
);
1016 pos
= SCM_ARRAY_BASE (v
);
1019 SCM_ASRTGO (scm_is_null (ind
), wna
);
1025 j
= scm_to_long (ind
);
1026 if (!(j
>= (s
->lbnd
) && j
<= (s
->ubnd
)))
1028 SCM_ASRTGO (--k
== scm_ilength (args
), wna
);
1031 pos
+= (j
- s
->lbnd
) * (s
->inc
);
1032 if (!(--k
&& SCM_NIMP (args
)))
1034 ind
= SCM_CAR (args
);
1035 args
= SCM_CDR (args
);
1037 if (!scm_is_integer (ind
))
1038 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
1040 SCM_ASRTGO (0 == k
, wna
);
1041 v
= SCM_ARRAY_V (v
);
1044 case scm_tc7_string
:
1045 case scm_tc7_byvect
:
1052 #if SCM_SIZEOF_LONG_LONG != 0
1053 case scm_tc7_llvect
:
1055 case scm_tc7_vector
:
1058 unsigned long length
= scm_to_ulong (scm_uniform_vector_length (v
));
1059 SCM_ASRTGO (scm_is_null (args
) && scm_is_integer (ind
), wna
);
1060 return scm_from_bool(pos
>= 0 && pos
< length
);
1067 SCM_REGISTER_PROC(s_array_ref
, "array-ref", 1, 0, 1, scm_uniform_vector_ref
);
1070 SCM_DEFINE (scm_uniform_vector_ref
, "uniform-vector-ref", 2, 0, 0,
1072 "@deffnx {Scheme Procedure} array-ref v . args\n"
1073 "Return the element at the @code{(index1, index2)} element in\n"
1075 #define FUNC_NAME s_scm_uniform_vector_ref
1081 SCM_ASRTGO (scm_is_null (args
), badarg
);
1084 else if (SCM_ARRAYP (v
))
1086 pos
= scm_aind (v
, args
, FUNC_NAME
);
1087 v
= SCM_ARRAY_V (v
);
1091 unsigned long int length
;
1092 if (SCM_NIMP (args
))
1094 SCM_ASSERT (scm_is_pair (args
), args
, SCM_ARG2
, FUNC_NAME
);
1095 pos
= scm_to_long (SCM_CAR (args
));
1096 SCM_ASRTGO (scm_is_null (SCM_CDR (args
)), wna
);
1100 pos
= scm_to_long (args
);
1102 length
= scm_to_ulong (scm_uniform_vector_length (v
));
1103 SCM_ASRTGO (pos
>= 0 && pos
< length
, outrng
);
1108 if (scm_is_null (args
))
1111 SCM_WRONG_TYPE_ARG (1, v
);
1115 scm_out_of_range (FUNC_NAME
, scm_from_long (pos
));
1117 SCM_WRONG_NUM_ARGS ();
1120 int k
= SCM_ARRAY_NDIM (v
);
1121 SCM res
= scm_make_ra (k
);
1122 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1123 SCM_ARRAY_BASE (res
) = pos
;
1126 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1127 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1128 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1133 if (SCM_BITVEC_REF (v
, pos
))
1137 case scm_tc7_string
:
1138 return scm_c_string_ref (v
, pos
);
1139 case scm_tc7_byvect
:
1140 return scm_from_schar (((char *) SCM_UVECTOR_BASE (v
))[pos
]);
1142 return scm_from_ulong (((unsigned long *) SCM_VELTS (v
))[pos
]);
1144 return scm_from_long (((signed long *) SCM_VELTS (v
))[pos
]);
1147 return scm_from_short (((short *) SCM_CELL_WORD_1 (v
))[pos
]);
1148 #if SCM_SIZEOF_LONG_LONG != 0
1149 case scm_tc7_llvect
:
1150 return scm_from_long_long (((long long *) SCM_CELL_WORD_1 (v
))[pos
]);
1154 return scm_from_double (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1156 return scm_from_double (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1158 return scm_c_make_rectangular (((double *) SCM_CELL_WORD_1(v
))[2*pos
],
1159 ((double *) SCM_CELL_WORD_1(v
))[2*pos
+1]);
1160 case scm_tc7_vector
:
1162 return SCM_VELTS (v
)[pos
];
1167 /* Internal version of scm_uniform_vector_ref for uves that does no error checking and
1168 tries to recycle conses. (Make *sure* you want them recycled.) */
1171 scm_cvref (SCM v
, unsigned long pos
, SCM last
)
1172 #define FUNC_NAME "scm_cvref"
1177 SCM_WRONG_TYPE_ARG (SCM_ARG1
, v
);
1179 if (SCM_BITVEC_REF(v
, pos
))
1183 case scm_tc7_string
:
1184 return scm_c_string_ref (v
, pos
);
1185 case scm_tc7_byvect
:
1186 return scm_from_char (((char *) SCM_UVECTOR_BASE (v
))[pos
]);
1188 return scm_from_ulong (((unsigned long *) SCM_VELTS (v
))[pos
]);
1190 return scm_from_long (((signed long *) SCM_VELTS (v
))[pos
]);
1192 return scm_from_short (((short *) SCM_CELL_WORD_1 (v
))[pos
]);
1193 #if SCM_SIZEOF_LONG_LONG != 0
1194 case scm_tc7_llvect
:
1195 return scm_from_long_long (((long long *) SCM_CELL_WORD_1 (v
))[pos
]);
1198 if (SCM_REALP (last
) && !scm_is_eq (last
, scm_flo0
))
1200 SCM_REAL_VALUE (last
) = ((float *) SCM_CELL_WORD_1 (v
))[pos
];
1203 return scm_from_double (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1205 if (SCM_REALP (last
) && !scm_is_eq (last
, scm_flo0
))
1207 SCM_REAL_VALUE (last
) = ((double *) SCM_CELL_WORD_1 (v
))[pos
];
1210 return scm_from_double (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1212 if (SCM_COMPLEXP (last
))
1214 SCM_COMPLEX_REAL (last
) = ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
];
1215 SCM_COMPLEX_IMAG (last
) = ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1];
1218 return scm_c_make_rectangular (((double *) SCM_CELL_WORD_1(v
))[2*pos
],
1219 ((double *) SCM_CELL_WORD_1(v
))[2*pos
+1]);
1220 case scm_tc7_vector
:
1222 return SCM_VELTS (v
)[pos
];
1224 { /* enclosed scm_array */
1225 int k
= SCM_ARRAY_NDIM (v
);
1226 SCM res
= scm_make_ra (k
);
1227 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1228 SCM_ARRAY_BASE (res
) = pos
;
1231 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1232 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1233 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1242 SCM_REGISTER_PROC(s_uniform_array_set1_x
, "uniform-array-set1!", 3, 0, 0, scm_array_set_x
);
1245 /* Note that args may be a list or an immediate object, depending which
1246 PROC is used (and it's called from C too). */
1247 SCM_DEFINE (scm_array_set_x
, "array-set!", 2, 0, 1,
1248 (SCM v
, SCM obj
, SCM args
),
1249 "@deffnx {Scheme Procedure} uniform-array-set1! v obj args\n"
1250 "Set the element at the @code{(index1, index2)} element in @var{array} to\n"
1251 "@var{new-value}. The value returned by array-set! is unspecified.")
1252 #define FUNC_NAME s_scm_array_set_x
1256 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1259 pos
= scm_aind (v
, args
, FUNC_NAME
);
1260 v
= SCM_ARRAY_V (v
);
1264 unsigned long int length
;
1265 if (scm_is_pair (args
))
1267 SCM_ASRTGO (scm_is_null (SCM_CDR (args
)), wna
);
1268 pos
= scm_to_long (SCM_CAR (args
));
1272 pos
= scm_to_long (args
);
1274 length
= scm_to_ulong (scm_uniform_vector_length (v
));
1275 SCM_ASRTGO (pos
>= 0 && pos
< length
, outrng
);
1277 switch (SCM_TYP7 (v
))
1280 SCM_WRONG_TYPE_ARG (1, v
);
1283 scm_out_of_range (FUNC_NAME
, scm_from_long (pos
));
1285 SCM_WRONG_NUM_ARGS ();
1286 case scm_tc7_smob
: /* enclosed */
1289 if (scm_is_false (obj
))
1290 SCM_BITVEC_CLR(v
, pos
);
1291 else if (scm_is_eq (obj
, SCM_BOOL_T
))
1292 SCM_BITVEC_SET(v
, pos
);
1294 badobj
:SCM_WRONG_TYPE_ARG (2, obj
);
1296 case scm_tc7_string
:
1297 SCM_ASRTGO (SCM_CHARP (obj
), badobj
);
1298 scm_c_string_set_x (v
, pos
, obj
);
1300 case scm_tc7_byvect
:
1301 if (SCM_CHARP (obj
))
1302 obj
= scm_from_schar ((char) SCM_CHAR (obj
));
1303 ((char *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_schar (obj
);
1306 ((unsigned long *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_ulong (obj
);
1309 ((long *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_long (obj
);
1312 ((short *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_short (obj
);
1314 #if SCM_SIZEOF_LONG_LONG != 0
1315 case scm_tc7_llvect
:
1316 ((long long *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_long_long (obj
);
1320 ((float *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_double (obj
);
1323 ((double *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_double (obj
);
1326 SCM_ASRTGO (SCM_INEXACTP (obj
), badobj
);
1327 if (SCM_REALP (obj
)) {
1328 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
] = SCM_REAL_VALUE (obj
);
1329 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
+ 1] = 0.0;
1331 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
] = SCM_COMPLEX_REAL (obj
);
1332 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
+ 1] = SCM_COMPLEX_IMAG (obj
);
1335 case scm_tc7_vector
:
1337 SCM_VECTOR_SET (v
, pos
, obj
);
1340 return SCM_UNSPECIFIED
;
1344 /* attempts to unroll an array into a one-dimensional array.
1345 returns the unrolled array or #f if it can't be done. */
1346 /* if strict is not SCM_UNDEFINED, return #f if returned array
1347 wouldn't have contiguous elements. */
1348 SCM_DEFINE (scm_array_contents
, "array-contents", 1, 1, 0,
1349 (SCM ra
, SCM strict
),
1350 "If @var{array} may be @dfn{unrolled} into a one dimensional shared array\n"
1351 "without changing their order (last subscript changing fastest), then\n"
1352 "@code{array-contents} returns that shared array, otherwise it returns\n"
1353 "@code{#f}. All arrays made by @var{make-array} and\n"
1354 "@var{make-uniform-array} may be unrolled, some arrays made by\n"
1355 "@var{make-shared-array} may not be.\n\n"
1356 "If the optional argument @var{strict} is provided, a shared array will\n"
1357 "be returned only if its elements are stored internally contiguous in\n"
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 #if SCM_SIZEOF_LONG_LONG != 0
1380 case scm_tc7_llvect
:
1385 size_t 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_BITVECTOR_LENGTH (SCM_ARRAY_V (ra
)) ||
1397 SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
||
1404 SCM v
= SCM_ARRAY_V (ra
);
1405 unsigned long length
= scm_to_ulong (scm_uniform_vector_length (v
));
1406 if ((len
== length
) && 0 == SCM_ARRAY_BASE (ra
) && SCM_ARRAY_DIMS (ra
)->inc
)
1410 sra
= scm_make_ra (1);
1411 SCM_ARRAY_DIMS (sra
)->lbnd
= 0;
1412 SCM_ARRAY_DIMS (sra
)->ubnd
= len
- 1;
1413 SCM_ARRAY_V (sra
) = SCM_ARRAY_V (ra
);
1414 SCM_ARRAY_BASE (sra
) = SCM_ARRAY_BASE (ra
);
1415 SCM_ARRAY_DIMS (sra
)->inc
= (ndim
? SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
: 1);
1424 scm_ra2contig (SCM ra
, int copy
)
1429 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
1430 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1431 k
= SCM_ARRAY_NDIM (ra
);
1432 if (SCM_ARRAY_CONTP (ra
) && ((0 == k
) || (1 == SCM_ARRAY_DIMS (ra
)[k
- 1].inc
)))
1434 if (scm_tc7_bvect
!= SCM_TYP7 (SCM_ARRAY_V (ra
)))
1436 if ((len
== SCM_BITVECTOR_LENGTH (SCM_ARRAY_V (ra
)) &&
1437 0 == SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
&&
1438 0 == len
% SCM_LONG_BIT
))
1441 ret
= scm_make_ra (k
);
1442 SCM_ARRAY_BASE (ret
) = 0;
1445 SCM_ARRAY_DIMS (ret
)[k
].lbnd
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
;
1446 SCM_ARRAY_DIMS (ret
)[k
].ubnd
= SCM_ARRAY_DIMS (ra
)[k
].ubnd
;
1447 SCM_ARRAY_DIMS (ret
)[k
].inc
= inc
;
1448 inc
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1450 SCM_ARRAY_V (ret
) = scm_make_uve (inc
, scm_array_prototype (ra
));
1452 scm_array_copy_x (ra
, ret
);
1458 SCM_DEFINE (scm_uniform_array_read_x
, "uniform-array-read!", 1, 3, 0,
1459 (SCM ra
, SCM port_or_fd
, SCM start
, SCM end
),
1460 "@deffnx {Scheme Procedure} uniform-vector-read! uve [port-or-fdes] [start] [end]\n"
1461 "Attempt to read all elements of @var{ura}, in lexicographic order, as\n"
1462 "binary objects from @var{port-or-fdes}.\n"
1463 "If an end of file is encountered,\n"
1464 "the objects up to that point are put into @var{ura}\n"
1465 "(starting at the beginning) and the remainder of the array is\n"
1467 "The optional arguments @var{start} and @var{end} allow\n"
1468 "a specified region of a vector (or linearized array) to be read,\n"
1469 "leaving the remainder of the vector unchanged.\n\n"
1470 "@code{uniform-array-read!} returns the number of objects read.\n"
1471 "@var{port-or-fdes} may be omitted, in which case it defaults to the value\n"
1472 "returned by @code{(current-input-port)}.")
1473 #define FUNC_NAME s_scm_uniform_array_read_x
1475 SCM cra
= SCM_UNDEFINED
, v
= ra
;
1482 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1483 if (SCM_UNBNDP (port_or_fd
))
1484 port_or_fd
= scm_cur_inp
;
1486 SCM_ASSERT (scm_is_integer (port_or_fd
)
1487 || (SCM_OPINPORTP (port_or_fd
)),
1488 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1489 vlen
= (SCM_TYP7 (v
) == scm_tc7_smob
1491 : scm_to_long (scm_uniform_vector_length (v
)));
1497 badarg1
:SCM_WRONG_TYPE_ARG (SCM_ARG1
, v
);
1499 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1500 cra
= scm_ra2contig (ra
, 0);
1501 cstart
+= SCM_ARRAY_BASE (cra
);
1502 vlen
= SCM_ARRAY_DIMS (cra
)->inc
*
1503 (SCM_ARRAY_DIMS (cra
)->ubnd
- SCM_ARRAY_DIMS (cra
)->lbnd
+ 1);
1504 v
= SCM_ARRAY_V (cra
);
1506 case scm_tc7_string
:
1507 base
= NULL
; /* writing to strings is special, see below. */
1511 base
= (char *) SCM_BITVECTOR_BASE (v
);
1512 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1513 cstart
/= SCM_LONG_BIT
;
1516 case scm_tc7_byvect
:
1517 base
= (char *) SCM_UVECTOR_BASE (v
);
1522 base
= (char *) SCM_UVECTOR_BASE (v
);
1526 base
= (char *) SCM_UVECTOR_BASE (v
);
1527 sz
= sizeof (short);
1529 #if SCM_SIZEOF_LONG_LONG != 0
1530 case scm_tc7_llvect
:
1531 base
= (char *) SCM_UVECTOR_BASE (v
);
1532 sz
= sizeof (long long);
1536 base
= (char *) SCM_UVECTOR_BASE (v
);
1537 sz
= sizeof (float);
1540 base
= (char *) SCM_UVECTOR_BASE (v
);
1541 sz
= sizeof (double);
1544 base
= (char *) SCM_UVECTOR_BASE (v
);
1545 sz
= 2 * sizeof (double);
1550 if (!SCM_UNBNDP (start
))
1553 SCM_NUM2LONG (3, start
);
1555 if (offset
< 0 || offset
>= cend
)
1556 scm_out_of_range (FUNC_NAME
, start
);
1558 if (!SCM_UNBNDP (end
))
1561 SCM_NUM2LONG (4, end
);
1563 if (tend
<= offset
|| tend
> cend
)
1564 scm_out_of_range (FUNC_NAME
, end
);
1569 if (SCM_NIMP (port_or_fd
))
1571 scm_t_port
*pt
= SCM_PTAB_ENTRY (port_or_fd
);
1572 int remaining
= (cend
- offset
) * sz
;
1573 size_t off
= (cstart
+ offset
) * sz
;
1575 if (pt
->rw_active
== SCM_PORT_WRITE
)
1576 scm_flush (port_or_fd
);
1578 ans
= cend
- offset
;
1579 while (remaining
> 0)
1581 if (pt
->read_pos
< pt
->read_end
)
1583 int to_copy
= min (pt
->read_end
- pt
->read_pos
,
1589 char *b
= scm_i_string_writable_chars (v
);
1590 memcpy (b
+ off
, pt
->read_pos
, to_copy
);
1591 scm_i_string_stop_writing ();
1594 memcpy (base
+ off
, pt
->read_pos
, to_copy
);
1595 pt
->read_pos
+= to_copy
;
1596 remaining
-= to_copy
;
1601 if (scm_fill_input (port_or_fd
) == EOF
)
1603 if (remaining
% sz
!= 0)
1605 SCM_MISC_ERROR ("unexpected EOF", SCM_EOL
);
1607 ans
-= remaining
/ sz
;
1614 pt
->rw_active
= SCM_PORT_READ
;
1616 else /* file descriptor. */
1621 char *b
= scm_i_string_writable_chars (v
);
1622 SCM_SYSCALL (ans
= read (scm_to_int (port_or_fd
),
1623 b
+ (cstart
+ offset
) * sz
,
1624 (sz
* (cend
- offset
))));
1625 scm_i_string_stop_writing ();
1628 SCM_SYSCALL (ans
= read (scm_to_int (port_or_fd
),
1629 base
+ (cstart
+ offset
) * sz
,
1630 (sz
* (cend
- offset
))));
1634 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1635 ans
*= SCM_LONG_BIT
;
1637 if (!scm_is_eq (v
, ra
) && !scm_is_eq (cra
, ra
))
1638 scm_array_copy_x (cra
, ra
);
1640 return scm_from_long (ans
);
1644 SCM_DEFINE (scm_uniform_array_write
, "uniform-array-write", 1, 3, 0,
1645 (SCM v
, SCM port_or_fd
, SCM start
, SCM end
),
1646 "@deffnx {Scheme Procedure} uniform-vector-write uve [port-or-fdes] [start] [end]\n"
1647 "Writes all elements of @var{ura} as binary objects to\n"
1648 "@var{port-or-fdes}.\n\n"
1649 "The optional arguments @var{start}\n"
1650 "and @var{end} allow\n"
1651 "a specified region of a vector (or linearized array) to be written.\n\n"
1652 "The number of objects actually written is returned.\n"
1653 "@var{port-or-fdes} may be\n"
1654 "omitted, in which case it defaults to the value returned by\n"
1655 "@code{(current-output-port)}.")
1656 #define FUNC_NAME s_scm_uniform_array_write
1664 port_or_fd
= SCM_COERCE_OUTPORT (port_or_fd
);
1666 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1667 if (SCM_UNBNDP (port_or_fd
))
1668 port_or_fd
= scm_cur_outp
;
1670 SCM_ASSERT (scm_is_integer (port_or_fd
)
1671 || (SCM_OPOUTPORTP (port_or_fd
)),
1672 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1673 vlen
= (SCM_TYP7 (v
) == scm_tc7_smob
1675 : scm_to_long (scm_uniform_vector_length (v
)));
1681 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
1683 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1684 v
= scm_ra2contig (v
, 1);
1685 cstart
= SCM_ARRAY_BASE (v
);
1686 vlen
= (SCM_ARRAY_DIMS (v
)->inc
1687 * (SCM_ARRAY_DIMS (v
)->ubnd
- SCM_ARRAY_DIMS (v
)->lbnd
+ 1));
1688 v
= SCM_ARRAY_V (v
);
1690 case scm_tc7_string
:
1691 base
= scm_i_string_chars (v
);
1695 base
= (char *) SCM_BITVECTOR_BASE (v
);
1696 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1697 cstart
/= SCM_LONG_BIT
;
1700 case scm_tc7_byvect
:
1701 base
= (char *) SCM_UVECTOR_BASE (v
);
1706 base
= (char *) SCM_UVECTOR_BASE (v
);
1710 base
= (char *) SCM_UVECTOR_BASE (v
);
1711 sz
= sizeof (short);
1713 #if SCM_SIZEOF_LONG_LONG != 0
1714 case scm_tc7_llvect
:
1715 base
= (char *) SCM_UVECTOR_BASE (v
);
1716 sz
= sizeof (long long);
1720 base
= (char *) SCM_UVECTOR_BASE (v
);
1721 sz
= sizeof (float);
1724 base
= (char *) SCM_UVECTOR_BASE (v
);
1725 sz
= sizeof (double);
1728 base
= (char *) SCM_UVECTOR_BASE (v
);
1729 sz
= 2 * sizeof (double);
1734 if (!SCM_UNBNDP (start
))
1737 SCM_NUM2LONG (3, start
);
1739 if (offset
< 0 || offset
>= cend
)
1740 scm_out_of_range (FUNC_NAME
, start
);
1742 if (!SCM_UNBNDP (end
))
1745 SCM_NUM2LONG (4, end
);
1747 if (tend
<= offset
|| tend
> cend
)
1748 scm_out_of_range (FUNC_NAME
, end
);
1753 if (SCM_NIMP (port_or_fd
))
1755 const char *source
= base
+ (cstart
+ offset
) * sz
;
1757 ans
= cend
- offset
;
1758 scm_lfwrite (source
, ans
* sz
, port_or_fd
);
1760 else /* file descriptor. */
1762 SCM_SYSCALL (ans
= write (scm_to_int (port_or_fd
),
1763 base
+ (cstart
+ offset
) * sz
,
1764 (sz
* (cend
- offset
))));
1768 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1769 ans
*= SCM_LONG_BIT
;
1771 return scm_from_long (ans
);
1776 static char cnt_tab
[16] =
1777 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1779 SCM_DEFINE (scm_bit_count
, "bit-count", 2, 0, 0,
1780 (SCM b
, SCM bitvector
),
1781 "Return the number of occurrences of the boolean @var{b} in\n"
1783 #define FUNC_NAME s_scm_bit_count
1785 SCM_VALIDATE_BOOL (1, b
);
1786 SCM_ASSERT (SCM_BITVECTOR_P (bitvector
), bitvector
, 2, FUNC_NAME
);
1787 if (SCM_BITVECTOR_LENGTH (bitvector
) == 0) {
1790 unsigned long int count
= 0;
1791 unsigned long int i
= (SCM_BITVECTOR_LENGTH (bitvector
) - 1) / SCM_LONG_BIT
;
1792 unsigned long int w
= SCM_UNPACK (SCM_VELTS (bitvector
)[i
]);
1793 if (scm_is_false (b
)) {
1796 w
<<= SCM_LONG_BIT
- 1 - ((SCM_BITVECTOR_LENGTH (bitvector
) - 1) % SCM_LONG_BIT
);
1799 count
+= cnt_tab
[w
& 0x0f];
1803 return scm_from_ulong (count
);
1806 w
= SCM_UNPACK (SCM_VELTS (bitvector
)[i
]);
1807 if (scm_is_false (b
)) {
1817 SCM_DEFINE (scm_bit_position
, "bit-position", 3, 0, 0,
1818 (SCM item
, SCM v
, SCM k
),
1819 "Return the index of the first occurrance of @var{item} in bit\n"
1820 "vector @var{v}, starting from @var{k}. If there is no\n"
1821 "@var{item} entry between @var{k} and the end of\n"
1822 "@var{bitvector}, then return @code{#f}. For example,\n"
1825 "(bit-position #t #*000101 0) @result{} 3\n"
1826 "(bit-position #f #*0001111 3) @result{} #f\n"
1828 #define FUNC_NAME s_scm_bit_position
1830 long i
, lenw
, xbits
, pos
;
1831 register unsigned long w
;
1833 SCM_VALIDATE_BOOL (1, item
);
1834 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG2
, FUNC_NAME
);
1835 pos
= scm_to_long (k
);
1836 SCM_ASSERT_RANGE (3, k
, (pos
<= SCM_BITVECTOR_LENGTH (v
)) && (pos
>= 0));
1838 if (pos
== SCM_BITVECTOR_LENGTH (v
))
1841 lenw
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
; /* watch for part words */
1842 i
= pos
/ SCM_LONG_BIT
;
1843 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1844 if (scm_is_false (item
))
1846 xbits
= (pos
% SCM_LONG_BIT
);
1848 w
= ((w
>> xbits
) << xbits
);
1849 xbits
= SCM_LONG_BIT
- 1 - (SCM_BITVECTOR_LENGTH (v
) - 1) % SCM_LONG_BIT
;
1852 if (w
&& (i
== lenw
))
1853 w
= ((w
<< xbits
) >> xbits
);
1859 return scm_from_long (pos
);
1864 return scm_from_long (pos
+ 1);
1867 return scm_from_long (pos
+ 2);
1869 return scm_from_long (pos
+ 3);
1876 pos
+= SCM_LONG_BIT
;
1877 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1878 if (scm_is_false (item
))
1886 SCM_DEFINE (scm_bit_set_star_x
, "bit-set*!", 3, 0, 0,
1887 (SCM v
, SCM kv
, SCM obj
),
1888 "Set entries of bit vector @var{v} to @var{obj}, with @var{kv}\n"
1889 "selecting the entries to change. The return value is\n"
1892 "If @var{kv} is a bit vector, then those entries where it has\n"
1893 "@code{#t} are the ones in @var{v} which are set to @var{obj}.\n"
1894 "@var{kv} and @var{v} must be the same length. When @var{obj}\n"
1895 "is @code{#t} it's like @var{kv} is OR'ed into @var{v}. Or when\n"
1896 "@var{obj} is @code{#f} it can be seen as an ANDNOT.\n"
1899 "(define bv #*01000010)\n"
1900 "(bit-set*! bv #*10010001 #t)\n"
1902 "@result{} #*11010011\n"
1905 "If @var{kv} is a uniform vector of unsigned long integers, then\n"
1906 "they're indexes into @var{v} which are set to @var{obj}.\n"
1909 "(define bv #*01000010)\n"
1910 "(bit-set*! bv #u(5 2 7) #t)\n"
1912 "@result{} #*01100111\n"
1914 #define FUNC_NAME s_scm_bit_set_star_x
1916 register long i
, k
, vlen
;
1917 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
1918 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1919 switch SCM_TYP7 (kv
)
1922 badarg2
:SCM_WRONG_TYPE_ARG (2, kv
);
1924 vlen
= SCM_BITVECTOR_LENGTH (v
);
1925 if (scm_is_false (obj
))
1926 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1928 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1930 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
1931 SCM_BITVEC_CLR(v
, k
);
1933 else if (scm_is_eq (obj
, SCM_BOOL_T
))
1934 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1936 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1938 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
1939 SCM_BITVEC_SET(v
, k
);
1942 badarg3
:SCM_WRONG_TYPE_ARG (3, obj
);
1945 SCM_ASSERT (SCM_BITVECTOR_LENGTH (v
) == SCM_BITVECTOR_LENGTH (kv
), v
, SCM_ARG1
, FUNC_NAME
);
1946 if (scm_is_false (obj
))
1947 for (k
= (SCM_BITVECTOR_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1948 SCM_BITVECTOR_BASE (v
) [k
] &= ~SCM_BITVECTOR_BASE (kv
) [k
];
1949 else if (scm_is_eq (obj
, SCM_BOOL_T
))
1950 for (k
= (SCM_BITVECTOR_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1951 SCM_BITVECTOR_BASE (v
) [k
] |= SCM_BITVECTOR_BASE (kv
) [k
];
1956 return SCM_UNSPECIFIED
;
1961 SCM_DEFINE (scm_bit_count_star
, "bit-count*", 3, 0, 0,
1962 (SCM v
, SCM kv
, SCM obj
),
1963 "Return a count of how many entries in bit vector @var{v} are\n"
1964 "equal to @var{obj}, with @var{kv} selecting the entries to\n"
1967 "If @var{kv} is a bit vector, then those entries where it has\n"
1968 "@code{#t} are the ones in @var{v} which are considered.\n"
1969 "@var{kv} and @var{v} must be the same length.\n"
1971 "If @var{kv} is a uniform vector of unsigned long integers, then\n"
1972 "it's the indexes in @var{v} to consider.\n"
1977 "(bit-count* #*01110111 #*11001101 #t) @result{} 3\n"
1978 "(bit-count* #*01110111 #u(7 0 4) #f) @result{} 2\n"
1980 #define FUNC_NAME s_scm_bit_count_star
1982 register long i
, vlen
, count
= 0;
1983 register unsigned long k
;
1986 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
1987 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1988 switch SCM_TYP7 (kv
)
1992 SCM_WRONG_TYPE_ARG (2, kv
);
1994 vlen
= SCM_BITVECTOR_LENGTH (v
);
1995 if (scm_is_false (obj
))
1996 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1998 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
2000 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
2001 if (!SCM_BITVEC_REF(v
, k
))
2004 else if (scm_is_eq (obj
, SCM_BOOL_T
))
2005 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
2007 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
2009 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
2010 if (SCM_BITVEC_REF (v
, k
))
2014 badarg3
:SCM_WRONG_TYPE_ARG (3, obj
);
2017 SCM_ASSERT (SCM_BITVECTOR_LENGTH (v
) == SCM_BITVECTOR_LENGTH (kv
), v
, SCM_ARG1
, FUNC_NAME
);
2018 if (0 == SCM_BITVECTOR_LENGTH (v
))
2020 SCM_ASRTGO (scm_is_bool (obj
), badarg3
);
2021 fObj
= scm_is_eq (obj
, SCM_BOOL_T
);
2022 i
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
;
2023 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK (SCM_VELTS (v
)[i
]) : ~ SCM_UNPACK (SCM_VELTS (v
)[i
]));
2024 k
<<= SCM_LONG_BIT
- 1 - ((SCM_BITVECTOR_LENGTH (v
) - 1) % SCM_LONG_BIT
);
2028 count
+= cnt_tab
[k
& 0x0f];
2030 return scm_from_long (count
);
2032 /* urg. repetitive (see above.) */
2033 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK(SCM_VELTS (v
)[i
]) : ~SCM_UNPACK (SCM_VELTS (v
)[i
]));
2036 return scm_from_long (count
);
2041 SCM_DEFINE (scm_bit_invert_x
, "bit-invert!", 1, 0, 0,
2043 "Modify the bit vector @var{v} by replacing each element with\n"
2045 #define FUNC_NAME s_scm_bit_invert_x
2049 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
2051 k
= SCM_BITVECTOR_LENGTH (v
);
2052 for (k
= (k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
2053 SCM_BITVECTOR_BASE (v
) [k
] = ~SCM_BITVECTOR_BASE (v
) [k
];
2055 return SCM_UNSPECIFIED
;
2061 scm_istr2bve (SCM str
)
2063 size_t len
= scm_i_string_length (str
);
2064 SCM v
= scm_make_uve (len
, SCM_BOOL_T
);
2065 long *data
= (long *) SCM_VELTS (v
);
2066 register unsigned long mask
;
2069 const char *c_str
= scm_i_string_chars (str
);
2071 for (k
= 0; k
< (len
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
++)
2074 j
= len
- k
* SCM_LONG_BIT
;
2075 if (j
> SCM_LONG_BIT
)
2077 for (mask
= 1L; j
--; mask
<<= 1)
2095 ra2l (SCM ra
, unsigned long base
, unsigned long k
)
2097 register SCM res
= SCM_EOL
;
2098 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2100 if (SCM_ARRAY_DIMS (ra
)[k
].ubnd
< SCM_ARRAY_DIMS (ra
)[k
].lbnd
)
2102 i
= base
+ (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
) * inc
;
2103 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2108 res
= scm_cons (ra2l (ra
, i
, k
+ 1), res
);
2116 res
= scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra
), scm_from_size_t (i
)), res
);
2123 SCM_DEFINE (scm_array_to_list
, "array->list", 1, 0, 0,
2125 "Return a list consisting of all the elements, in order, of\n"
2127 #define FUNC_NAME s_scm_array_to_list
2131 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
2135 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
2137 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
2138 return ra2l (v
, SCM_ARRAY_BASE (v
), 0);
2139 case scm_tc7_vector
:
2141 return scm_vector_to_list (v
);
2142 case scm_tc7_string
:
2143 return scm_string_to_list (v
);
2146 long *data
= (long *) SCM_VELTS (v
);
2147 register unsigned long mask
;
2148 for (k
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
; k
> 0; k
--)
2149 for (mask
= 1UL << (SCM_LONG_BIT
- 1); mask
; mask
>>= 1)
2150 res
= scm_cons (scm_from_bool(((long *) data
)[k
] & mask
), res
);
2151 for (mask
= 1L << ((SCM_BITVECTOR_LENGTH (v
) % SCM_LONG_BIT
) - 1); mask
; mask
>>= 1)
2152 res
= scm_cons (scm_from_bool(((long *) data
)[k
] & mask
), res
);
2155 case scm_tc7_byvect
:
2157 signed char *data
= (signed char *) SCM_VELTS (v
);
2158 unsigned long k
= SCM_UVECTOR_LENGTH (v
);
2160 res
= scm_cons (scm_from_schar (data
[--k
]), res
);
2165 unsigned long *data
= (unsigned long *)SCM_VELTS(v
);
2166 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2167 res
= scm_cons(scm_from_ulong (data
[k
]), res
);
2172 long *data
= (long *)SCM_VELTS(v
);
2173 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2174 res
= scm_cons(scm_from_long (data
[k
]), res
);
2179 short *data
= (short *)SCM_VELTS(v
);
2180 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2181 res
= scm_cons (scm_from_short (data
[k
]), res
);
2184 #if SCM_SIZEOF_LONG_LONG != 0
2185 case scm_tc7_llvect
:
2187 long long *data
= (long long *)SCM_VELTS(v
);
2188 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2189 res
= scm_cons(scm_from_long_long (data
[k
]), res
);
2195 float *data
= (float *) SCM_VELTS (v
);
2196 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2197 res
= scm_cons (scm_from_double (data
[k
]), res
);
2202 double *data
= (double *) SCM_VELTS (v
);
2203 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2204 res
= scm_cons (scm_from_double (data
[k
]), res
);
2209 double (*data
)[2] = (double (*)[2]) SCM_VELTS (v
);
2210 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2211 res
= scm_cons (scm_c_make_rectangular (data
[k
][0], data
[k
][1]),
2220 static int l2ra(SCM lst
, SCM ra
, unsigned long base
, unsigned long k
);
2222 SCM_DEFINE (scm_list_to_uniform_array
, "list->uniform-array", 3, 0, 0,
2223 (SCM ndim
, SCM prot
, SCM lst
),
2224 "@deffnx {Scheme Procedure} list->uniform-vector prot lst\n"
2225 "Return a uniform array of the type indicated by prototype\n"
2226 "@var{prot} with elements the same as those of @var{lst}.\n"
2227 "Elements must be of the appropriate type, no coercions are\n"
2229 #define FUNC_NAME s_scm_list_to_uniform_array
2236 k
= scm_to_ulong (ndim
);
2239 n
= scm_ilength (row
);
2240 SCM_ASSERT (n
>= 0, lst
, SCM_ARG3
, FUNC_NAME
);
2241 shp
= scm_cons (scm_from_long (n
), shp
);
2243 row
= SCM_CAR (row
);
2245 ra
= scm_dimensions_to_uniform_array (scm_reverse (shp
), prot
,
2247 if (scm_is_null (shp
))
2249 SCM_ASRTGO (1 == scm_ilength (lst
), badlst
);
2250 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_EOL
);
2253 if (!SCM_ARRAYP (ra
))
2255 unsigned long length
= scm_to_ulong (scm_uniform_vector_length (ra
));
2256 for (k
= 0; k
< length
; k
++, lst
= SCM_CDR (lst
))
2257 scm_array_set_x (ra
, SCM_CAR (lst
), scm_from_ulong (k
));
2260 if (l2ra (lst
, ra
, SCM_ARRAY_BASE (ra
), 0))
2263 badlst
:SCM_MISC_ERROR ("Bad scm_array contents list: ~S",
2269 l2ra (SCM lst
, SCM ra
, unsigned long base
, unsigned long k
)
2271 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2272 register long n
= (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
);
2275 return (scm_is_null (lst
));
2276 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2280 if (!scm_is_pair (lst
))
2282 ok
= ok
&& l2ra (SCM_CAR (lst
), ra
, base
, k
+ 1);
2284 lst
= SCM_CDR (lst
);
2286 if (!scm_is_null (lst
))
2293 if (!scm_is_pair (lst
))
2295 scm_array_set_x (SCM_ARRAY_V (ra
), SCM_CAR (lst
), scm_from_ulong (base
));
2297 lst
= SCM_CDR (lst
);
2299 if (!scm_is_null (lst
))
2307 rapr1 (SCM ra
, unsigned long j
, unsigned long k
, SCM port
, scm_print_state
*pstate
)
2310 long n
= (SCM_TYP7 (ra
) == scm_tc7_smob
2312 : scm_to_long (scm_uniform_vector_length (ra
)));
2315 switch SCM_TYP7 (ra
)
2320 SCM_ARRAY_BASE (ra
) = j
;
2322 scm_iprin1 (ra
, port
, pstate
);
2323 for (j
+= inc
; n
-- > 0; j
+= inc
)
2325 scm_putc (' ', port
);
2326 SCM_ARRAY_BASE (ra
) = j
;
2327 scm_iprin1 (ra
, port
, pstate
);
2331 if (k
+ 1 < SCM_ARRAY_NDIM (ra
))
2334 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2335 for (i
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
; i
< SCM_ARRAY_DIMS (ra
)[k
].ubnd
; i
++)
2337 scm_putc ('(', port
);
2338 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2339 scm_puts (") ", port
);
2342 if (i
== SCM_ARRAY_DIMS (ra
)[k
].ubnd
)
2343 { /* could be zero size. */
2344 scm_putc ('(', port
);
2345 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2346 scm_putc (')', port
);
2350 if (SCM_ARRAY_NDIM (ra
) > 0)
2351 { /* Could be zero-dimensional */
2352 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2353 n
= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
2357 ra
= SCM_ARRAY_V (ra
);
2360 /* scm_tc7_bvect and scm_tc7_llvect only? */
2362 scm_iprin1 (scm_uniform_vector_ref (ra
, scm_from_ulong (j
)), port
, pstate
);
2363 for (j
+= inc
; n
-- > 0; j
+= inc
)
2365 scm_putc (' ', port
);
2366 scm_iprin1 (scm_cvref (ra
, j
, SCM_UNDEFINED
), port
, pstate
);
2369 case scm_tc7_string
:
2372 src
= scm_i_string_chars (ra
);
2374 scm_iprin1 (SCM_MAKE_CHAR (src
[j
]), port
, pstate
);
2375 if (SCM_WRITINGP (pstate
))
2376 for (j
+= inc
; n
-- > 0; j
+= inc
)
2378 scm_putc (' ', port
);
2379 scm_iprin1 (SCM_MAKE_CHAR (src
[j
]), port
, pstate
);
2382 for (j
+= inc
; n
-- > 0; j
+= inc
)
2383 scm_putc (src
[j
], port
);
2384 scm_remember_upto_here_1 (ra
);
2387 case scm_tc7_byvect
:
2389 scm_intprint (((char *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2390 for (j
+= inc
; n
-- > 0; j
+= inc
)
2392 scm_putc (' ', port
);
2393 scm_intprint (((char *)SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2403 /* intprint can't handle >= 2^31. */
2404 sprintf (str
, "%lu", ((unsigned long *) SCM_VELTS (ra
))[j
]);
2405 scm_puts (str
, port
);
2407 for (j
+= inc
; n
-- > 0; j
+= inc
)
2409 scm_putc (' ', port
);
2410 sprintf (str
, "%lu", ((unsigned long *) SCM_VELTS (ra
))[j
]);
2411 scm_puts (str
, port
);
2416 scm_intprint (((signed long *) SCM_VELTS (ra
))[j
], 10, port
);
2417 for (j
+= inc
; n
-- > 0; j
+= inc
)
2419 scm_putc (' ', port
);
2420 scm_intprint (((signed long *) SCM_VELTS (ra
))[j
], 10, port
);
2426 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2427 for (j
+= inc
; n
-- > 0; j
+= inc
)
2429 scm_putc (' ', port
);
2430 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2437 SCM z
= scm_from_double (1.0);
2438 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2439 scm_print_real (z
, port
, pstate
);
2440 for (j
+= inc
; n
-- > 0; j
+= inc
)
2442 scm_putc (' ', port
);
2443 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2444 scm_print_real (z
, port
, pstate
);
2451 SCM z
= scm_from_double (1.0 / 3.0);
2452 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2453 scm_print_real (z
, port
, pstate
);
2454 for (j
+= inc
; n
-- > 0; j
+= inc
)
2456 scm_putc (' ', port
);
2457 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2458 scm_print_real (z
, port
, pstate
);
2465 SCM cz
= scm_c_make_rectangular (0.0, 1.0);
2466 SCM z
= scm_from_double (1.0/3.0);
2467 SCM_REAL_VALUE (z
) =
2468 SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2469 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2470 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2472 for (j
+= inc
; n
-- > 0; j
+= inc
)
2474 scm_putc (' ', port
);
2476 = SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2477 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2478 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2489 scm_raprin1 (SCM exp
, SCM port
, scm_print_state
*pstate
)
2492 unsigned long base
= 0;
2493 scm_putc ('#', port
);
2499 long ndim
= SCM_ARRAY_NDIM (v
);
2500 base
= SCM_ARRAY_BASE (v
);
2501 v
= SCM_ARRAY_V (v
);
2505 scm_puts ("<enclosed-array ", port
);
2506 rapr1 (exp
, base
, 0, port
, pstate
);
2507 scm_putc ('>', port
);
2512 scm_intprint (ndim
, 10, port
);
2517 if (scm_is_eq (exp
, v
))
2518 { /* a uve, not an scm_array */
2519 register long i
, j
, w
;
2520 scm_putc ('*', port
);
2521 for (i
= 0; i
< (SCM_BITVECTOR_LENGTH (exp
)) / SCM_LONG_BIT
; i
++)
2523 scm_t_bits w
= SCM_UNPACK (SCM_VELTS (exp
)[i
]);
2524 for (j
= SCM_LONG_BIT
; j
; j
--)
2526 scm_putc (w
& 1 ? '1' : '0', port
);
2530 j
= SCM_BITVECTOR_LENGTH (exp
) % SCM_LONG_BIT
;
2533 w
= SCM_UNPACK (SCM_VELTS (exp
)[SCM_BITVECTOR_LENGTH (exp
) / SCM_LONG_BIT
]);
2536 scm_putc (w
& 1 ? '1' : '0', port
);
2543 scm_putc ('b', port
);
2545 case scm_tc7_string
:
2546 scm_putc ('a', port
);
2548 case scm_tc7_byvect
:
2549 scm_putc ('y', port
);
2552 scm_putc ('u', port
);
2555 scm_putc ('e', port
);
2558 scm_putc ('h', port
);
2560 #if SCM_SIZEOF_LONG_LONG != 0
2561 case scm_tc7_llvect
:
2562 scm_putc ('l', port
);
2566 scm_putc ('s', port
);
2569 scm_putc ('i', port
);
2572 scm_putc ('c', port
);
2575 scm_putc ('(', port
);
2576 rapr1 (exp
, base
, 0, port
, pstate
);
2577 scm_putc (')', port
);
2581 SCM_DEFINE (scm_array_prototype
, "array-prototype", 1, 0, 0,
2583 "Return an object that would produce an array of the same type\n"
2584 "as @var{array}, if used as the @var{prototype} for\n"
2585 "@code{make-uniform-array}.")
2586 #define FUNC_NAME s_scm_array_prototype
2589 SCM_ASRTGO (SCM_NIMP (ra
), badarg
);
2591 switch SCM_TYP7 (ra
)
2594 badarg
:SCM_WRONG_TYPE_ARG (1, ra
);
2596 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
2598 return SCM_UNSPECIFIED
;
2599 ra
= SCM_ARRAY_V (ra
);
2601 case scm_tc7_vector
:
2606 case scm_tc7_string
:
2607 return SCM_MAKE_CHAR ('a');
2608 case scm_tc7_byvect
:
2609 return SCM_MAKE_CHAR ('\0');
2611 return scm_from_int (1);
2613 return scm_from_int (-1);
2615 return scm_from_locale_symbol ("s");
2616 #if SCM_SIZEOF_LONG_LONG != 0
2617 case scm_tc7_llvect
:
2618 return scm_from_locale_symbol ("l");
2621 return scm_from_double (1.0);
2623 return exactly_one_third
;
2625 return scm_c_make_rectangular (0.0, 1.0);
2632 array_mark (SCM ptr
)
2634 return SCM_ARRAY_V (ptr
);
2639 array_free (SCM ptr
)
2641 scm_gc_free (SCM_ARRAY_MEM (ptr
),
2642 (sizeof (scm_t_array
)
2643 + SCM_ARRAY_NDIM (ptr
) * sizeof (scm_t_array_dim
)),
2651 scm_tc16_array
= scm_make_smob_type ("array", 0);
2652 scm_set_smob_mark (scm_tc16_array
, array_mark
);
2653 scm_set_smob_free (scm_tc16_array
, array_free
);
2654 scm_set_smob_print (scm_tc16_array
, scm_raprin1
);
2655 scm_set_smob_equalp (scm_tc16_array
, scm_array_equal_p
);
2656 exactly_one_third
= scm_permanent_object (scm_divide (scm_from_int (1),
2658 scm_add_feature ("array");
2659 #include "libguile/unif.x"