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_from_long (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
))
160 SCM_ASSERT_RANGE (1, scm_from_long (k
),
161 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_from_double (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1130 return scm_from_double (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1132 return scm_c_make_rectangular (((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_from_double (((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_from_double (((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_c_make_rectangular (((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
] = scm_to_ulong (obj
);
1283 ((long *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_long (obj
);
1286 ((short *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_short (obj
);
1288 #if SCM_SIZEOF_LONG_LONG != 0
1289 case scm_tc7_llvect
:
1290 ((long long *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_long_long (obj
);
1294 ((float *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_double (obj
);
1297 ((double *) SCM_UVECTOR_BASE (v
))[pos
] = scm_to_double (obj
);
1300 SCM_ASRTGO (SCM_INEXACTP (obj
), badobj
);
1301 if (SCM_REALP (obj
)) {
1302 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
] = SCM_REAL_VALUE (obj
);
1303 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
+ 1] = 0.0;
1305 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
] = SCM_COMPLEX_REAL (obj
);
1306 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
+ 1] = SCM_COMPLEX_IMAG (obj
);
1309 case scm_tc7_vector
:
1311 SCM_VECTOR_SET (v
, pos
, obj
);
1314 return SCM_UNSPECIFIED
;
1318 /* attempts to unroll an array into a one-dimensional array.
1319 returns the unrolled array or #f if it can't be done. */
1320 /* if strict is not SCM_UNDEFINED, return #f if returned array
1321 wouldn't have contiguous elements. */
1322 SCM_DEFINE (scm_array_contents
, "array-contents", 1, 1, 0,
1323 (SCM ra
, SCM strict
),
1324 "If @var{array} may be @dfn{unrolled} into a one dimensional shared array\n"
1325 "without changing their order (last subscript changing fastest), then\n"
1326 "@code{array-contents} returns that shared array, otherwise it returns\n"
1327 "@code{#f}. All arrays made by @var{make-array} and\n"
1328 "@var{make-uniform-array} may be unrolled, some arrays made by\n"
1329 "@var{make-shared-array} may not be.\n\n"
1330 "If the optional argument @var{strict} is provided, a shared array will\n"
1331 "be returned only if its elements are stored internally contiguous in\n"
1333 #define FUNC_NAME s_scm_array_contents
1338 switch SCM_TYP7 (ra
)
1342 case scm_tc7_vector
:
1344 case scm_tc7_string
:
1346 case scm_tc7_byvect
:
1353 #if SCM_SIZEOF_LONG_LONG != 0
1354 case scm_tc7_llvect
:
1359 size_t k
, ndim
= SCM_ARRAY_NDIM (ra
), len
= 1;
1360 if (!SCM_ARRAYP (ra
) || !SCM_ARRAY_CONTP (ra
))
1362 for (k
= 0; k
< ndim
; k
++)
1363 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1364 if (!SCM_UNBNDP (strict
))
1366 if (ndim
&& (1 != SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
))
1368 if (scm_tc7_bvect
== SCM_TYP7 (SCM_ARRAY_V (ra
)))
1370 if (len
!= SCM_BITVECTOR_LENGTH (SCM_ARRAY_V (ra
)) ||
1371 SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
||
1378 SCM v
= SCM_ARRAY_V (ra
);
1379 unsigned long length
= scm_to_ulong (scm_uniform_vector_length (v
));
1380 if ((len
== length
) && 0 == SCM_ARRAY_BASE (ra
) && SCM_ARRAY_DIMS (ra
)->inc
)
1384 sra
= scm_make_ra (1);
1385 SCM_ARRAY_DIMS (sra
)->lbnd
= 0;
1386 SCM_ARRAY_DIMS (sra
)->ubnd
= len
- 1;
1387 SCM_ARRAY_V (sra
) = SCM_ARRAY_V (ra
);
1388 SCM_ARRAY_BASE (sra
) = SCM_ARRAY_BASE (ra
);
1389 SCM_ARRAY_DIMS (sra
)->inc
= (ndim
? SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
: 1);
1398 scm_ra2contig (SCM ra
, int copy
)
1403 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
1404 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1405 k
= SCM_ARRAY_NDIM (ra
);
1406 if (SCM_ARRAY_CONTP (ra
) && ((0 == k
) || (1 == SCM_ARRAY_DIMS (ra
)[k
- 1].inc
)))
1408 if (scm_tc7_bvect
!= SCM_TYP7 (SCM_ARRAY_V (ra
)))
1410 if ((len
== SCM_BITVECTOR_LENGTH (SCM_ARRAY_V (ra
)) &&
1411 0 == SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
&&
1412 0 == len
% SCM_LONG_BIT
))
1415 ret
= scm_make_ra (k
);
1416 SCM_ARRAY_BASE (ret
) = 0;
1419 SCM_ARRAY_DIMS (ret
)[k
].lbnd
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
;
1420 SCM_ARRAY_DIMS (ret
)[k
].ubnd
= SCM_ARRAY_DIMS (ra
)[k
].ubnd
;
1421 SCM_ARRAY_DIMS (ret
)[k
].inc
= inc
;
1422 inc
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1424 SCM_ARRAY_V (ret
) = scm_make_uve (inc
, scm_array_prototype (ra
));
1426 scm_array_copy_x (ra
, ret
);
1432 SCM_DEFINE (scm_uniform_array_read_x
, "uniform-array-read!", 1, 3, 0,
1433 (SCM ra
, SCM port_or_fd
, SCM start
, SCM end
),
1434 "@deffnx {Scheme Procedure} uniform-vector-read! uve [port-or-fdes] [start] [end]\n"
1435 "Attempt to read all elements of @var{ura}, in lexicographic order, as\n"
1436 "binary objects from @var{port-or-fdes}.\n"
1437 "If an end of file is encountered,\n"
1438 "the objects up to that point are put into @var{ura}\n"
1439 "(starting at the beginning) and the remainder of the array is\n"
1441 "The optional arguments @var{start} and @var{end} allow\n"
1442 "a specified region of a vector (or linearized array) to be read,\n"
1443 "leaving the remainder of the vector unchanged.\n\n"
1444 "@code{uniform-array-read!} returns the number of objects read.\n"
1445 "@var{port-or-fdes} may be omitted, in which case it defaults to the value\n"
1446 "returned by @code{(current-input-port)}.")
1447 #define FUNC_NAME s_scm_uniform_array_read_x
1449 SCM cra
= SCM_UNDEFINED
, v
= ra
;
1456 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1457 if (SCM_UNBNDP (port_or_fd
))
1458 port_or_fd
= scm_cur_inp
;
1460 SCM_ASSERT (scm_is_integer (port_or_fd
)
1461 || (SCM_OPINPORTP (port_or_fd
)),
1462 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1463 vlen
= (SCM_TYP7 (v
) == scm_tc7_smob
1465 : scm_to_long (scm_uniform_vector_length (v
)));
1471 badarg1
:SCM_WRONG_TYPE_ARG (SCM_ARG1
, v
);
1473 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1474 cra
= scm_ra2contig (ra
, 0);
1475 cstart
+= SCM_ARRAY_BASE (cra
);
1476 vlen
= SCM_ARRAY_DIMS (cra
)->inc
*
1477 (SCM_ARRAY_DIMS (cra
)->ubnd
- SCM_ARRAY_DIMS (cra
)->lbnd
+ 1);
1478 v
= SCM_ARRAY_V (cra
);
1480 case scm_tc7_string
:
1481 base
= SCM_STRING_CHARS (v
);
1485 base
= (char *) SCM_BITVECTOR_BASE (v
);
1486 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1487 cstart
/= SCM_LONG_BIT
;
1490 case scm_tc7_byvect
:
1491 base
= (char *) SCM_UVECTOR_BASE (v
);
1496 base
= (char *) SCM_UVECTOR_BASE (v
);
1500 base
= (char *) SCM_UVECTOR_BASE (v
);
1501 sz
= sizeof (short);
1503 #if SCM_SIZEOF_LONG_LONG != 0
1504 case scm_tc7_llvect
:
1505 base
= (char *) SCM_UVECTOR_BASE (v
);
1506 sz
= sizeof (long long);
1510 base
= (char *) SCM_UVECTOR_BASE (v
);
1511 sz
= sizeof (float);
1514 base
= (char *) SCM_UVECTOR_BASE (v
);
1515 sz
= sizeof (double);
1518 base
= (char *) SCM_UVECTOR_BASE (v
);
1519 sz
= 2 * sizeof (double);
1524 if (!SCM_UNBNDP (start
))
1527 SCM_NUM2LONG (3, start
);
1529 if (offset
< 0 || offset
>= cend
)
1530 scm_out_of_range (FUNC_NAME
, start
);
1532 if (!SCM_UNBNDP (end
))
1535 SCM_NUM2LONG (4, end
);
1537 if (tend
<= offset
|| tend
> cend
)
1538 scm_out_of_range (FUNC_NAME
, end
);
1543 if (SCM_NIMP (port_or_fd
))
1545 scm_t_port
*pt
= SCM_PTAB_ENTRY (port_or_fd
);
1546 int remaining
= (cend
- offset
) * sz
;
1547 char *dest
= base
+ (cstart
+ offset
) * sz
;
1549 if (pt
->rw_active
== SCM_PORT_WRITE
)
1550 scm_flush (port_or_fd
);
1552 ans
= cend
- offset
;
1553 while (remaining
> 0)
1555 if (pt
->read_pos
< pt
->read_end
)
1557 int to_copy
= min (pt
->read_end
- pt
->read_pos
,
1560 memcpy (dest
, pt
->read_pos
, to_copy
);
1561 pt
->read_pos
+= to_copy
;
1562 remaining
-= to_copy
;
1567 if (scm_fill_input (port_or_fd
) == EOF
)
1569 if (remaining
% sz
!= 0)
1571 SCM_MISC_ERROR ("unexpected EOF", SCM_EOL
);
1573 ans
-= remaining
/ sz
;
1580 pt
->rw_active
= SCM_PORT_READ
;
1582 else /* file descriptor. */
1584 SCM_SYSCALL (ans
= read (scm_to_int (port_or_fd
),
1585 base
+ (cstart
+ offset
) * sz
,
1586 (sz
* (cend
- offset
))));
1590 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1591 ans
*= SCM_LONG_BIT
;
1593 if (!scm_is_eq (v
, ra
) && !scm_is_eq (cra
, ra
))
1594 scm_array_copy_x (cra
, ra
);
1596 return scm_from_long (ans
);
1600 SCM_DEFINE (scm_uniform_array_write
, "uniform-array-write", 1, 3, 0,
1601 (SCM v
, SCM port_or_fd
, SCM start
, SCM end
),
1602 "@deffnx {Scheme Procedure} uniform-vector-write uve [port-or-fdes] [start] [end]\n"
1603 "Writes all elements of @var{ura} as binary objects to\n"
1604 "@var{port-or-fdes}.\n\n"
1605 "The optional arguments @var{start}\n"
1606 "and @var{end} allow\n"
1607 "a specified region of a vector (or linearized array) to be written.\n\n"
1608 "The number of objects actually written is returned.\n"
1609 "@var{port-or-fdes} may be\n"
1610 "omitted, in which case it defaults to the value returned by\n"
1611 "@code{(current-output-port)}.")
1612 #define FUNC_NAME s_scm_uniform_array_write
1620 port_or_fd
= SCM_COERCE_OUTPORT (port_or_fd
);
1622 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1623 if (SCM_UNBNDP (port_or_fd
))
1624 port_or_fd
= scm_cur_outp
;
1626 SCM_ASSERT (scm_is_integer (port_or_fd
)
1627 || (SCM_OPOUTPORTP (port_or_fd
)),
1628 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1629 vlen
= (SCM_TYP7 (v
) == scm_tc7_smob
1631 : scm_to_long (scm_uniform_vector_length (v
)));
1637 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
1639 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1640 v
= scm_ra2contig (v
, 1);
1641 cstart
= SCM_ARRAY_BASE (v
);
1642 vlen
= (SCM_ARRAY_DIMS (v
)->inc
1643 * (SCM_ARRAY_DIMS (v
)->ubnd
- SCM_ARRAY_DIMS (v
)->lbnd
+ 1));
1644 v
= SCM_ARRAY_V (v
);
1646 case scm_tc7_string
:
1647 base
= SCM_STRING_CHARS (v
);
1651 base
= (char *) SCM_BITVECTOR_BASE (v
);
1652 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1653 cstart
/= SCM_LONG_BIT
;
1656 case scm_tc7_byvect
:
1657 base
= (char *) SCM_UVECTOR_BASE (v
);
1662 base
= (char *) SCM_UVECTOR_BASE (v
);
1666 base
= (char *) SCM_UVECTOR_BASE (v
);
1667 sz
= sizeof (short);
1669 #if SCM_SIZEOF_LONG_LONG != 0
1670 case scm_tc7_llvect
:
1671 base
= (char *) SCM_UVECTOR_BASE (v
);
1672 sz
= sizeof (long long);
1676 base
= (char *) SCM_UVECTOR_BASE (v
);
1677 sz
= sizeof (float);
1680 base
= (char *) SCM_UVECTOR_BASE (v
);
1681 sz
= sizeof (double);
1684 base
= (char *) SCM_UVECTOR_BASE (v
);
1685 sz
= 2 * sizeof (double);
1690 if (!SCM_UNBNDP (start
))
1693 SCM_NUM2LONG (3, start
);
1695 if (offset
< 0 || offset
>= cend
)
1696 scm_out_of_range (FUNC_NAME
, start
);
1698 if (!SCM_UNBNDP (end
))
1701 SCM_NUM2LONG (4, end
);
1703 if (tend
<= offset
|| tend
> cend
)
1704 scm_out_of_range (FUNC_NAME
, end
);
1709 if (SCM_NIMP (port_or_fd
))
1711 char *source
= base
+ (cstart
+ offset
) * sz
;
1713 ans
= cend
- offset
;
1714 scm_lfwrite (source
, ans
* sz
, port_or_fd
);
1716 else /* file descriptor. */
1718 SCM_SYSCALL (ans
= write (scm_to_int (port_or_fd
),
1719 base
+ (cstart
+ offset
) * sz
,
1720 (sz
* (cend
- offset
))));
1724 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1725 ans
*= SCM_LONG_BIT
;
1727 return scm_from_long (ans
);
1732 static char cnt_tab
[16] =
1733 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1735 SCM_DEFINE (scm_bit_count
, "bit-count", 2, 0, 0,
1736 (SCM b
, SCM bitvector
),
1737 "Return the number of occurrences of the boolean @var{b} in\n"
1739 #define FUNC_NAME s_scm_bit_count
1741 SCM_VALIDATE_BOOL (1, b
);
1742 SCM_ASSERT (SCM_BITVECTOR_P (bitvector
), bitvector
, 2, FUNC_NAME
);
1743 if (SCM_BITVECTOR_LENGTH (bitvector
) == 0) {
1746 unsigned long int count
= 0;
1747 unsigned long int i
= (SCM_BITVECTOR_LENGTH (bitvector
) - 1) / SCM_LONG_BIT
;
1748 unsigned long int w
= SCM_UNPACK (SCM_VELTS (bitvector
)[i
]);
1749 if (scm_is_false (b
)) {
1752 w
<<= SCM_LONG_BIT
- 1 - ((SCM_BITVECTOR_LENGTH (bitvector
) - 1) % SCM_LONG_BIT
);
1755 count
+= cnt_tab
[w
& 0x0f];
1759 return scm_from_ulong (count
);
1762 w
= SCM_UNPACK (SCM_VELTS (bitvector
)[i
]);
1763 if (scm_is_false (b
)) {
1773 SCM_DEFINE (scm_bit_position
, "bit-position", 3, 0, 0,
1774 (SCM item
, SCM v
, SCM k
),
1775 "Return the index of the first occurrance of @var{item} in bit\n"
1776 "vector @var{v}, starting from @var{k}. If there is no\n"
1777 "@var{item} entry between @var{k} and the end of\n"
1778 "@var{bitvector}, then return @code{#f}. For example,\n"
1781 "(bit-position #t #*000101 0) @result{} 3\n"
1782 "(bit-position #f #*0001111 3) @result{} #f\n"
1784 #define FUNC_NAME s_scm_bit_position
1786 long i
, lenw
, xbits
, pos
;
1787 register unsigned long w
;
1789 SCM_VALIDATE_BOOL (1, item
);
1790 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG2
, FUNC_NAME
);
1791 pos
= scm_to_long (k
);
1792 SCM_ASSERT_RANGE (3, k
, (pos
<= SCM_BITVECTOR_LENGTH (v
)) && (pos
>= 0));
1794 if (pos
== SCM_BITVECTOR_LENGTH (v
))
1797 lenw
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
; /* watch for part words */
1798 i
= pos
/ SCM_LONG_BIT
;
1799 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1800 if (scm_is_false (item
))
1802 xbits
= (pos
% SCM_LONG_BIT
);
1804 w
= ((w
>> xbits
) << xbits
);
1805 xbits
= SCM_LONG_BIT
- 1 - (SCM_BITVECTOR_LENGTH (v
) - 1) % SCM_LONG_BIT
;
1808 if (w
&& (i
== lenw
))
1809 w
= ((w
<< xbits
) >> xbits
);
1815 return scm_from_long (pos
);
1820 return scm_from_long (pos
+ 1);
1823 return scm_from_long (pos
+ 2);
1825 return scm_from_long (pos
+ 3);
1832 pos
+= SCM_LONG_BIT
;
1833 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1834 if (scm_is_false (item
))
1842 SCM_DEFINE (scm_bit_set_star_x
, "bit-set*!", 3, 0, 0,
1843 (SCM v
, SCM kv
, SCM obj
),
1844 "Set entries of bit vector @var{v} to @var{obj}, with @var{kv}\n"
1845 "selecting the entries to change. The return value is\n"
1848 "If @var{kv} is a bit vector, then those entries where it has\n"
1849 "@code{#t} are the ones in @var{v} which are set to @var{obj}.\n"
1850 "@var{kv} and @var{v} must be the same length. When @var{obj}\n"
1851 "is @code{#t} it's like @var{kv} is OR'ed into @var{v}. Or when\n"
1852 "@var{obj} is @code{#f} it can be seen as an ANDNOT.\n"
1855 "(define bv #*01000010)\n"
1856 "(bit-set*! bv #*10010001 #t)\n"
1858 "@result{} #*11010011\n"
1861 "If @var{kv} is a uniform vector of unsigned long integers, then\n"
1862 "they're indexes into @var{v} which are set to @var{obj}.\n"
1865 "(define bv #*01000010)\n"
1866 "(bit-set*! bv #u(5 2 7) #t)\n"
1868 "@result{} #*01100111\n"
1870 #define FUNC_NAME s_scm_bit_set_star_x
1872 register long i
, k
, vlen
;
1873 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
1874 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1875 switch SCM_TYP7 (kv
)
1878 badarg2
:SCM_WRONG_TYPE_ARG (2, kv
);
1880 vlen
= SCM_BITVECTOR_LENGTH (v
);
1881 if (scm_is_false (obj
))
1882 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1884 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1886 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
1887 SCM_BITVEC_CLR(v
, k
);
1889 else if (scm_is_eq (obj
, SCM_BOOL_T
))
1890 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1892 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1894 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
1895 SCM_BITVEC_SET(v
, k
);
1898 badarg3
:SCM_WRONG_TYPE_ARG (3, obj
);
1901 SCM_ASSERT (SCM_BITVECTOR_LENGTH (v
) == SCM_BITVECTOR_LENGTH (kv
), v
, SCM_ARG1
, FUNC_NAME
);
1902 if (scm_is_false (obj
))
1903 for (k
= (SCM_BITVECTOR_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1904 SCM_BITVECTOR_BASE (v
) [k
] &= ~SCM_BITVECTOR_BASE (kv
) [k
];
1905 else if (scm_is_eq (obj
, SCM_BOOL_T
))
1906 for (k
= (SCM_BITVECTOR_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1907 SCM_BITVECTOR_BASE (v
) [k
] |= SCM_BITVECTOR_BASE (kv
) [k
];
1912 return SCM_UNSPECIFIED
;
1917 SCM_DEFINE (scm_bit_count_star
, "bit-count*", 3, 0, 0,
1918 (SCM v
, SCM kv
, SCM obj
),
1919 "Return a count of how many entries in bit vector @var{v} are\n"
1920 "equal to @var{obj}, with @var{kv} selecting the entries to\n"
1923 "If @var{kv} is a bit vector, then those entries where it has\n"
1924 "@code{#t} are the ones in @var{v} which are considered.\n"
1925 "@var{kv} and @var{v} must be the same length.\n"
1927 "If @var{kv} is a uniform vector of unsigned long integers, then\n"
1928 "it's the indexes in @var{v} to consider.\n"
1933 "(bit-count* #*01110111 #*11001101 #t) @result{} 3\n"
1934 "(bit-count* #*01110111 #u(7 0 4) #f) @result{} 2\n"
1936 #define FUNC_NAME s_scm_bit_count_star
1938 register long i
, vlen
, count
= 0;
1939 register unsigned long k
;
1942 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
1943 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1944 switch SCM_TYP7 (kv
)
1948 SCM_WRONG_TYPE_ARG (2, kv
);
1950 vlen
= SCM_BITVECTOR_LENGTH (v
);
1951 if (scm_is_false (obj
))
1952 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1954 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1956 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
1957 if (!SCM_BITVEC_REF(v
, k
))
1960 else if (scm_is_eq (obj
, SCM_BOOL_T
))
1961 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1963 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1965 scm_out_of_range (FUNC_NAME
, scm_from_long (k
));
1966 if (SCM_BITVEC_REF (v
, k
))
1970 badarg3
:SCM_WRONG_TYPE_ARG (3, obj
);
1973 SCM_ASSERT (SCM_BITVECTOR_LENGTH (v
) == SCM_BITVECTOR_LENGTH (kv
), v
, SCM_ARG1
, FUNC_NAME
);
1974 if (0 == SCM_BITVECTOR_LENGTH (v
))
1976 SCM_ASRTGO (scm_is_bool (obj
), badarg3
);
1977 fObj
= scm_is_eq (obj
, SCM_BOOL_T
);
1978 i
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
;
1979 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK (SCM_VELTS (v
)[i
]) : ~ SCM_UNPACK (SCM_VELTS (v
)[i
]));
1980 k
<<= SCM_LONG_BIT
- 1 - ((SCM_BITVECTOR_LENGTH (v
) - 1) % SCM_LONG_BIT
);
1984 count
+= cnt_tab
[k
& 0x0f];
1986 return scm_from_long (count
);
1988 /* urg. repetitive (see above.) */
1989 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK(SCM_VELTS (v
)[i
]) : ~SCM_UNPACK (SCM_VELTS (v
)[i
]));
1992 return scm_from_long (count
);
1997 SCM_DEFINE (scm_bit_invert_x
, "bit-invert!", 1, 0, 0,
1999 "Modify the bit vector @var{v} by replacing each element with\n"
2001 #define FUNC_NAME s_scm_bit_invert_x
2005 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
2007 k
= SCM_BITVECTOR_LENGTH (v
);
2008 for (k
= (k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
2009 SCM_BITVECTOR_BASE (v
) [k
] = ~SCM_BITVECTOR_BASE (v
) [k
];
2011 return SCM_UNSPECIFIED
;
2017 scm_istr2bve (char *str
, long len
)
2019 SCM v
= scm_make_uve (len
, SCM_BOOL_T
);
2020 long *data
= (long *) SCM_VELTS (v
);
2021 register unsigned long mask
;
2024 for (k
= 0; k
< (len
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
++)
2027 j
= len
- k
* SCM_LONG_BIT
;
2028 if (j
> SCM_LONG_BIT
)
2030 for (mask
= 1L; j
--; mask
<<= 1)
2048 ra2l (SCM ra
, unsigned long base
, unsigned long k
)
2050 register SCM res
= SCM_EOL
;
2051 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2053 if (SCM_ARRAY_DIMS (ra
)[k
].ubnd
< SCM_ARRAY_DIMS (ra
)[k
].lbnd
)
2055 i
= base
+ (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
) * inc
;
2056 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2061 res
= scm_cons (ra2l (ra
, i
, k
+ 1), res
);
2069 res
= scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra
), scm_from_size_t (i
)), res
);
2076 SCM_DEFINE (scm_array_to_list
, "array->list", 1, 0, 0,
2078 "Return a list consisting of all the elements, in order, of\n"
2080 #define FUNC_NAME s_scm_array_to_list
2084 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
2088 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
2090 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
2091 return ra2l (v
, SCM_ARRAY_BASE (v
), 0);
2092 case scm_tc7_vector
:
2094 return scm_vector_to_list (v
);
2095 case scm_tc7_string
:
2096 return scm_string_to_list (v
);
2099 long *data
= (long *) SCM_VELTS (v
);
2100 register unsigned long mask
;
2101 for (k
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
; k
> 0; k
--)
2102 for (mask
= 1UL << (SCM_LONG_BIT
- 1); mask
; mask
>>= 1)
2103 res
= scm_cons (scm_from_bool(((long *) data
)[k
] & mask
), res
);
2104 for (mask
= 1L << ((SCM_BITVECTOR_LENGTH (v
) % SCM_LONG_BIT
) - 1); mask
; mask
>>= 1)
2105 res
= scm_cons (scm_from_bool(((long *) data
)[k
] & mask
), res
);
2108 case scm_tc7_byvect
:
2110 signed char *data
= (signed char *) SCM_VELTS (v
);
2111 unsigned long k
= SCM_UVECTOR_LENGTH (v
);
2113 res
= scm_cons (scm_from_schar (data
[--k
]), res
);
2118 unsigned long *data
= (unsigned long *)SCM_VELTS(v
);
2119 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2120 res
= scm_cons(scm_from_ulong (data
[k
]), res
);
2125 long *data
= (long *)SCM_VELTS(v
);
2126 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2127 res
= scm_cons(scm_from_long (data
[k
]), res
);
2132 short *data
= (short *)SCM_VELTS(v
);
2133 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2134 res
= scm_cons (scm_from_short (data
[k
]), res
);
2137 #if SCM_SIZEOF_LONG_LONG != 0
2138 case scm_tc7_llvect
:
2140 long long *data
= (long long *)SCM_VELTS(v
);
2141 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2142 res
= scm_cons(scm_from_long_long (data
[k
]), res
);
2148 float *data
= (float *) SCM_VELTS (v
);
2149 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2150 res
= scm_cons (scm_from_double (data
[k
]), res
);
2155 double *data
= (double *) SCM_VELTS (v
);
2156 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2157 res
= scm_cons (scm_from_double (data
[k
]), res
);
2162 double (*data
)[2] = (double (*)[2]) SCM_VELTS (v
);
2163 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2164 res
= scm_cons (scm_c_make_rectangular (data
[k
][0], data
[k
][1]),
2173 static int l2ra(SCM lst
, SCM ra
, unsigned long base
, unsigned long k
);
2175 SCM_DEFINE (scm_list_to_uniform_array
, "list->uniform-array", 3, 0, 0,
2176 (SCM ndim
, SCM prot
, SCM lst
),
2177 "@deffnx {Scheme Procedure} list->uniform-vector prot lst\n"
2178 "Return a uniform array of the type indicated by prototype\n"
2179 "@var{prot} with elements the same as those of @var{lst}.\n"
2180 "Elements must be of the appropriate type, no coercions are\n"
2182 #define FUNC_NAME s_scm_list_to_uniform_array
2189 k
= scm_to_ulong (ndim
);
2192 n
= scm_ilength (row
);
2193 SCM_ASSERT (n
>= 0, lst
, SCM_ARG3
, FUNC_NAME
);
2194 shp
= scm_cons (scm_from_long (n
), shp
);
2196 row
= SCM_CAR (row
);
2198 ra
= scm_dimensions_to_uniform_array (scm_reverse (shp
), prot
,
2200 if (SCM_NULLP (shp
))
2202 SCM_ASRTGO (1 == scm_ilength (lst
), badlst
);
2203 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_EOL
);
2206 if (!SCM_ARRAYP (ra
))
2208 unsigned long length
= scm_to_ulong (scm_uniform_vector_length (ra
));
2209 for (k
= 0; k
< length
; k
++, lst
= SCM_CDR (lst
))
2210 scm_array_set_x (ra
, SCM_CAR (lst
), scm_from_ulong (k
));
2213 if (l2ra (lst
, ra
, SCM_ARRAY_BASE (ra
), 0))
2216 badlst
:SCM_MISC_ERROR ("Bad scm_array contents list: ~S",
2222 l2ra (SCM lst
, SCM ra
, unsigned long base
, unsigned long k
)
2224 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2225 register long n
= (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
);
2228 return (SCM_NULLP (lst
));
2229 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2233 if (!SCM_CONSP (lst
))
2235 ok
= ok
&& l2ra (SCM_CAR (lst
), ra
, base
, k
+ 1);
2237 lst
= SCM_CDR (lst
);
2239 if (!SCM_NULLP (lst
))
2246 if (!SCM_CONSP (lst
))
2248 scm_array_set_x (SCM_ARRAY_V (ra
), SCM_CAR (lst
), scm_from_ulong (base
));
2250 lst
= SCM_CDR (lst
);
2252 if (!SCM_NULLP (lst
))
2260 rapr1 (SCM ra
, unsigned long j
, unsigned long k
, SCM port
, scm_print_state
*pstate
)
2263 long n
= (SCM_TYP7 (ra
) == scm_tc7_smob
2265 : scm_to_long (scm_uniform_vector_length (ra
)));
2268 switch SCM_TYP7 (ra
)
2273 SCM_ARRAY_BASE (ra
) = j
;
2275 scm_iprin1 (ra
, port
, pstate
);
2276 for (j
+= inc
; n
-- > 0; j
+= inc
)
2278 scm_putc (' ', port
);
2279 SCM_ARRAY_BASE (ra
) = j
;
2280 scm_iprin1 (ra
, port
, pstate
);
2284 if (k
+ 1 < SCM_ARRAY_NDIM (ra
))
2287 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2288 for (i
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
; i
< SCM_ARRAY_DIMS (ra
)[k
].ubnd
; i
++)
2290 scm_putc ('(', port
);
2291 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2292 scm_puts (") ", port
);
2295 if (i
== SCM_ARRAY_DIMS (ra
)[k
].ubnd
)
2296 { /* could be zero size. */
2297 scm_putc ('(', port
);
2298 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2299 scm_putc (')', port
);
2303 if (SCM_ARRAY_NDIM (ra
) > 0)
2304 { /* Could be zero-dimensional */
2305 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2306 n
= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
2310 ra
= SCM_ARRAY_V (ra
);
2313 /* scm_tc7_bvect and scm_tc7_llvect only? */
2315 scm_iprin1 (scm_uniform_vector_ref (ra
, scm_from_ulong (j
)), port
, pstate
);
2316 for (j
+= inc
; n
-- > 0; j
+= inc
)
2318 scm_putc (' ', port
);
2319 scm_iprin1 (scm_cvref (ra
, j
, SCM_UNDEFINED
), port
, pstate
);
2322 case scm_tc7_string
:
2324 scm_iprin1 (SCM_MAKE_CHAR (SCM_STRING_UCHARS (ra
)[j
]), port
, pstate
);
2325 if (SCM_WRITINGP (pstate
))
2326 for (j
+= inc
; n
-- > 0; j
+= inc
)
2328 scm_putc (' ', port
);
2329 scm_iprin1 (SCM_MAKE_CHAR (SCM_STRING_UCHARS (ra
)[j
]), port
, pstate
);
2332 for (j
+= inc
; n
-- > 0; j
+= inc
)
2333 scm_putc (SCM_STRING_CHARS (ra
)[j
], port
);
2335 case scm_tc7_byvect
:
2337 scm_intprint (((char *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2338 for (j
+= inc
; n
-- > 0; j
+= inc
)
2340 scm_putc (' ', port
);
2341 scm_intprint (((char *)SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2351 /* intprint can't handle >= 2^31. */
2352 sprintf (str
, "%lu", ((unsigned long *) SCM_VELTS (ra
))[j
]);
2353 scm_puts (str
, port
);
2355 for (j
+= inc
; n
-- > 0; j
+= inc
)
2357 scm_putc (' ', port
);
2358 sprintf (str
, "%lu", ((unsigned long *) SCM_VELTS (ra
))[j
]);
2359 scm_puts (str
, port
);
2364 scm_intprint (((signed long *) SCM_VELTS (ra
))[j
], 10, port
);
2365 for (j
+= inc
; n
-- > 0; j
+= inc
)
2367 scm_putc (' ', port
);
2368 scm_intprint (((signed long *) SCM_VELTS (ra
))[j
], 10, port
);
2374 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2375 for (j
+= inc
; n
-- > 0; j
+= inc
)
2377 scm_putc (' ', port
);
2378 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2385 SCM z
= scm_from_double (1.0);
2386 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2387 scm_print_real (z
, port
, pstate
);
2388 for (j
+= inc
; n
-- > 0; j
+= inc
)
2390 scm_putc (' ', port
);
2391 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2392 scm_print_real (z
, port
, pstate
);
2399 SCM z
= scm_from_double (1.0 / 3.0);
2400 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2401 scm_print_real (z
, port
, pstate
);
2402 for (j
+= inc
; n
-- > 0; j
+= inc
)
2404 scm_putc (' ', port
);
2405 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2406 scm_print_real (z
, port
, pstate
);
2413 SCM cz
= scm_c_make_rectangular (0.0, 1.0);
2414 SCM z
= scm_from_double (1.0/3.0);
2415 SCM_REAL_VALUE (z
) =
2416 SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2417 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2418 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2420 for (j
+= inc
; n
-- > 0; j
+= inc
)
2422 scm_putc (' ', port
);
2424 = SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2425 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2426 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2437 scm_raprin1 (SCM exp
, SCM port
, scm_print_state
*pstate
)
2440 unsigned long base
= 0;
2441 scm_putc ('#', port
);
2447 long ndim
= SCM_ARRAY_NDIM (v
);
2448 base
= SCM_ARRAY_BASE (v
);
2449 v
= SCM_ARRAY_V (v
);
2453 scm_puts ("<enclosed-array ", port
);
2454 rapr1 (exp
, base
, 0, port
, pstate
);
2455 scm_putc ('>', port
);
2460 scm_intprint (ndim
, 10, port
);
2465 if (scm_is_eq (exp
, v
))
2466 { /* a uve, not an scm_array */
2467 register long i
, j
, w
;
2468 scm_putc ('*', port
);
2469 for (i
= 0; i
< (SCM_BITVECTOR_LENGTH (exp
)) / SCM_LONG_BIT
; i
++)
2471 scm_t_bits w
= SCM_UNPACK (SCM_VELTS (exp
)[i
]);
2472 for (j
= SCM_LONG_BIT
; j
; j
--)
2474 scm_putc (w
& 1 ? '1' : '0', port
);
2478 j
= SCM_BITVECTOR_LENGTH (exp
) % SCM_LONG_BIT
;
2481 w
= SCM_UNPACK (SCM_VELTS (exp
)[SCM_BITVECTOR_LENGTH (exp
) / SCM_LONG_BIT
]);
2484 scm_putc (w
& 1 ? '1' : '0', port
);
2491 scm_putc ('b', port
);
2493 case scm_tc7_string
:
2494 scm_putc ('a', port
);
2496 case scm_tc7_byvect
:
2497 scm_putc ('y', port
);
2500 scm_putc ('u', port
);
2503 scm_putc ('e', port
);
2506 scm_putc ('h', port
);
2508 #if SCM_SIZEOF_LONG_LONG != 0
2509 case scm_tc7_llvect
:
2510 scm_putc ('l', port
);
2514 scm_putc ('s', port
);
2517 scm_putc ('i', port
);
2520 scm_putc ('c', port
);
2523 scm_putc ('(', port
);
2524 rapr1 (exp
, base
, 0, port
, pstate
);
2525 scm_putc (')', port
);
2529 SCM_DEFINE (scm_array_prototype
, "array-prototype", 1, 0, 0,
2531 "Return an object that would produce an array of the same type\n"
2532 "as @var{array}, if used as the @var{prototype} for\n"
2533 "@code{make-uniform-array}.")
2534 #define FUNC_NAME s_scm_array_prototype
2537 SCM_ASRTGO (SCM_NIMP (ra
), badarg
);
2539 switch SCM_TYP7 (ra
)
2542 badarg
:SCM_WRONG_TYPE_ARG (1, ra
);
2544 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
2546 return SCM_UNSPECIFIED
;
2547 ra
= SCM_ARRAY_V (ra
);
2549 case scm_tc7_vector
:
2554 case scm_tc7_string
:
2555 return SCM_MAKE_CHAR ('a');
2556 case scm_tc7_byvect
:
2557 return SCM_MAKE_CHAR ('\0');
2559 return scm_from_int (1);
2561 return scm_from_int (-1);
2563 return scm_str2symbol ("s");
2564 #if SCM_SIZEOF_LONG_LONG != 0
2565 case scm_tc7_llvect
:
2566 return scm_str2symbol ("l");
2569 return scm_from_double (1.0);
2571 return exactly_one_third
;
2573 return scm_c_make_rectangular (0.0, 1.0);
2580 array_mark (SCM ptr
)
2582 return SCM_ARRAY_V (ptr
);
2587 array_free (SCM ptr
)
2589 scm_gc_free (SCM_ARRAY_MEM (ptr
),
2590 (sizeof (scm_t_array
)
2591 + SCM_ARRAY_NDIM (ptr
) * sizeof (scm_t_array_dim
)),
2599 scm_tc16_array
= scm_make_smob_type ("array", 0);
2600 scm_set_smob_mark (scm_tc16_array
, array_mark
);
2601 scm_set_smob_free (scm_tc16_array
, array_free
);
2602 scm_set_smob_print (scm_tc16_array
, scm_raprin1
);
2603 scm_set_smob_equalp (scm_tc16_array
, scm_array_equal_p
);
2604 exactly_one_third
= scm_permanent_object (scm_divide (scm_from_int (1),
2606 scm_add_feature ("array");
2607 #include "libguile/unif.x"