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
);
141 make_uve (long type
, long k
, size_t size
)
142 #define FUNC_NAME "scm_make_uve"
144 SCM_ASSERT_RANGE (1, scm_long2num (k
), k
<= SCM_UVECTOR_MAX_LENGTH
);
146 return scm_cell (SCM_MAKE_UVECTOR_TAG (k
, type
),
147 (scm_t_bits
) scm_gc_malloc (k
* size
, "vector"));
152 scm_make_uve (long k
, SCM prot
)
153 #define FUNC_NAME "scm_make_uve"
155 if (scm_is_eq (prot
, SCM_BOOL_T
))
161 scm_long2num (k
), k
<= SCM_BITVECTOR_MAX_LENGTH
);
162 i
= sizeof (long) * ((k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
);
163 return scm_cell (SCM_MAKE_BITVECTOR_TAG (k
),
164 (scm_t_bits
) scm_gc_malloc (i
, "vector"));
167 return scm_cell (SCM_MAKE_BITVECTOR_TAG (0), 0);
169 else if (SCM_CHARP (prot
) && (SCM_CHAR (prot
) == '\0'))
170 return make_uve (scm_tc7_byvect
, k
, sizeof (char));
171 else if (SCM_CHARP (prot
))
172 return scm_allocate_string (sizeof (char) * k
);
173 else if (SCM_I_INUMP (prot
))
174 return make_uve (SCM_I_INUM (prot
) > 0 ? scm_tc7_uvect
: scm_tc7_ivect
,
177 else if (SCM_FRACTIONP (prot
))
179 if (scm_num_eq_p (exactly_one_third
, prot
))
182 else if (SCM_SYMBOLP (prot
) && (1 == SCM_SYMBOL_LENGTH (prot
)))
186 s
= SCM_SYMBOL_CHARS (prot
)[0];
188 return make_uve (scm_tc7_svect
, k
, sizeof (short));
189 #if SCM_SIZEOF_LONG_LONG != 0
191 return make_uve (scm_tc7_llvect
, k
, sizeof (long long));
194 return scm_c_make_vector (k
, SCM_UNDEFINED
);
196 else if (!SCM_INEXACTP (prot
))
197 /* Huge non-unif vectors are NOT supported. */
198 /* no special scm_vector */
199 return scm_c_make_vector (k
, SCM_UNDEFINED
);
200 else if (singp (prot
))
201 return make_uve (scm_tc7_fvect
, k
, sizeof (float));
202 else if (SCM_COMPLEXP (prot
))
203 return make_uve (scm_tc7_cvect
, k
, 2 * sizeof (double));
205 return make_uve (scm_tc7_dvect
, k
, sizeof (double));
209 SCM_DEFINE (scm_uniform_vector_length
, "uniform-vector-length", 1, 0, 0,
211 "Return the number of elements in @var{uve}.")
212 #define FUNC_NAME s_scm_uniform_vector_length
214 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
218 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
221 return scm_from_size_t (SCM_VECTOR_LENGTH (v
));
223 return scm_from_size_t (SCM_STRING_LENGTH (v
));
225 return scm_from_size_t (SCM_BITVECTOR_LENGTH (v
));
233 #if SCM_SIZEOF_LONG_LONG != 0
236 return scm_from_size_t (SCM_UVECTOR_LENGTH (v
));
241 SCM_DEFINE (scm_array_p
, "array?", 1, 1, 0,
243 "Return @code{#t} if the @var{obj} is an array, and @code{#f} if\n"
244 "not. The @var{prototype} argument is used with uniform arrays\n"
245 "and is described elsewhere.")
246 #define FUNC_NAME s_scm_array_p
250 nprot
= SCM_UNBNDP (prot
);
255 while (SCM_TYP7 (v
) == scm_tc7_smob
)
266 return scm_from_bool(nprot
);
271 switch (SCM_TYP7 (v
))
274 protp
= (scm_is_eq (prot
, SCM_BOOL_T
));
277 protp
= SCM_CHARP(prot
) && (SCM_CHAR (prot
) != '\0');
280 protp
= scm_is_eq (prot
, SCM_MAKE_CHAR ('\0'));
283 protp
= SCM_I_INUMP(prot
) && SCM_I_INUM(prot
)>0;
286 protp
= SCM_I_INUMP(prot
) && SCM_I_INUM(prot
)<=0;
289 protp
= SCM_SYMBOLP (prot
)
290 && (1 == SCM_SYMBOL_LENGTH (prot
))
291 && ('s' == SCM_SYMBOL_CHARS (prot
)[0]);
293 #if SCM_SIZEOF_LONG_LONG != 0
295 protp
= SCM_SYMBOLP (prot
)
296 && (1 == SCM_SYMBOL_LENGTH (prot
))
297 && ('l' == SCM_SYMBOL_CHARS (prot
)[0]);
301 protp
= singp (prot
);
304 protp
= ((SCM_REALP(prot
) && ! singp (prot
))
305 || (SCM_FRACTIONP (prot
)
306 && scm_num_eq_p (exactly_one_third
, prot
)));
309 protp
= SCM_COMPLEXP(prot
);
313 protp
= SCM_NULLP(prot
);
319 return scm_from_bool(protp
);
325 SCM_DEFINE (scm_array_rank
, "array-rank", 1, 0, 0,
327 "Return the number of dimensions of @var{obj}. If @var{obj} is\n"
328 "not an array, @code{0} is returned.")
329 #define FUNC_NAME s_scm_array_rank
333 switch (SCM_TYP7 (ra
))
346 #if SCM_SIZEOF_LONG_LONG != 0
350 return scm_from_int (1);
353 return scm_from_size_t (SCM_ARRAY_NDIM (ra
));
360 SCM_DEFINE (scm_array_dimensions
, "array-dimensions", 1, 0, 0,
362 "@code{Array-dimensions} is similar to @code{array-shape} but replaces\n"
363 "elements with a @code{0} minimum with one greater than the maximum. So:\n"
365 "(array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5)\n"
367 #define FUNC_NAME s_scm_array_dimensions
374 switch (SCM_TYP7 (ra
))
389 #if SCM_SIZEOF_LONG_LONG != 0
392 return scm_cons (scm_uniform_vector_length (ra
), SCM_EOL
);
394 if (!SCM_ARRAYP (ra
))
396 k
= SCM_ARRAY_NDIM (ra
);
397 s
= SCM_ARRAY_DIMS (ra
);
399 res
= scm_cons (s
[k
].lbnd
400 ? scm_cons2 (scm_from_long (s
[k
].lbnd
),
401 scm_from_long (s
[k
].ubnd
),
403 : scm_from_long (1 + s
[k
].ubnd
),
411 SCM_DEFINE (scm_shared_array_root
, "shared-array-root", 1, 0, 0,
413 "Return the root vector of a shared array.")
414 #define FUNC_NAME s_scm_shared_array_root
416 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
417 return SCM_ARRAY_V (ra
);
422 SCM_DEFINE (scm_shared_array_offset
, "shared-array-offset", 1, 0, 0,
424 "Return the root vector index of the first element in the array.")
425 #define FUNC_NAME s_scm_shared_array_offset
427 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
428 return scm_from_int (SCM_ARRAY_BASE (ra
));
433 SCM_DEFINE (scm_shared_array_increments
, "shared-array-increments", 1, 0, 0,
435 "For each dimension, return the distance between elements in the root vector.")
436 #define FUNC_NAME s_scm_shared_array_increments
441 SCM_ASSERT (SCM_ARRAYP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
442 k
= SCM_ARRAY_NDIM (ra
);
443 s
= SCM_ARRAY_DIMS (ra
);
445 res
= scm_cons (scm_from_long (s
[k
].inc
), res
);
451 static char s_bad_ind
[] = "Bad scm_array index";
455 scm_aind (SCM ra
, SCM args
, const char *what
)
456 #define FUNC_NAME what
460 register unsigned long pos
= SCM_ARRAY_BASE (ra
);
461 register unsigned long k
= SCM_ARRAY_NDIM (ra
);
462 scm_t_array_dim
*s
= SCM_ARRAY_DIMS (ra
);
463 if (scm_is_integer (args
))
466 scm_error_num_args_subr (what
);
467 return pos
+ (scm_to_long (args
) - s
->lbnd
) * (s
->inc
);
469 while (k
&& SCM_CONSP (args
))
471 ind
= SCM_CAR (args
);
472 args
= SCM_CDR (args
);
473 if (!scm_is_integer (ind
))
474 scm_misc_error (what
, s_bad_ind
, SCM_EOL
);
475 j
= scm_to_long (ind
);
476 if (j
< s
->lbnd
|| j
> s
->ubnd
)
477 scm_out_of_range (what
, ind
);
478 pos
+= (j
- s
->lbnd
) * (s
->inc
);
482 if (k
!= 0 || !SCM_NULLP (args
))
483 scm_error_num_args_subr (what
);
491 scm_make_ra (int ndim
)
495 SCM_NEWSMOB(ra
, ((scm_t_bits
) ndim
<< 17) + scm_tc16_array
,
496 scm_gc_malloc ((sizeof (scm_t_array
) +
497 ndim
* sizeof (scm_t_array_dim
)),
499 SCM_ARRAY_V (ra
) = scm_nullvect
;
504 static char s_bad_spec
[] = "Bad scm_array dimension";
505 /* Increments will still need to be set. */
509 scm_shap2ra (SCM args
, const char *what
)
513 int ndim
= scm_ilength (args
);
515 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
517 ra
= scm_make_ra (ndim
);
518 SCM_ARRAY_BASE (ra
) = 0;
519 s
= SCM_ARRAY_DIMS (ra
);
520 for (; !SCM_NULLP (args
); s
++, args
= SCM_CDR (args
))
522 spec
= SCM_CAR (args
);
523 if (scm_is_integer (spec
))
525 if (scm_to_long (spec
) < 0)
526 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
528 s
->ubnd
= scm_to_long (spec
) - 1;
533 if (!SCM_CONSP (spec
) || !scm_is_integer (SCM_CAR (spec
)))
534 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
535 s
->lbnd
= scm_to_long (SCM_CAR (spec
));
538 || !scm_is_integer (SCM_CAR (sp
))
539 || !SCM_NULLP (SCM_CDR (sp
)))
540 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
541 s
->ubnd
= scm_to_long (SCM_CAR (sp
));
548 SCM_DEFINE (scm_dimensions_to_uniform_array
, "dimensions->uniform-array", 2, 1, 0,
549 (SCM dims
, SCM prot
, SCM fill
),
550 "@deffnx {Scheme Procedure} make-uniform-vector length prototype [fill]\n"
551 "Create and return a uniform array or vector of type\n"
552 "corresponding to @var{prototype} with dimensions @var{dims} or\n"
553 "length @var{length}. If @var{fill} is supplied, it's used to\n"
554 "fill the array, otherwise @var{prototype} is used.")
555 #define FUNC_NAME s_scm_dimensions_to_uniform_array
558 unsigned long rlen
= 1;
562 if (scm_is_integer (dims
))
564 SCM answer
= scm_make_uve (scm_to_long (dims
), prot
);
565 if (!SCM_UNBNDP (fill
))
566 scm_array_fill_x (answer
, fill
);
567 else if (SCM_SYMBOLP (prot
))
568 scm_array_fill_x (answer
, scm_from_int (0));
570 scm_array_fill_x (answer
, prot
);
574 SCM_ASSERT (SCM_NULLP (dims
) || SCM_CONSP (dims
),
575 dims
, SCM_ARG1
, FUNC_NAME
);
576 ra
= scm_shap2ra (dims
, FUNC_NAME
);
577 SCM_SET_ARRAY_CONTIGUOUS_FLAG (ra
);
578 s
= SCM_ARRAY_DIMS (ra
);
579 k
= SCM_ARRAY_NDIM (ra
);
584 SCM_ASSERT_RANGE (1, dims
, s
[k
].lbnd
<= s
[k
].ubnd
);
585 rlen
= (s
[k
].ubnd
- s
[k
].lbnd
+ 1) * s
[k
].inc
;
588 SCM_ARRAY_V (ra
) = scm_make_uve (rlen
, prot
);
590 if (!SCM_UNBNDP (fill
))
591 scm_array_fill_x (ra
, fill
);
592 else if (SCM_SYMBOLP (prot
))
593 scm_array_fill_x (ra
, scm_from_int (0));
595 scm_array_fill_x (ra
, prot
);
597 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
598 if (s
->ubnd
< s
->lbnd
|| (0 == s
->lbnd
&& 1 == s
->inc
))
599 return SCM_ARRAY_V (ra
);
606 scm_ra_set_contp (SCM ra
)
608 size_t k
= SCM_ARRAY_NDIM (ra
);
611 long inc
= SCM_ARRAY_DIMS (ra
)[k
- 1].inc
;
614 if (inc
!= SCM_ARRAY_DIMS (ra
)[k
].inc
)
616 SCM_CLR_ARRAY_CONTIGUOUS_FLAG (ra
);
619 inc
*= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
620 - SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
623 SCM_SET_ARRAY_CONTIGUOUS_FLAG (ra
);
627 SCM_DEFINE (scm_make_shared_array
, "make-shared-array", 2, 0, 1,
628 (SCM oldra
, SCM mapfunc
, SCM dims
),
629 "@code{make-shared-array} can be used to create shared subarrays of other\n"
630 "arrays. The @var{mapper} is a function that translates coordinates in\n"
631 "the new array into coordinates in the old array. A @var{mapper} must be\n"
632 "linear, and its range must stay within the bounds of the old array, but\n"
633 "it can be otherwise arbitrary. A simple example:\n"
635 "(define fred (make-array #f 8 8))\n"
636 "(define freds-diagonal\n"
637 " (make-shared-array fred (lambda (i) (list i i)) 8))\n"
638 "(array-set! freds-diagonal 'foo 3)\n"
639 "(array-ref fred 3 3) @result{} foo\n"
640 "(define freds-center\n"
641 " (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))\n"
642 "(array-ref freds-center 0 0) @result{} foo\n"
644 #define FUNC_NAME s_scm_make_shared_array
650 long old_min
, new_min
, old_max
, new_max
;
653 SCM_VALIDATE_REST_ARGUMENT (dims
);
654 SCM_VALIDATE_ARRAY (1, oldra
);
655 SCM_VALIDATE_PROC (2, mapfunc
);
656 ra
= scm_shap2ra (dims
, FUNC_NAME
);
657 if (SCM_ARRAYP (oldra
))
659 SCM_ARRAY_V (ra
) = SCM_ARRAY_V (oldra
);
660 old_min
= old_max
= SCM_ARRAY_BASE (oldra
);
661 s
= SCM_ARRAY_DIMS (oldra
);
662 k
= SCM_ARRAY_NDIM (oldra
);
666 old_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
668 old_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
673 SCM_ARRAY_V (ra
) = oldra
;
675 old_max
= scm_to_long (scm_uniform_vector_length (oldra
)) - 1;
678 s
= SCM_ARRAY_DIMS (ra
);
679 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
681 inds
= scm_cons (scm_from_long (s
[k
].lbnd
), inds
);
682 if (s
[k
].ubnd
< s
[k
].lbnd
)
684 if (1 == SCM_ARRAY_NDIM (ra
))
685 ra
= scm_make_uve (0L, scm_array_prototype (ra
));
687 SCM_ARRAY_V (ra
) = scm_make_uve (0L, scm_array_prototype (ra
));
691 imap
= scm_apply_0 (mapfunc
, scm_reverse (inds
));
692 if (SCM_ARRAYP (oldra
))
693 i
= (size_t) scm_aind (oldra
, imap
, FUNC_NAME
);
696 if (!scm_is_integer (imap
))
698 if (scm_ilength (imap
) != 1 || !scm_is_integer (SCM_CAR (imap
)))
699 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
700 imap
= SCM_CAR (imap
);
702 i
= scm_to_size_t (imap
);
704 SCM_ARRAY_BASE (ra
) = new_min
= new_max
= i
;
706 k
= SCM_ARRAY_NDIM (ra
);
709 if (s
[k
].ubnd
> s
[k
].lbnd
)
711 SCM_SETCAR (indptr
, scm_sum (SCM_CAR (indptr
), scm_from_int (1)));
712 imap
= scm_apply_0 (mapfunc
, scm_reverse (inds
));
713 if (SCM_ARRAYP (oldra
))
715 s
[k
].inc
= scm_aind (oldra
, imap
, FUNC_NAME
) - i
;
718 if (!scm_is_integer (imap
))
720 if (scm_ilength (imap
) != 1 || !scm_is_integer (SCM_CAR (imap
)))
721 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
722 imap
= SCM_CAR (imap
);
724 s
[k
].inc
= scm_to_long (imap
) - i
;
728 new_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
730 new_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
733 s
[k
].inc
= new_max
- new_min
+ 1; /* contiguous by default */
734 indptr
= SCM_CDR (indptr
);
736 if (old_min
> new_min
|| old_max
< new_max
)
737 SCM_MISC_ERROR ("mapping out of range", SCM_EOL
);
738 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
740 SCM v
= SCM_ARRAY_V (ra
);
741 unsigned long int length
= scm_to_ulong (scm_uniform_vector_length (v
));
742 if (1 == s
->inc
&& 0 == s
->lbnd
&& length
== 1 + s
->ubnd
)
744 if (s
->ubnd
< s
->lbnd
)
745 return scm_make_uve (0L, scm_array_prototype (ra
));
747 scm_ra_set_contp (ra
);
753 /* args are RA . DIMS */
754 SCM_DEFINE (scm_transpose_array
, "transpose-array", 1, 0, 1,
756 "Return an array sharing contents with @var{array}, but with\n"
757 "dimensions arranged in a different order. There must be one\n"
758 "@var{dim} argument for each dimension of @var{array}.\n"
759 "@var{dim0}, @var{dim1}, @dots{} should be integers between 0\n"
760 "and the rank of the array to be returned. Each integer in that\n"
761 "range must appear at least once in the argument list.\n"
763 "The values of @var{dim0}, @var{dim1}, @dots{} correspond to\n"
764 "dimensions in the array to be returned, their positions in the\n"
765 "argument list to dimensions of @var{array}. Several @var{dim}s\n"
766 "may have the same value, in which case the returned array will\n"
767 "have smaller rank than @var{array}.\n"
770 "(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))\n"
771 "(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)\n"
772 "(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}\n"
773 " #2((a 4) (b 5) (c 6))\n"
775 #define FUNC_NAME s_scm_transpose_array
778 SCM
const *ve
= &vargs
;
779 scm_t_array_dim
*s
, *r
;
782 SCM_VALIDATE_REST_ARGUMENT (args
);
783 SCM_ASSERT (SCM_NIMP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
784 switch (SCM_TYP7 (ra
))
787 badarg
:SCM_WRONG_TYPE_ARG (1, ra
);
797 #if SCM_SIZEOF_LONG_LONG != 0
800 if (SCM_NULLP (args
) || !SCM_NULLP (SCM_CDR (args
)))
801 SCM_WRONG_NUM_ARGS ();
802 SCM_VALIDATE_INT_COPY (SCM_ARG2
, SCM_CAR (args
), i
);
803 SCM_ASSERT_RANGE (SCM_ARG2
, SCM_CAR (args
), i
== 0);
806 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
807 vargs
= scm_vector (args
);
808 if (SCM_VECTOR_LENGTH (vargs
) != SCM_ARRAY_NDIM (ra
))
809 SCM_WRONG_NUM_ARGS ();
810 ve
= SCM_VELTS (vargs
);
812 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
814 i
= scm_to_signed_integer (ve
[k
], 0, SCM_ARRAY_NDIM(ra
));
819 res
= scm_make_ra (ndim
);
820 SCM_ARRAY_V (res
) = SCM_ARRAY_V (ra
);
821 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra
);
824 SCM_ARRAY_DIMS (res
)[k
].lbnd
= 0;
825 SCM_ARRAY_DIMS (res
)[k
].ubnd
= -1;
827 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
829 i
= scm_to_int (ve
[k
]);
830 s
= &(SCM_ARRAY_DIMS (ra
)[k
]);
831 r
= &(SCM_ARRAY_DIMS (res
)[i
]);
832 if (r
->ubnd
< r
->lbnd
)
841 if (r
->ubnd
> s
->ubnd
)
843 if (r
->lbnd
< s
->lbnd
)
845 SCM_ARRAY_BASE (res
) += (s
->lbnd
- r
->lbnd
) * r
->inc
;
852 SCM_MISC_ERROR ("bad argument list", SCM_EOL
);
853 scm_ra_set_contp (res
);
859 /* args are RA . AXES */
860 SCM_DEFINE (scm_enclose_array
, "enclose-array", 1, 0, 1,
862 "@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than\n"
863 "the rank of @var{array}. @var{enclose-array} returns an array\n"
864 "resembling an array of shared arrays. The dimensions of each shared\n"
865 "array are the same as the @var{dim}th dimensions of the original array,\n"
866 "the dimensions of the outer array are the same as those of the original\n"
867 "array that did not match a @var{dim}.\n\n"
868 "An enclosed array is not a general Scheme array. Its elements may not\n"
869 "be set using @code{array-set!}. Two references to the same element of\n"
870 "an enclosed array will be @code{equal?} but will not in general be\n"
871 "@code{eq?}. The value returned by @var{array-prototype} when given an\n"
872 "enclosed array is unspecified.\n\n"
875 "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) @result{}\n"
876 " #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>\n\n"
877 "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{}\n"
878 " #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>\n"
880 #define FUNC_NAME s_scm_enclose_array
882 SCM axv
, res
, ra_inr
;
883 scm_t_array_dim vdim
, *s
= &vdim
;
884 int ndim
, j
, k
, ninr
, noutr
;
886 SCM_VALIDATE_REST_ARGUMENT (axes
);
887 if (SCM_NULLP (axes
))
888 axes
= scm_cons ((SCM_ARRAYP (ra
) ? scm_from_size_t (SCM_ARRAY_NDIM (ra
) - 1) : SCM_INUM0
), SCM_EOL
);
889 ninr
= scm_ilength (axes
);
891 SCM_WRONG_NUM_ARGS ();
892 ra_inr
= scm_make_ra (ninr
);
893 SCM_ASRTGO (SCM_NIMP (ra
), badarg1
);
897 badarg1
:SCM_WRONG_TYPE_ARG (1, ra
);
909 #if SCM_SIZEOF_LONG_LONG != 0
913 s
->ubnd
= scm_to_long (scm_uniform_vector_length (ra
)) - 1;
915 SCM_ARRAY_V (ra_inr
) = ra
;
916 SCM_ARRAY_BASE (ra_inr
) = 0;
920 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg1
);
921 s
= SCM_ARRAY_DIMS (ra
);
922 SCM_ARRAY_V (ra_inr
) = SCM_ARRAY_V (ra
);
923 SCM_ARRAY_BASE (ra_inr
) = SCM_ARRAY_BASE (ra
);
924 ndim
= SCM_ARRAY_NDIM (ra
);
929 SCM_WRONG_NUM_ARGS ();
930 axv
= scm_make_string (scm_from_int (ndim
), SCM_MAKE_CHAR (0));
931 res
= scm_make_ra (noutr
);
932 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra_inr
);
933 SCM_ARRAY_V (res
) = ra_inr
;
934 for (k
= 0; k
< ninr
; k
++, axes
= SCM_CDR (axes
))
936 if (!scm_is_integer (SCM_CAR (axes
)))
937 SCM_MISC_ERROR ("bad axis", SCM_EOL
);
938 j
= scm_to_int (SCM_CAR (axes
));
939 SCM_ARRAY_DIMS (ra_inr
)[k
].lbnd
= s
[j
].lbnd
;
940 SCM_ARRAY_DIMS (ra_inr
)[k
].ubnd
= s
[j
].ubnd
;
941 SCM_ARRAY_DIMS (ra_inr
)[k
].inc
= s
[j
].inc
;
942 SCM_STRING_CHARS (axv
)[j
] = 1;
944 for (j
= 0, k
= 0; k
< noutr
; k
++, j
++)
946 while (SCM_STRING_CHARS (axv
)[j
])
948 SCM_ARRAY_DIMS (res
)[k
].lbnd
= s
[j
].lbnd
;
949 SCM_ARRAY_DIMS (res
)[k
].ubnd
= s
[j
].ubnd
;
950 SCM_ARRAY_DIMS (res
)[k
].inc
= s
[j
].inc
;
952 scm_ra_set_contp (ra_inr
);
953 scm_ra_set_contp (res
);
960 SCM_DEFINE (scm_array_in_bounds_p
, "array-in-bounds?", 1, 0, 1,
962 "Return @code{#t} if its arguments would be acceptable to\n"
964 #define FUNC_NAME s_scm_array_in_bounds_p
972 SCM_VALIDATE_REST_ARGUMENT (args
);
973 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
977 ind
= SCM_CAR (args
);
978 args
= SCM_CDR (args
);
979 pos
= scm_to_long (ind
);
985 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
986 wna
: SCM_WRONG_NUM_ARGS ();
988 k
= SCM_ARRAY_NDIM (v
);
989 s
= SCM_ARRAY_DIMS (v
);
990 pos
= SCM_ARRAY_BASE (v
);
993 SCM_ASRTGO (SCM_NULLP (ind
), wna
);
999 j
= scm_to_long (ind
);
1000 if (!(j
>= (s
->lbnd
) && j
<= (s
->ubnd
)))
1002 SCM_ASRTGO (--k
== scm_ilength (args
), wna
);
1005 pos
+= (j
- s
->lbnd
) * (s
->inc
);
1006 if (!(--k
&& SCM_NIMP (args
)))
1008 ind
= SCM_CAR (args
);
1009 args
= SCM_CDR (args
);
1011 if (!scm_is_integer (ind
))
1012 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
1014 SCM_ASRTGO (0 == k
, wna
);
1015 v
= SCM_ARRAY_V (v
);
1018 case scm_tc7_string
:
1019 case scm_tc7_byvect
:
1026 #if SCM_SIZEOF_LONG_LONG != 0
1027 case scm_tc7_llvect
:
1029 case scm_tc7_vector
:
1032 unsigned long length
= scm_to_ulong (scm_uniform_vector_length (v
));
1033 SCM_ASRTGO (SCM_NULLP (args
) && scm_is_integer (ind
), wna
);
1034 return scm_from_bool(pos
>= 0 && pos
< length
);
1041 SCM_REGISTER_PROC(s_array_ref
, "array-ref", 1, 0, 1, scm_uniform_vector_ref
);
1044 SCM_DEFINE (scm_uniform_vector_ref
, "uniform-vector-ref", 2, 0, 0,
1046 "@deffnx {Scheme Procedure} array-ref v . args\n"
1047 "Return the element at the @code{(index1, index2)} element in\n"
1049 #define FUNC_NAME s_scm_uniform_vector_ref
1055 SCM_ASRTGO (SCM_NULLP (args
), badarg
);
1058 else if (SCM_ARRAYP (v
))
1060 pos
= scm_aind (v
, args
, FUNC_NAME
);
1061 v
= SCM_ARRAY_V (v
);
1065 unsigned long int length
;
1066 if (SCM_NIMP (args
))
1068 SCM_ASSERT (SCM_CONSP (args
), args
, SCM_ARG2
, FUNC_NAME
);
1069 pos
= scm_to_long (SCM_CAR (args
));
1070 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1074 pos
= scm_to_long (args
);
1076 length
= scm_to_ulong (scm_uniform_vector_length (v
));
1077 SCM_ASRTGO (pos
>= 0 && pos
< length
, outrng
);
1082 if (SCM_NULLP (args
))
1085 SCM_WRONG_TYPE_ARG (1, v
);
1089 scm_out_of_range (FUNC_NAME
, scm_from_long (pos
));
1091 SCM_WRONG_NUM_ARGS ();
1094 int k
= SCM_ARRAY_NDIM (v
);
1095 SCM res
= scm_make_ra (k
);
1096 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1097 SCM_ARRAY_BASE (res
) = pos
;
1100 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1101 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1102 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1107 if (SCM_BITVEC_REF (v
, pos
))
1111 case scm_tc7_string
:
1112 return SCM_MAKE_CHAR (SCM_STRING_UCHARS (v
)[pos
]);
1113 case scm_tc7_byvect
:
1114 return scm_from_char (((char *) SCM_UVECTOR_BASE (v
))[pos
]);
1116 return scm_from_ulong (((unsigned long *) SCM_VELTS (v
))[pos
]);
1118 return scm_from_long (((signed long *) SCM_VELTS (v
))[pos
]);
1121 return scm_from_short (((short *) SCM_CELL_WORD_1 (v
))[pos
]);
1122 #if SCM_SIZEOF_LONG_LONG != 0
1123 case scm_tc7_llvect
:
1124 return scm_from_long_long (((long long *) SCM_CELL_WORD_1 (v
))[pos
]);
1128 return scm_make_real (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1130 return scm_make_real (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1132 return scm_make_complex (((double *) SCM_CELL_WORD_1 (v
))[2 * pos
],
1133 ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1]);
1134 case scm_tc7_vector
:
1136 return SCM_VELTS (v
)[pos
];
1141 /* Internal version of scm_uniform_vector_ref for uves that does no error checking and
1142 tries to recycle conses. (Make *sure* you want them recycled.) */
1145 scm_cvref (SCM v
, unsigned long pos
, SCM last
)
1146 #define FUNC_NAME "scm_cvref"
1151 SCM_WRONG_TYPE_ARG (SCM_ARG1
, v
);
1153 if (SCM_BITVEC_REF(v
, pos
))
1157 case scm_tc7_string
:
1158 return SCM_MAKE_CHAR (SCM_STRING_UCHARS (v
)[pos
]);
1159 case scm_tc7_byvect
:
1160 return scm_from_char (((char *) SCM_UVECTOR_BASE (v
))[pos
]);
1162 return scm_from_ulong (((unsigned long *) SCM_VELTS (v
))[pos
]);
1164 return scm_from_long (((signed long *) SCM_VELTS (v
))[pos
]);
1166 return scm_from_short (((short *) SCM_CELL_WORD_1 (v
))[pos
]);
1167 #if SCM_SIZEOF_LONG_LONG != 0
1168 case scm_tc7_llvect
:
1169 return scm_from_long_long (((long long *) SCM_CELL_WORD_1 (v
))[pos
]);
1172 if (SCM_REALP (last
) && !scm_is_eq (last
, scm_flo0
))
1174 SCM_REAL_VALUE (last
) = ((float *) SCM_CELL_WORD_1 (v
))[pos
];
1177 return scm_make_real (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1179 if (SCM_REALP (last
) && !scm_is_eq (last
, scm_flo0
))
1181 SCM_REAL_VALUE (last
) = ((double *) SCM_CELL_WORD_1 (v
))[pos
];
1184 return scm_make_real (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1186 if (SCM_COMPLEXP (last
))
1188 SCM_COMPLEX_REAL (last
) = ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
];
1189 SCM_COMPLEX_IMAG (last
) = ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1];
1192 return scm_make_complex (((double *) SCM_CELL_WORD_1 (v
))[2 * pos
],
1193 ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1]);
1194 case scm_tc7_vector
:
1196 return SCM_VELTS (v
)[pos
];
1198 { /* enclosed scm_array */
1199 int k
= SCM_ARRAY_NDIM (v
);
1200 SCM res
= scm_make_ra (k
);
1201 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1202 SCM_ARRAY_BASE (res
) = pos
;
1205 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1206 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1207 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1216 SCM_REGISTER_PROC(s_uniform_array_set1_x
, "uniform-array-set1!", 3, 0, 0, scm_array_set_x
);
1219 /* Note that args may be a list or an immediate object, depending which
1220 PROC is used (and it's called from C too). */
1221 SCM_DEFINE (scm_array_set_x
, "array-set!", 2, 0, 1,
1222 (SCM v
, SCM obj
, SCM args
),
1223 "@deffnx {Scheme Procedure} uniform-array-set1! v obj args\n"
1224 "Set the element at the @code{(index1, index2)} element in @var{array} to\n"
1225 "@var{new-value}. The value returned by array-set! is unspecified.")
1226 #define FUNC_NAME s_scm_array_set_x
1230 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1233 pos
= scm_aind (v
, args
, FUNC_NAME
);
1234 v
= SCM_ARRAY_V (v
);
1238 unsigned long int length
;
1239 if (SCM_CONSP (args
))
1241 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1242 pos
= scm_to_long (SCM_CAR (args
));
1246 pos
= scm_to_long (args
);
1248 length
= scm_to_ulong (scm_uniform_vector_length (v
));
1249 SCM_ASRTGO (pos
>= 0 && pos
< length
, outrng
);
1251 switch (SCM_TYP7 (v
))
1254 SCM_WRONG_TYPE_ARG (1, v
);
1257 scm_out_of_range (FUNC_NAME
, scm_from_long (pos
));
1259 SCM_WRONG_NUM_ARGS ();
1260 case scm_tc7_smob
: /* enclosed */
1263 if (scm_is_false (obj
))
1264 SCM_BITVEC_CLR(v
, pos
);
1265 else if (scm_is_eq (obj
, SCM_BOOL_T
))
1266 SCM_BITVEC_SET(v
, pos
);
1268 badobj
:SCM_WRONG_TYPE_ARG (2, obj
);
1270 case scm_tc7_string
:
1271 SCM_ASRTGO (SCM_CHARP (obj
), badobj
);
1272 SCM_STRING_UCHARS (v
)[pos
] = SCM_CHAR (obj
);
1274 case scm_tc7_byvect
:
1275 if (SCM_CHARP (obj
))
1276 obj
= scm_from_char ((char) SCM_CHAR (obj
));
1277 ((char *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_char (obj
);
1280 ((unsigned long *) SCM_UVECTOR_BASE (v
))[pos
]
1281 = scm_num2ulong (obj
, SCM_ARG2
, FUNC_NAME
);
1284 ((long *) SCM_UVECTOR_BASE (v
))[pos
]
1285 = scm_num2long (obj
, SCM_ARG2
, FUNC_NAME
);
1288 ((short *) SCM_UVECTOR_BASE (v
))[pos
]
1289 = scm_num2short (obj
, SCM_ARG2
, FUNC_NAME
);
1291 #if SCM_SIZEOF_LONG_LONG != 0
1292 case scm_tc7_llvect
:
1293 ((long long *) SCM_UVECTOR_BASE (v
))[pos
]
1294 = scm_num2long_long (obj
, SCM_ARG2
, FUNC_NAME
);
1298 ((float *) SCM_UVECTOR_BASE (v
))[pos
]
1299 = (float) scm_num2dbl (obj
, FUNC_NAME
);
1302 ((double *) SCM_UVECTOR_BASE (v
))[pos
]
1303 = scm_num2dbl (obj
, FUNC_NAME
);
1306 SCM_ASRTGO (SCM_INEXACTP (obj
), badobj
);
1307 if (SCM_REALP (obj
)) {
1308 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
] = SCM_REAL_VALUE (obj
);
1309 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
+ 1] = 0.0;
1311 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
] = SCM_COMPLEX_REAL (obj
);
1312 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
+ 1] = SCM_COMPLEX_IMAG (obj
);
1315 case scm_tc7_vector
:
1317 SCM_VECTOR_SET (v
, pos
, obj
);
1320 return SCM_UNSPECIFIED
;
1324 /* attempts to unroll an array into a one-dimensional array.
1325 returns the unrolled array or #f if it can't be done. */
1326 /* if strict is not SCM_UNDEFINED, return #f if returned array
1327 wouldn't have contiguous elements. */
1328 SCM_DEFINE (scm_array_contents
, "array-contents", 1, 1, 0,
1329 (SCM ra
, SCM strict
),
1330 "If @var{array} may be @dfn{unrolled} into a one dimensional shared array\n"
1331 "without changing their order (last subscript changing fastest), then\n"
1332 "@code{array-contents} returns that shared array, otherwise it returns\n"
1333 "@code{#f}. All arrays made by @var{make-array} and\n"
1334 "@var{make-uniform-array} may be unrolled, some arrays made by\n"
1335 "@var{make-shared-array} may not be.\n\n"
1336 "If the optional argument @var{strict} is provided, a shared array will\n"
1337 "be returned only if its elements are stored internally contiguous in\n"
1339 #define FUNC_NAME s_scm_array_contents
1344 switch SCM_TYP7 (ra
)
1348 case scm_tc7_vector
:
1350 case scm_tc7_string
:
1352 case scm_tc7_byvect
:
1359 #if SCM_SIZEOF_LONG_LONG != 0
1360 case scm_tc7_llvect
:
1365 size_t k
, ndim
= SCM_ARRAY_NDIM (ra
), len
= 1;
1366 if (!SCM_ARRAYP (ra
) || !SCM_ARRAY_CONTP (ra
))
1368 for (k
= 0; k
< ndim
; k
++)
1369 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1370 if (!SCM_UNBNDP (strict
))
1372 if (ndim
&& (1 != SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
))
1374 if (scm_tc7_bvect
== SCM_TYP7 (SCM_ARRAY_V (ra
)))
1376 if (len
!= SCM_BITVECTOR_LENGTH (SCM_ARRAY_V (ra
)) ||
1377 SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
||
1384 SCM v
= SCM_ARRAY_V (ra
);
1385 unsigned long length
= scm_to_ulong (scm_uniform_vector_length (v
));
1386 if ((len
== length
) && 0 == SCM_ARRAY_BASE (ra
) && SCM_ARRAY_DIMS (ra
)->inc
)
1390 sra
= scm_make_ra (1);
1391 SCM_ARRAY_DIMS (sra
)->lbnd
= 0;
1392 SCM_ARRAY_DIMS (sra
)->ubnd
= len
- 1;
1393 SCM_ARRAY_V (sra
) = SCM_ARRAY_V (ra
);
1394 SCM_ARRAY_BASE (sra
) = SCM_ARRAY_BASE (ra
);
1395 SCM_ARRAY_DIMS (sra
)->inc
= (ndim
? SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
: 1);
1404 scm_ra2contig (SCM ra
, int copy
)
1409 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
1410 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1411 k
= SCM_ARRAY_NDIM (ra
);
1412 if (SCM_ARRAY_CONTP (ra
) && ((0 == k
) || (1 == SCM_ARRAY_DIMS (ra
)[k
- 1].inc
)))
1414 if (scm_tc7_bvect
!= SCM_TYP7 (SCM_ARRAY_V (ra
)))
1416 if ((len
== SCM_BITVECTOR_LENGTH (SCM_ARRAY_V (ra
)) &&
1417 0 == SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
&&
1418 0 == len
% SCM_LONG_BIT
))
1421 ret
= scm_make_ra (k
);
1422 SCM_ARRAY_BASE (ret
) = 0;
1425 SCM_ARRAY_DIMS (ret
)[k
].lbnd
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
;
1426 SCM_ARRAY_DIMS (ret
)[k
].ubnd
= SCM_ARRAY_DIMS (ra
)[k
].ubnd
;
1427 SCM_ARRAY_DIMS (ret
)[k
].inc
= inc
;
1428 inc
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1430 SCM_ARRAY_V (ret
) = scm_make_uve (inc
, scm_array_prototype (ra
));
1432 scm_array_copy_x (ra
, ret
);
1438 SCM_DEFINE (scm_uniform_array_read_x
, "uniform-array-read!", 1, 3, 0,
1439 (SCM ra
, SCM port_or_fd
, SCM start
, SCM end
),
1440 "@deffnx {Scheme Procedure} uniform-vector-read! uve [port-or-fdes] [start] [end]\n"
1441 "Attempt to read all elements of @var{ura}, in lexicographic order, as\n"
1442 "binary objects from @var{port-or-fdes}.\n"
1443 "If an end of file is encountered,\n"
1444 "the objects up to that point are put into @var{ura}\n"
1445 "(starting at the beginning) and the remainder of the array is\n"
1447 "The optional arguments @var{start} and @var{end} allow\n"
1448 "a specified region of a vector (or linearized array) to be read,\n"
1449 "leaving the remainder of the vector unchanged.\n\n"
1450 "@code{uniform-array-read!} returns the number of objects read.\n"
1451 "@var{port-or-fdes} may be omitted, in which case it defaults to the value\n"
1452 "returned by @code{(current-input-port)}.")
1453 #define FUNC_NAME s_scm_uniform_array_read_x
1455 SCM cra
= SCM_UNDEFINED
, v
= ra
;
1462 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1463 if (SCM_UNBNDP (port_or_fd
))
1464 port_or_fd
= scm_cur_inp
;
1466 SCM_ASSERT (scm_is_integer (port_or_fd
)
1467 || (SCM_OPINPORTP (port_or_fd
)),
1468 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1469 vlen
= (SCM_TYP7 (v
) == scm_tc7_smob
1471 : scm_to_long (scm_uniform_vector_length (v
)));
1477 badarg1
:SCM_WRONG_TYPE_ARG (SCM_ARG1
, v
);
1479 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1480 cra
= scm_ra2contig (ra
, 0);
1481 cstart
+= SCM_ARRAY_BASE (cra
);
1482 vlen
= SCM_ARRAY_DIMS (cra
)->inc
*
1483 (SCM_ARRAY_DIMS (cra
)->ubnd
- SCM_ARRAY_DIMS (cra
)->lbnd
+ 1);
1484 v
= SCM_ARRAY_V (cra
);
1486 case scm_tc7_string
:
1487 base
= SCM_STRING_CHARS (v
);
1491 base
= (char *) SCM_BITVECTOR_BASE (v
);
1492 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1493 cstart
/= SCM_LONG_BIT
;
1496 case scm_tc7_byvect
:
1497 base
= (char *) SCM_UVECTOR_BASE (v
);
1502 base
= (char *) SCM_UVECTOR_BASE (v
);
1506 base
= (char *) SCM_UVECTOR_BASE (v
);
1507 sz
= sizeof (short);
1509 #if SCM_SIZEOF_LONG_LONG != 0
1510 case scm_tc7_llvect
:
1511 base
= (char *) SCM_UVECTOR_BASE (v
);
1512 sz
= sizeof (long long);
1516 base
= (char *) SCM_UVECTOR_BASE (v
);
1517 sz
= sizeof (float);
1520 base
= (char *) SCM_UVECTOR_BASE (v
);
1521 sz
= sizeof (double);
1524 base
= (char *) SCM_UVECTOR_BASE (v
);
1525 sz
= 2 * sizeof (double);
1530 if (!SCM_UNBNDP (start
))
1533 SCM_NUM2LONG (3, start
);
1535 if (offset
< 0 || offset
>= cend
)
1536 scm_out_of_range (FUNC_NAME
, start
);
1538 if (!SCM_UNBNDP (end
))
1541 SCM_NUM2LONG (4, end
);
1543 if (tend
<= offset
|| tend
> cend
)
1544 scm_out_of_range (FUNC_NAME
, end
);
1549 if (SCM_NIMP (port_or_fd
))
1551 scm_t_port
*pt
= SCM_PTAB_ENTRY (port_or_fd
);
1552 int remaining
= (cend
- offset
) * sz
;
1553 char *dest
= base
+ (cstart
+ offset
) * sz
;
1555 if (pt
->rw_active
== SCM_PORT_WRITE
)
1556 scm_flush (port_or_fd
);
1558 ans
= cend
- offset
;
1559 while (remaining
> 0)
1561 if (pt
->read_pos
< pt
->read_end
)
1563 int to_copy
= min (pt
->read_end
- pt
->read_pos
,
1566 memcpy (dest
, pt
->read_pos
, to_copy
);
1567 pt
->read_pos
+= to_copy
;
1568 remaining
-= to_copy
;
1573 if (scm_fill_input (port_or_fd
) == EOF
)
1575 if (remaining
% sz
!= 0)
1577 SCM_MISC_ERROR ("unexpected EOF", SCM_EOL
);
1579 ans
-= remaining
/ sz
;
1586 pt
->rw_active
= SCM_PORT_READ
;
1588 else /* file descriptor. */
1590 SCM_SYSCALL (ans
= read (scm_to_int (port_or_fd
),
1591 base
+ (cstart
+ offset
) * sz
,
1592 (sz
* (cend
- offset
))));
1596 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1597 ans
*= SCM_LONG_BIT
;
1599 if (!scm_is_eq (v
, ra
) && !scm_is_eq (cra
, ra
))
1600 scm_array_copy_x (cra
, ra
);
1602 return scm_from_long (ans
);
1606 SCM_DEFINE (scm_uniform_array_write
, "uniform-array-write", 1, 3, 0,
1607 (SCM v
, SCM port_or_fd
, SCM start
, SCM end
),
1608 "@deffnx {Scheme Procedure} uniform-vector-write uve [port-or-fdes] [start] [end]\n"
1609 "Writes all elements of @var{ura} as binary objects to\n"
1610 "@var{port-or-fdes}.\n\n"
1611 "The optional arguments @var{start}\n"
1612 "and @var{end} allow\n"
1613 "a specified region of a vector (or linearized array) to be written.\n\n"
1614 "The number of objects actually written is returned.\n"
1615 "@var{port-or-fdes} may be\n"
1616 "omitted, in which case it defaults to the value returned by\n"
1617 "@code{(current-output-port)}.")
1618 #define FUNC_NAME s_scm_uniform_array_write
1626 port_or_fd
= SCM_COERCE_OUTPORT (port_or_fd
);
1628 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1629 if (SCM_UNBNDP (port_or_fd
))
1630 port_or_fd
= scm_cur_outp
;
1632 SCM_ASSERT (scm_is_integer (port_or_fd
)
1633 || (SCM_OPOUTPORTP (port_or_fd
)),
1634 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1635 vlen
= (SCM_TYP7 (v
) == scm_tc7_smob
1637 : scm_to_long (scm_uniform_vector_length (v
)));
1643 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
1645 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1646 v
= scm_ra2contig (v
, 1);
1647 cstart
= SCM_ARRAY_BASE (v
);
1648 vlen
= (SCM_ARRAY_DIMS (v
)->inc
1649 * (SCM_ARRAY_DIMS (v
)->ubnd
- SCM_ARRAY_DIMS (v
)->lbnd
+ 1));
1650 v
= SCM_ARRAY_V (v
);
1652 case scm_tc7_string
:
1653 base
= SCM_STRING_CHARS (v
);
1657 base
= (char *) SCM_BITVECTOR_BASE (v
);
1658 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1659 cstart
/= SCM_LONG_BIT
;
1662 case scm_tc7_byvect
:
1663 base
= (char *) SCM_UVECTOR_BASE (v
);
1668 base
= (char *) SCM_UVECTOR_BASE (v
);
1672 base
= (char *) SCM_UVECTOR_BASE (v
);
1673 sz
= sizeof (short);
1675 #if SCM_SIZEOF_LONG_LONG != 0
1676 case scm_tc7_llvect
:
1677 base
= (char *) SCM_UVECTOR_BASE (v
);
1678 sz
= sizeof (long long);
1682 base
= (char *) SCM_UVECTOR_BASE (v
);
1683 sz
= sizeof (float);
1686 base
= (char *) SCM_UVECTOR_BASE (v
);
1687 sz
= sizeof (double);
1690 base
= (char *) SCM_UVECTOR_BASE (v
);
1691 sz
= 2 * sizeof (double);
1696 if (!SCM_UNBNDP (start
))
1699 SCM_NUM2LONG (3, start
);
1701 if (offset
< 0 || offset
>= cend
)
1702 scm_out_of_range (FUNC_NAME
, start
);
1704 if (!SCM_UNBNDP (end
))
1707 SCM_NUM2LONG (4, end
);
1709 if (tend
<= offset
|| tend
> cend
)
1710 scm_out_of_range (FUNC_NAME
, end
);
1715 if (SCM_NIMP (port_or_fd
))
1717 char *source
= base
+ (cstart
+ offset
) * sz
;
1719 ans
= cend
- offset
;
1720 scm_lfwrite (source
, ans
* sz
, port_or_fd
);
1722 else /* file descriptor. */
1724 SCM_SYSCALL (ans
= write (scm_to_int (port_or_fd
),
1725 base
+ (cstart
+ offset
) * sz
,
1726 (sz
* (cend
- offset
))));
1730 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1731 ans
*= SCM_LONG_BIT
;
1733 return scm_from_long (ans
);
1738 static char cnt_tab
[16] =
1739 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1741 SCM_DEFINE (scm_bit_count
, "bit-count", 2, 0, 0,
1742 (SCM b
, SCM bitvector
),
1743 "Return the number of occurrences of the boolean @var{b} in\n"
1745 #define FUNC_NAME s_scm_bit_count
1747 SCM_VALIDATE_BOOL (1, b
);
1748 SCM_ASSERT (SCM_BITVECTOR_P (bitvector
), bitvector
, 2, FUNC_NAME
);
1749 if (SCM_BITVECTOR_LENGTH (bitvector
) == 0) {
1752 unsigned long int count
= 0;
1753 unsigned long int i
= (SCM_BITVECTOR_LENGTH (bitvector
) - 1) / SCM_LONG_BIT
;
1754 unsigned long int w
= SCM_UNPACK (SCM_VELTS (bitvector
)[i
]);
1755 if (scm_is_false (b
)) {
1758 w
<<= SCM_LONG_BIT
- 1 - ((SCM_BITVECTOR_LENGTH (bitvector
) - 1) % SCM_LONG_BIT
);
1761 count
+= cnt_tab
[w
& 0x0f];
1765 return scm_from_ulong (count
);
1768 w
= SCM_UNPACK (SCM_VELTS (bitvector
)[i
]);
1769 if (scm_is_false (b
)) {
1779 SCM_DEFINE (scm_bit_position
, "bit-position", 3, 0, 0,
1780 (SCM item
, SCM v
, SCM k
),
1781 "Return the index of the first occurrance of @var{item} in bit\n"
1782 "vector @var{v}, starting from @var{k}. If there is no\n"
1783 "@var{item} entry between @var{k} and the end of\n"
1784 "@var{bitvector}, then return @code{#f}. For example,\n"
1787 "(bit-position #t #*000101 0) @result{} 3\n"
1788 "(bit-position #f #*0001111 3) @result{} #f\n"
1790 #define FUNC_NAME s_scm_bit_position
1792 long i
, lenw
, xbits
, pos
;
1793 register unsigned long w
;
1795 SCM_VALIDATE_BOOL (1, item
);
1796 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG2
, FUNC_NAME
);
1797 pos
= scm_to_long (k
);
1798 SCM_ASSERT_RANGE (3, k
, (pos
<= SCM_BITVECTOR_LENGTH (v
)) && (pos
>= 0));
1800 if (pos
== SCM_BITVECTOR_LENGTH (v
))
1803 lenw
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
; /* watch for part words */
1804 i
= pos
/ SCM_LONG_BIT
;
1805 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1806 if (scm_is_false (item
))
1808 xbits
= (pos
% SCM_LONG_BIT
);
1810 w
= ((w
>> xbits
) << xbits
);
1811 xbits
= SCM_LONG_BIT
- 1 - (SCM_BITVECTOR_LENGTH (v
) - 1) % SCM_LONG_BIT
;
1814 if (w
&& (i
== lenw
))
1815 w
= ((w
<< xbits
) >> xbits
);
1821 return scm_from_long (pos
);
1826 return scm_from_long (pos
+ 1);
1829 return scm_from_long (pos
+ 2);
1831 return scm_from_long (pos
+ 3);
1838 pos
+= SCM_LONG_BIT
;
1839 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1840 if (scm_is_false (item
))
1848 SCM_DEFINE (scm_bit_set_star_x
, "bit-set*!", 3, 0, 0,
1849 (SCM v
, SCM kv
, SCM obj
),
1850 "Set entries of bit vector @var{v} to @var{obj}, with @var{kv}\n"
1851 "selecting the entries to change. The return value is\n"
1854 "If @var{kv} is a bit vector, then those entries where it has\n"
1855 "@code{#t} are the ones in @var{v} which are set to @var{obj}.\n"
1856 "@var{kv} and @var{v} must be the same length. When @var{obj}\n"
1857 "is @code{#t} it's like @var{kv} is OR'ed into @var{v}. Or when\n"
1858 "@var{obj} is @code{#f} it can be seen as an ANDNOT.\n"
1861 "(define bv #*01000010)\n"
1862 "(bit-set*! bv #*10010001 #t)\n"
1864 "@result{} #*11010011\n"
1867 "If @var{kv} is a uniform vector of unsigned long integers, then\n"
1868 "they're indexes into @var{v} which are set to @var{obj}.\n"
1871 "(define bv #*01000010)\n"
1872 "(bit-set*! bv #u(5 2 7) #t)\n"
1874 "@result{} #*01100111\n"
1876 #define FUNC_NAME s_scm_bit_set_star_x
1878 register long i
, k
, vlen
;
1879 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
1880 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1881 switch SCM_TYP7 (kv
)
1884 badarg2
:SCM_WRONG_TYPE_ARG (2, kv
);
1886 vlen
= SCM_BITVECTOR_LENGTH (v
);
1887 if (scm_is_false (obj
))
1888 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1890 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1892 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
1893 SCM_BITVEC_CLR(v
, k
);
1895 else if (scm_is_eq (obj
, SCM_BOOL_T
))
1896 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1898 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1900 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
1901 SCM_BITVEC_SET(v
, k
);
1904 badarg3
:SCM_WRONG_TYPE_ARG (3, obj
);
1907 SCM_ASSERT (SCM_BITVECTOR_LENGTH (v
) == SCM_BITVECTOR_LENGTH (kv
), v
, SCM_ARG1
, FUNC_NAME
);
1908 if (scm_is_false (obj
))
1909 for (k
= (SCM_BITVECTOR_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1910 SCM_BITVECTOR_BASE (v
) [k
] &= ~SCM_BITVECTOR_BASE (kv
) [k
];
1911 else if (scm_is_eq (obj
, SCM_BOOL_T
))
1912 for (k
= (SCM_BITVECTOR_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1913 SCM_BITVECTOR_BASE (v
) [k
] |= SCM_BITVECTOR_BASE (kv
) [k
];
1918 return SCM_UNSPECIFIED
;
1923 SCM_DEFINE (scm_bit_count_star
, "bit-count*", 3, 0, 0,
1924 (SCM v
, SCM kv
, SCM obj
),
1925 "Return a count of how many entries in bit vector @var{v} are\n"
1926 "equal to @var{obj}, with @var{kv} selecting the entries to\n"
1929 "If @var{kv} is a bit vector, then those entries where it has\n"
1930 "@code{#t} are the ones in @var{v} which are considered.\n"
1931 "@var{kv} and @var{v} must be the same length.\n"
1933 "If @var{kv} is a uniform vector of unsigned long integers, then\n"
1934 "it's the indexes in @var{v} to consider.\n"
1939 "(bit-count* #*01110111 #*11001101 #t) @result{} 3\n"
1940 "(bit-count* #*01110111 #u(7 0 4) #f) @result{} 2\n"
1942 #define FUNC_NAME s_scm_bit_count_star
1944 register long i
, vlen
, count
= 0;
1945 register unsigned long k
;
1948 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
1949 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1950 switch SCM_TYP7 (kv
)
1954 SCM_WRONG_TYPE_ARG (2, kv
);
1956 vlen
= SCM_BITVECTOR_LENGTH (v
);
1957 if (scm_is_false (obj
))
1958 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1960 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1962 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
1963 if (!SCM_BITVEC_REF(v
, k
))
1966 else if (scm_is_eq (obj
, SCM_BOOL_T
))
1967 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1969 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1971 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
1972 if (SCM_BITVEC_REF (v
, k
))
1976 badarg3
:SCM_WRONG_TYPE_ARG (3, obj
);
1979 SCM_ASSERT (SCM_BITVECTOR_LENGTH (v
) == SCM_BITVECTOR_LENGTH (kv
), v
, SCM_ARG1
, FUNC_NAME
);
1980 if (0 == SCM_BITVECTOR_LENGTH (v
))
1982 SCM_ASRTGO (scm_is_bool (obj
), badarg3
);
1983 fObj
= scm_is_eq (obj
, SCM_BOOL_T
);
1984 i
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
;
1985 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK (SCM_VELTS (v
)[i
]) : ~ SCM_UNPACK (SCM_VELTS (v
)[i
]));
1986 k
<<= SCM_LONG_BIT
- 1 - ((SCM_BITVECTOR_LENGTH (v
) - 1) % SCM_LONG_BIT
);
1990 count
+= cnt_tab
[k
& 0x0f];
1992 return scm_from_long (count
);
1994 /* urg. repetitive (see above.) */
1995 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK(SCM_VELTS (v
)[i
]) : ~SCM_UNPACK (SCM_VELTS (v
)[i
]));
1998 return scm_from_long (count
);
2003 SCM_DEFINE (scm_bit_invert_x
, "bit-invert!", 1, 0, 0,
2005 "Modify the bit vector @var{v} by replacing each element with\n"
2007 #define FUNC_NAME s_scm_bit_invert_x
2011 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
2013 k
= SCM_BITVECTOR_LENGTH (v
);
2014 for (k
= (k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
2015 SCM_BITVECTOR_BASE (v
) [k
] = ~SCM_BITVECTOR_BASE (v
) [k
];
2017 return SCM_UNSPECIFIED
;
2023 scm_istr2bve (char *str
, long len
)
2025 SCM v
= scm_make_uve (len
, SCM_BOOL_T
);
2026 long *data
= (long *) SCM_VELTS (v
);
2027 register unsigned long mask
;
2030 for (k
= 0; k
< (len
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
++)
2033 j
= len
- k
* SCM_LONG_BIT
;
2034 if (j
> SCM_LONG_BIT
)
2036 for (mask
= 1L; j
--; mask
<<= 1)
2054 ra2l (SCM ra
, unsigned long base
, unsigned long k
)
2056 register SCM res
= SCM_EOL
;
2057 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2059 if (SCM_ARRAY_DIMS (ra
)[k
].ubnd
< SCM_ARRAY_DIMS (ra
)[k
].lbnd
)
2061 i
= base
+ (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
) * inc
;
2062 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2067 res
= scm_cons (ra2l (ra
, i
, k
+ 1), res
);
2075 res
= scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra
), scm_from_size_t (i
)), res
);
2082 SCM_DEFINE (scm_array_to_list
, "array->list", 1, 0, 0,
2084 "Return a list consisting of all the elements, in order, of\n"
2086 #define FUNC_NAME s_scm_array_to_list
2090 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
2094 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
2096 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
2097 return ra2l (v
, SCM_ARRAY_BASE (v
), 0);
2098 case scm_tc7_vector
:
2100 return scm_vector_to_list (v
);
2101 case scm_tc7_string
:
2102 return scm_string_to_list (v
);
2105 long *data
= (long *) SCM_VELTS (v
);
2106 register unsigned long mask
;
2107 for (k
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
; k
> 0; k
--)
2108 for (mask
= 1UL << (SCM_LONG_BIT
- 1); mask
; mask
>>= 1)
2109 res
= scm_cons (scm_from_bool(((long *) data
)[k
] & mask
), res
);
2110 for (mask
= 1L << ((SCM_BITVECTOR_LENGTH (v
) % SCM_LONG_BIT
) - 1); mask
; mask
>>= 1)
2111 res
= scm_cons (scm_from_bool(((long *) data
)[k
] & mask
), res
);
2114 case scm_tc7_byvect
:
2116 signed char *data
= (signed char *) SCM_VELTS (v
);
2117 unsigned long k
= SCM_UVECTOR_LENGTH (v
);
2119 res
= scm_cons (scm_from_schar (data
[--k
]), res
);
2124 unsigned long *data
= (unsigned long *)SCM_VELTS(v
);
2125 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2126 res
= scm_cons(scm_from_ulong (data
[k
]), res
);
2131 long *data
= (long *)SCM_VELTS(v
);
2132 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2133 res
= scm_cons(scm_from_long (data
[k
]), res
);
2138 short *data
= (short *)SCM_VELTS(v
);
2139 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2140 res
= scm_cons(scm_short2num (data
[k
]), res
);
2143 #if SCM_SIZEOF_LONG_LONG != 0
2144 case scm_tc7_llvect
:
2146 long long *data
= (long long *)SCM_VELTS(v
);
2147 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2148 res
= scm_cons(scm_long_long2num(data
[k
]), res
);
2154 float *data
= (float *) SCM_VELTS (v
);
2155 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2156 res
= scm_cons (scm_make_real (data
[k
]), res
);
2161 double *data
= (double *) SCM_VELTS (v
);
2162 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2163 res
= scm_cons (scm_make_real (data
[k
]), res
);
2168 double (*data
)[2] = (double (*)[2]) SCM_VELTS (v
);
2169 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2170 res
= scm_cons (scm_make_complex (data
[k
][0], data
[k
][1]), res
);
2178 static int l2ra(SCM lst
, SCM ra
, unsigned long base
, unsigned long k
);
2180 SCM_DEFINE (scm_list_to_uniform_array
, "list->uniform-array", 3, 0, 0,
2181 (SCM ndim
, SCM prot
, SCM lst
),
2182 "@deffnx {Scheme Procedure} list->uniform-vector prot lst\n"
2183 "Return a uniform array of the type indicated by prototype\n"
2184 "@var{prot} with elements the same as those of @var{lst}.\n"
2185 "Elements must be of the appropriate type, no coercions are\n"
2187 #define FUNC_NAME s_scm_list_to_uniform_array
2194 k
= scm_to_ulong (ndim
);
2197 n
= scm_ilength (row
);
2198 SCM_ASSERT (n
>= 0, lst
, SCM_ARG3
, FUNC_NAME
);
2199 shp
= scm_cons (scm_from_long (n
), shp
);
2201 row
= SCM_CAR (row
);
2203 ra
= scm_dimensions_to_uniform_array (scm_reverse (shp
), prot
,
2205 if (SCM_NULLP (shp
))
2207 SCM_ASRTGO (1 == scm_ilength (lst
), badlst
);
2208 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_EOL
);
2211 if (!SCM_ARRAYP (ra
))
2213 unsigned long length
= scm_to_ulong (scm_uniform_vector_length (ra
));
2214 for (k
= 0; k
< length
; k
++, lst
= SCM_CDR (lst
))
2215 scm_array_set_x (ra
, SCM_CAR (lst
), scm_from_ulong (k
));
2218 if (l2ra (lst
, ra
, SCM_ARRAY_BASE (ra
), 0))
2221 badlst
:SCM_MISC_ERROR ("Bad scm_array contents list: ~S",
2227 l2ra (SCM lst
, SCM ra
, unsigned long base
, unsigned long k
)
2229 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2230 register long n
= (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
);
2233 return (SCM_NULLP (lst
));
2234 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2238 if (!SCM_CONSP (lst
))
2240 ok
= ok
&& l2ra (SCM_CAR (lst
), ra
, base
, k
+ 1);
2242 lst
= SCM_CDR (lst
);
2244 if (!SCM_NULLP (lst
))
2251 if (!SCM_CONSP (lst
))
2253 scm_array_set_x (SCM_ARRAY_V (ra
), SCM_CAR (lst
), scm_from_ulong (base
));
2255 lst
= SCM_CDR (lst
);
2257 if (!SCM_NULLP (lst
))
2265 rapr1 (SCM ra
, unsigned long j
, unsigned long k
, SCM port
, scm_print_state
*pstate
)
2268 long n
= (SCM_TYP7 (ra
) == scm_tc7_smob
2270 : scm_to_long (scm_uniform_vector_length (ra
)));
2273 switch SCM_TYP7 (ra
)
2278 SCM_ARRAY_BASE (ra
) = j
;
2280 scm_iprin1 (ra
, port
, pstate
);
2281 for (j
+= inc
; n
-- > 0; j
+= inc
)
2283 scm_putc (' ', port
);
2284 SCM_ARRAY_BASE (ra
) = j
;
2285 scm_iprin1 (ra
, port
, pstate
);
2289 if (k
+ 1 < SCM_ARRAY_NDIM (ra
))
2292 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2293 for (i
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
; i
< SCM_ARRAY_DIMS (ra
)[k
].ubnd
; i
++)
2295 scm_putc ('(', port
);
2296 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2297 scm_puts (") ", port
);
2300 if (i
== SCM_ARRAY_DIMS (ra
)[k
].ubnd
)
2301 { /* could be zero size. */
2302 scm_putc ('(', port
);
2303 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2304 scm_putc (')', port
);
2308 if (SCM_ARRAY_NDIM (ra
) > 0)
2309 { /* Could be zero-dimensional */
2310 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2311 n
= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
2315 ra
= SCM_ARRAY_V (ra
);
2318 /* scm_tc7_bvect and scm_tc7_llvect only? */
2320 scm_iprin1 (scm_uniform_vector_ref (ra
, scm_from_ulong (j
)), port
, pstate
);
2321 for (j
+= inc
; n
-- > 0; j
+= inc
)
2323 scm_putc (' ', port
);
2324 scm_iprin1 (scm_cvref (ra
, j
, SCM_UNDEFINED
), port
, pstate
);
2327 case scm_tc7_string
:
2329 scm_iprin1 (SCM_MAKE_CHAR (SCM_STRING_UCHARS (ra
)[j
]), port
, pstate
);
2330 if (SCM_WRITINGP (pstate
))
2331 for (j
+= inc
; n
-- > 0; j
+= inc
)
2333 scm_putc (' ', port
);
2334 scm_iprin1 (SCM_MAKE_CHAR (SCM_STRING_UCHARS (ra
)[j
]), port
, pstate
);
2337 for (j
+= inc
; n
-- > 0; j
+= inc
)
2338 scm_putc (SCM_STRING_CHARS (ra
)[j
], port
);
2340 case scm_tc7_byvect
:
2342 scm_intprint (((char *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2343 for (j
+= inc
; n
-- > 0; j
+= inc
)
2345 scm_putc (' ', port
);
2346 scm_intprint (((char *)SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2356 /* intprint can't handle >= 2^31. */
2357 sprintf (str
, "%lu", ((unsigned long *) SCM_VELTS (ra
))[j
]);
2358 scm_puts (str
, port
);
2360 for (j
+= inc
; n
-- > 0; j
+= inc
)
2362 scm_putc (' ', port
);
2363 sprintf (str
, "%lu", ((unsigned long *) SCM_VELTS (ra
))[j
]);
2364 scm_puts (str
, port
);
2369 scm_intprint (((signed long *) SCM_VELTS (ra
))[j
], 10, port
);
2370 for (j
+= inc
; n
-- > 0; j
+= inc
)
2372 scm_putc (' ', port
);
2373 scm_intprint (((signed long *) SCM_VELTS (ra
))[j
], 10, port
);
2379 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2380 for (j
+= inc
; n
-- > 0; j
+= inc
)
2382 scm_putc (' ', port
);
2383 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2390 SCM z
= scm_make_real (1.0);
2391 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2392 scm_print_real (z
, port
, pstate
);
2393 for (j
+= inc
; n
-- > 0; j
+= inc
)
2395 scm_putc (' ', port
);
2396 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2397 scm_print_real (z
, port
, pstate
);
2404 SCM z
= scm_make_real (1.0 / 3.0);
2405 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2406 scm_print_real (z
, port
, pstate
);
2407 for (j
+= inc
; n
-- > 0; j
+= inc
)
2409 scm_putc (' ', port
);
2410 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2411 scm_print_real (z
, port
, pstate
);
2418 SCM cz
= scm_make_complex (0.0, 1.0), z
= scm_make_real (1.0 / 3.0);
2419 SCM_REAL_VALUE (z
) =
2420 SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2421 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2422 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2424 for (j
+= inc
; n
-- > 0; j
+= inc
)
2426 scm_putc (' ', port
);
2428 = SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2429 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2430 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2441 scm_raprin1 (SCM exp
, SCM port
, scm_print_state
*pstate
)
2444 unsigned long base
= 0;
2445 scm_putc ('#', port
);
2451 long ndim
= SCM_ARRAY_NDIM (v
);
2452 base
= SCM_ARRAY_BASE (v
);
2453 v
= SCM_ARRAY_V (v
);
2457 scm_puts ("<enclosed-array ", port
);
2458 rapr1 (exp
, base
, 0, port
, pstate
);
2459 scm_putc ('>', port
);
2464 scm_intprint (ndim
, 10, port
);
2469 if (scm_is_eq (exp
, v
))
2470 { /* a uve, not an scm_array */
2471 register long i
, j
, w
;
2472 scm_putc ('*', port
);
2473 for (i
= 0; i
< (SCM_BITVECTOR_LENGTH (exp
)) / SCM_LONG_BIT
; i
++)
2475 scm_t_bits w
= SCM_UNPACK (SCM_VELTS (exp
)[i
]);
2476 for (j
= SCM_LONG_BIT
; j
; j
--)
2478 scm_putc (w
& 1 ? '1' : '0', port
);
2482 j
= SCM_BITVECTOR_LENGTH (exp
) % SCM_LONG_BIT
;
2485 w
= SCM_UNPACK (SCM_VELTS (exp
)[SCM_BITVECTOR_LENGTH (exp
) / SCM_LONG_BIT
]);
2488 scm_putc (w
& 1 ? '1' : '0', port
);
2495 scm_putc ('b', port
);
2497 case scm_tc7_string
:
2498 scm_putc ('a', port
);
2500 case scm_tc7_byvect
:
2501 scm_putc ('y', port
);
2504 scm_putc ('u', port
);
2507 scm_putc ('e', port
);
2510 scm_putc ('h', port
);
2512 #if SCM_SIZEOF_LONG_LONG != 0
2513 case scm_tc7_llvect
:
2514 scm_putc ('l', port
);
2518 scm_putc ('s', port
);
2521 scm_putc ('i', port
);
2524 scm_putc ('c', port
);
2527 scm_putc ('(', port
);
2528 rapr1 (exp
, base
, 0, port
, pstate
);
2529 scm_putc (')', port
);
2533 SCM_DEFINE (scm_array_prototype
, "array-prototype", 1, 0, 0,
2535 "Return an object that would produce an array of the same type\n"
2536 "as @var{array}, if used as the @var{prototype} for\n"
2537 "@code{make-uniform-array}.")
2538 #define FUNC_NAME s_scm_array_prototype
2541 SCM_ASRTGO (SCM_NIMP (ra
), badarg
);
2543 switch SCM_TYP7 (ra
)
2546 badarg
:SCM_WRONG_TYPE_ARG (1, ra
);
2548 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
2550 return SCM_UNSPECIFIED
;
2551 ra
= SCM_ARRAY_V (ra
);
2553 case scm_tc7_vector
:
2558 case scm_tc7_string
:
2559 return SCM_MAKE_CHAR ('a');
2560 case scm_tc7_byvect
:
2561 return SCM_MAKE_CHAR ('\0');
2563 return scm_from_int (1);
2565 return scm_from_int (-1);
2567 return scm_str2symbol ("s");
2568 #if SCM_SIZEOF_LONG_LONG != 0
2569 case scm_tc7_llvect
:
2570 return scm_str2symbol ("l");
2573 return scm_make_real (1.0);
2575 return exactly_one_third
;
2577 return scm_make_complex (0.0, 1.0);
2584 array_mark (SCM ptr
)
2586 return SCM_ARRAY_V (ptr
);
2591 array_free (SCM ptr
)
2593 scm_gc_free (SCM_ARRAY_MEM (ptr
),
2594 (sizeof (scm_t_array
)
2595 + SCM_ARRAY_NDIM (ptr
) * sizeof (scm_t_array_dim
)),
2603 scm_tc16_array
= scm_make_smob_type ("array", 0);
2604 scm_set_smob_mark (scm_tc16_array
, array_mark
);
2605 scm_set_smob_free (scm_tc16_array
, array_free
);
2606 scm_set_smob_print (scm_tc16_array
, scm_raprin1
);
2607 scm_set_smob_equalp (scm_tc16_array
, scm_array_equal_p
);
2608 exactly_one_third
= scm_permanent_object (scm_make_ratio (scm_from_int (1),
2610 scm_add_feature ("array");
2611 #include "libguile/unif.x"