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_EQ_P (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_INUMP (prot
))
174 return make_uve (SCM_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_I_MAKINUM (SCM_VECTOR_LENGTH (v
));
223 return SCM_I_MAKINUM (SCM_STRING_LENGTH (v
));
225 return SCM_I_MAKINUM (SCM_BITVECTOR_LENGTH (v
));
233 #if SCM_SIZEOF_LONG_LONG != 0
236 return SCM_I_MAKINUM (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_EQ_P (prot
, SCM_BOOL_T
));
277 protp
= SCM_CHARP(prot
) && (SCM_CHAR (prot
) != '\0');
280 protp
= SCM_EQ_P (prot
, SCM_MAKE_CHAR ('\0'));
283 protp
= SCM_INUMP(prot
) && SCM_INUM(prot
)>0;
286 protp
= SCM_INUMP(prot
) && SCM_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_I_MAKINUM (1L);
353 return SCM_I_MAKINUM (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_I_MAKINUM (s
[k
].lbnd
),
401 SCM_I_MAKINUM (s
[k
].ubnd
),
403 : SCM_I_MAKINUM (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_I_MAKINUM (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_I_MAKINUM (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_INUMP (args
))
466 scm_error_num_args_subr (what
);
467 return pos
+ (SCM_INUM (args
) - s
->lbnd
) * (s
->inc
);
469 while (k
&& SCM_CONSP (args
))
471 ind
= SCM_CAR (args
);
472 args
= SCM_CDR (args
);
473 if (!SCM_INUMP (ind
))
474 scm_misc_error (what
, s_bad_ind
, SCM_EOL
);
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_INUMP (spec
))
525 if (SCM_INUM (spec
) < 0)
526 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
528 s
->ubnd
= SCM_INUM (spec
) - 1;
533 if (!SCM_CONSP (spec
) || !SCM_INUMP (SCM_CAR (spec
)))
534 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
535 s
->lbnd
= SCM_INUM (SCM_CAR (spec
));
538 || !SCM_INUMP (SCM_CAR (sp
))
539 || !SCM_NULLP (SCM_CDR (sp
)))
540 scm_misc_error (what
, s_bad_spec
, SCM_EOL
);
541 s
->ubnd
= SCM_INUM (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_INUMP (dims
))
564 SCM answer
= scm_make_uve (SCM_INUM (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_I_MAKINUM (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_I_MAKINUM (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_INUM (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_I_MAKINUM (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_NINUMP (imap
))
699 if (scm_ilength (imap
) != 1 || !SCM_INUMP (SCM_CAR (imap
)))
700 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
701 imap
= SCM_CAR (imap
);
705 SCM_ARRAY_BASE (ra
) = new_min
= new_max
= i
;
707 k
= SCM_ARRAY_NDIM (ra
);
710 if (s
[k
].ubnd
> s
[k
].lbnd
)
712 SCM_SETCAR (indptr
, SCM_I_MAKINUM (SCM_INUM (SCM_CAR (indptr
)) + 1));
713 imap
= scm_apply_0 (mapfunc
, scm_reverse (inds
));
714 if (SCM_ARRAYP (oldra
))
716 s
[k
].inc
= scm_aind (oldra
, imap
, FUNC_NAME
) - i
;
719 if (SCM_NINUMP (imap
))
721 if (scm_ilength (imap
) != 1 || !SCM_INUMP (SCM_CAR (imap
)))
722 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
723 imap
= SCM_CAR (imap
);
725 s
[k
].inc
= (long) SCM_INUM (imap
) - i
;
729 new_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
731 new_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
734 s
[k
].inc
= new_max
- new_min
+ 1; /* contiguous by default */
735 indptr
= SCM_CDR (indptr
);
737 if (old_min
> new_min
|| old_max
< new_max
)
738 SCM_MISC_ERROR ("mapping out of range", SCM_EOL
);
739 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
741 SCM v
= SCM_ARRAY_V (ra
);
742 unsigned long int length
= SCM_INUM (scm_uniform_vector_length (v
));
743 if (1 == s
->inc
&& 0 == s
->lbnd
&& length
== 1 + s
->ubnd
)
745 if (s
->ubnd
< s
->lbnd
)
746 return scm_make_uve (0L, scm_array_prototype (ra
));
748 scm_ra_set_contp (ra
);
754 /* args are RA . DIMS */
755 SCM_DEFINE (scm_transpose_array
, "transpose-array", 1, 0, 1,
757 "Return an array sharing contents with @var{array}, but with\n"
758 "dimensions arranged in a different order. There must be one\n"
759 "@var{dim} argument for each dimension of @var{array}.\n"
760 "@var{dim0}, @var{dim1}, @dots{} should be integers between 0\n"
761 "and the rank of the array to be returned. Each integer in that\n"
762 "range must appear at least once in the argument list.\n"
764 "The values of @var{dim0}, @var{dim1}, @dots{} correspond to\n"
765 "dimensions in the array to be returned, their positions in the\n"
766 "argument list to dimensions of @var{array}. Several @var{dim}s\n"
767 "may have the same value, in which case the returned array will\n"
768 "have smaller rank than @var{array}.\n"
771 "(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))\n"
772 "(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)\n"
773 "(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}\n"
774 " #2((a 4) (b 5) (c 6))\n"
776 #define FUNC_NAME s_scm_transpose_array
779 SCM
const *ve
= &vargs
;
780 scm_t_array_dim
*s
, *r
;
783 SCM_VALIDATE_REST_ARGUMENT (args
);
784 SCM_ASSERT (SCM_NIMP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
785 switch (SCM_TYP7 (ra
))
788 badarg
:SCM_WRONG_TYPE_ARG (1, ra
);
798 #if SCM_SIZEOF_LONG_LONG != 0
801 if (SCM_NULLP (args
) || !SCM_NULLP (SCM_CDR (args
)))
802 SCM_WRONG_NUM_ARGS ();
803 SCM_VALIDATE_INT_COPY (SCM_ARG2
, SCM_CAR (args
), i
);
804 SCM_ASSERT_RANGE (SCM_ARG2
, SCM_CAR (args
), i
== 0);
807 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
808 vargs
= scm_vector (args
);
809 if (SCM_VECTOR_LENGTH (vargs
) != SCM_ARRAY_NDIM (ra
))
810 SCM_WRONG_NUM_ARGS ();
811 ve
= SCM_VELTS (vargs
);
813 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
815 SCM_ASSERT (SCM_INUMP (ve
[k
]), ve
[k
], (SCM_ARG2
+ k
),
817 i
= SCM_INUM (ve
[k
]);
818 if (i
< 0 || i
>= SCM_ARRAY_NDIM (ra
))
819 scm_out_of_range (FUNC_NAME
, ve
[k
]);
824 res
= scm_make_ra (ndim
);
825 SCM_ARRAY_V (res
) = SCM_ARRAY_V (ra
);
826 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra
);
829 SCM_ARRAY_DIMS (res
)[k
].lbnd
= 0;
830 SCM_ARRAY_DIMS (res
)[k
].ubnd
= -1;
832 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
834 i
= SCM_INUM (ve
[k
]);
835 s
= &(SCM_ARRAY_DIMS (ra
)[k
]);
836 r
= &(SCM_ARRAY_DIMS (res
)[i
]);
837 if (r
->ubnd
< r
->lbnd
)
846 if (r
->ubnd
> s
->ubnd
)
848 if (r
->lbnd
< s
->lbnd
)
850 SCM_ARRAY_BASE (res
) += (s
->lbnd
- r
->lbnd
) * r
->inc
;
857 SCM_MISC_ERROR ("bad argument list", SCM_EOL
);
858 scm_ra_set_contp (res
);
864 /* args are RA . AXES */
865 SCM_DEFINE (scm_enclose_array
, "enclose-array", 1, 0, 1,
867 "@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than\n"
868 "the rank of @var{array}. @var{enclose-array} returns an array\n"
869 "resembling an array of shared arrays. The dimensions of each shared\n"
870 "array are the same as the @var{dim}th dimensions of the original array,\n"
871 "the dimensions of the outer array are the same as those of the original\n"
872 "array that did not match a @var{dim}.\n\n"
873 "An enclosed array is not a general Scheme array. Its elements may not\n"
874 "be set using @code{array-set!}. Two references to the same element of\n"
875 "an enclosed array will be @code{equal?} but will not in general be\n"
876 "@code{eq?}. The value returned by @var{array-prototype} when given an\n"
877 "enclosed array is unspecified.\n\n"
880 "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) @result{}\n"
881 " #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>\n\n"
882 "(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{}\n"
883 " #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>\n"
885 #define FUNC_NAME s_scm_enclose_array
887 SCM axv
, res
, ra_inr
;
888 scm_t_array_dim vdim
, *s
= &vdim
;
889 int ndim
, j
, k
, ninr
, noutr
;
891 SCM_VALIDATE_REST_ARGUMENT (axes
);
892 if (SCM_NULLP (axes
))
893 axes
= scm_cons ((SCM_ARRAYP (ra
) ? SCM_I_MAKINUM (SCM_ARRAY_NDIM (ra
) - 1) : SCM_INUM0
), SCM_EOL
);
894 ninr
= scm_ilength (axes
);
896 SCM_WRONG_NUM_ARGS ();
897 ra_inr
= scm_make_ra (ninr
);
898 SCM_ASRTGO (SCM_NIMP (ra
), badarg1
);
902 badarg1
:SCM_WRONG_TYPE_ARG (1, ra
);
914 #if SCM_SIZEOF_LONG_LONG != 0
918 s
->ubnd
= SCM_INUM (scm_uniform_vector_length (ra
)) - 1;
920 SCM_ARRAY_V (ra_inr
) = ra
;
921 SCM_ARRAY_BASE (ra_inr
) = 0;
925 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg1
);
926 s
= SCM_ARRAY_DIMS (ra
);
927 SCM_ARRAY_V (ra_inr
) = SCM_ARRAY_V (ra
);
928 SCM_ARRAY_BASE (ra_inr
) = SCM_ARRAY_BASE (ra
);
929 ndim
= SCM_ARRAY_NDIM (ra
);
934 SCM_WRONG_NUM_ARGS ();
935 axv
= scm_make_string (SCM_I_MAKINUM (ndim
), SCM_MAKE_CHAR (0));
936 res
= scm_make_ra (noutr
);
937 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra_inr
);
938 SCM_ARRAY_V (res
) = ra_inr
;
939 for (k
= 0; k
< ninr
; k
++, axes
= SCM_CDR (axes
))
941 if (!SCM_INUMP (SCM_CAR (axes
)))
942 SCM_MISC_ERROR ("bad axis", SCM_EOL
);
943 j
= SCM_INUM (SCM_CAR (axes
));
944 SCM_ARRAY_DIMS (ra_inr
)[k
].lbnd
= s
[j
].lbnd
;
945 SCM_ARRAY_DIMS (ra_inr
)[k
].ubnd
= s
[j
].ubnd
;
946 SCM_ARRAY_DIMS (ra_inr
)[k
].inc
= s
[j
].inc
;
947 SCM_STRING_CHARS (axv
)[j
] = 1;
949 for (j
= 0, k
= 0; k
< noutr
; k
++, j
++)
951 while (SCM_STRING_CHARS (axv
)[j
])
953 SCM_ARRAY_DIMS (res
)[k
].lbnd
= s
[j
].lbnd
;
954 SCM_ARRAY_DIMS (res
)[k
].ubnd
= s
[j
].ubnd
;
955 SCM_ARRAY_DIMS (res
)[k
].inc
= s
[j
].inc
;
957 scm_ra_set_contp (ra_inr
);
958 scm_ra_set_contp (res
);
965 SCM_DEFINE (scm_array_in_bounds_p
, "array-in-bounds?", 1, 0, 1,
967 "Return @code{#t} if its arguments would be acceptable to\n"
969 #define FUNC_NAME s_scm_array_in_bounds_p
977 SCM_VALIDATE_REST_ARGUMENT (args
);
978 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
982 ind
= SCM_CAR (args
);
983 args
= SCM_CDR (args
);
984 SCM_ASSERT (SCM_INUMP (ind
), ind
, SCM_ARG2
, FUNC_NAME
);
985 pos
= SCM_INUM (ind
);
991 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
992 wna
: SCM_WRONG_NUM_ARGS ();
994 k
= SCM_ARRAY_NDIM (v
);
995 s
= SCM_ARRAY_DIMS (v
);
996 pos
= SCM_ARRAY_BASE (v
);
999 SCM_ASRTGO (SCM_NULLP (ind
), wna
);
1006 if (!(j
>= (s
->lbnd
) && j
<= (s
->ubnd
)))
1008 SCM_ASRTGO (--k
== scm_ilength (args
), wna
);
1011 pos
+= (j
- s
->lbnd
) * (s
->inc
);
1012 if (!(--k
&& SCM_NIMP (args
)))
1014 ind
= SCM_CAR (args
);
1015 args
= SCM_CDR (args
);
1017 if (!SCM_INUMP (ind
))
1018 SCM_MISC_ERROR (s_bad_ind
, SCM_EOL
);
1020 SCM_ASRTGO (0 == k
, wna
);
1021 v
= SCM_ARRAY_V (v
);
1024 case scm_tc7_string
:
1025 case scm_tc7_byvect
:
1032 #if SCM_SIZEOF_LONG_LONG != 0
1033 case scm_tc7_llvect
:
1035 case scm_tc7_vector
:
1038 unsigned long int length
= SCM_INUM (scm_uniform_vector_length (v
));
1039 SCM_ASRTGO (SCM_NULLP (args
) && SCM_INUMP (ind
), wna
);
1040 return scm_from_bool(pos
>= 0 && pos
< length
);
1047 SCM_REGISTER_PROC(s_array_ref
, "array-ref", 1, 0, 1, scm_uniform_vector_ref
);
1050 SCM_DEFINE (scm_uniform_vector_ref
, "uniform-vector-ref", 2, 0, 0,
1052 "@deffnx {Scheme Procedure} array-ref v . args\n"
1053 "Return the element at the @code{(index1, index2)} element in\n"
1055 #define FUNC_NAME s_scm_uniform_vector_ref
1061 SCM_ASRTGO (SCM_NULLP (args
), badarg
);
1064 else if (SCM_ARRAYP (v
))
1066 pos
= scm_aind (v
, args
, FUNC_NAME
);
1067 v
= SCM_ARRAY_V (v
);
1071 unsigned long int length
;
1072 if (SCM_NIMP (args
))
1074 SCM_ASSERT (SCM_CONSP (args
) && SCM_INUMP (SCM_CAR (args
)), args
, SCM_ARG2
, FUNC_NAME
);
1075 pos
= SCM_INUM (SCM_CAR (args
));
1076 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1080 pos
= scm_to_long (args
);
1082 length
= SCM_INUM (scm_uniform_vector_length (v
));
1083 SCM_ASRTGO (pos
>= 0 && pos
< length
, outrng
);
1088 if (SCM_NULLP (args
))
1091 SCM_WRONG_TYPE_ARG (1, v
);
1095 scm_out_of_range (FUNC_NAME
, SCM_I_MAKINUM (pos
));
1097 SCM_WRONG_NUM_ARGS ();
1100 int k
= SCM_ARRAY_NDIM (v
);
1101 SCM res
= scm_make_ra (k
);
1102 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1103 SCM_ARRAY_BASE (res
) = pos
;
1106 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1107 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1108 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1113 if (SCM_BITVEC_REF (v
, pos
))
1117 case scm_tc7_string
:
1118 return SCM_MAKE_CHAR (SCM_STRING_UCHARS (v
)[pos
]);
1119 case scm_tc7_byvect
:
1120 return SCM_I_MAKINUM (((char *) SCM_UVECTOR_BASE (v
))[pos
]);
1122 return scm_ulong2num (((unsigned long *) SCM_VELTS (v
))[pos
]);
1124 return scm_long2num (((signed long *) SCM_VELTS (v
))[pos
]);
1127 return SCM_I_MAKINUM (((short *) SCM_CELL_WORD_1 (v
))[pos
]);
1128 #if SCM_SIZEOF_LONG_LONG != 0
1129 case scm_tc7_llvect
:
1130 return scm_long_long2num (((long long *) SCM_CELL_WORD_1 (v
))[pos
]);
1134 return scm_make_real (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1136 return scm_make_real (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1138 return scm_make_complex (((double *) SCM_CELL_WORD_1 (v
))[2 * pos
],
1139 ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1]);
1140 case scm_tc7_vector
:
1142 return SCM_VELTS (v
)[pos
];
1147 /* Internal version of scm_uniform_vector_ref for uves that does no error checking and
1148 tries to recycle conses. (Make *sure* you want them recycled.) */
1151 scm_cvref (SCM v
, unsigned long pos
, SCM last
)
1152 #define FUNC_NAME "scm_cvref"
1157 SCM_WRONG_TYPE_ARG (SCM_ARG1
, v
);
1159 if (SCM_BITVEC_REF(v
, pos
))
1163 case scm_tc7_string
:
1164 return SCM_MAKE_CHAR (SCM_STRING_UCHARS (v
)[pos
]);
1165 case scm_tc7_byvect
:
1166 return SCM_I_MAKINUM (((char *) SCM_UVECTOR_BASE (v
))[pos
]);
1168 return scm_ulong2num(((unsigned long *) SCM_VELTS (v
))[pos
]);
1170 return scm_long2num(((signed long *) SCM_VELTS (v
))[pos
]);
1172 return SCM_I_MAKINUM (((short *) SCM_CELL_WORD_1 (v
))[pos
]);
1173 #if SCM_SIZEOF_LONG_LONG != 0
1174 case scm_tc7_llvect
:
1175 return scm_long_long2num (((long long *) SCM_CELL_WORD_1 (v
))[pos
]);
1178 if (SCM_REALP (last
) && !SCM_EQ_P (last
, scm_flo0
))
1180 SCM_REAL_VALUE (last
) = ((float *) SCM_CELL_WORD_1 (v
))[pos
];
1183 return scm_make_real (((float *) SCM_CELL_WORD_1 (v
))[pos
]);
1185 if (SCM_REALP (last
) && !SCM_EQ_P (last
, scm_flo0
))
1187 SCM_REAL_VALUE (last
) = ((double *) SCM_CELL_WORD_1 (v
))[pos
];
1190 return scm_make_real (((double *) SCM_CELL_WORD_1 (v
))[pos
]);
1192 if (SCM_COMPLEXP (last
))
1194 SCM_COMPLEX_REAL (last
) = ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
];
1195 SCM_COMPLEX_IMAG (last
) = ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1];
1198 return scm_make_complex (((double *) SCM_CELL_WORD_1 (v
))[2 * pos
],
1199 ((double *) SCM_CELL_WORD_1 (v
))[2 * pos
+ 1]);
1200 case scm_tc7_vector
:
1202 return SCM_VELTS (v
)[pos
];
1204 { /* enclosed scm_array */
1205 int k
= SCM_ARRAY_NDIM (v
);
1206 SCM res
= scm_make_ra (k
);
1207 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1208 SCM_ARRAY_BASE (res
) = pos
;
1211 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1212 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1213 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1222 SCM_REGISTER_PROC(s_uniform_array_set1_x
, "uniform-array-set1!", 3, 0, 0, scm_array_set_x
);
1225 /* Note that args may be a list or an immediate object, depending which
1226 PROC is used (and it's called from C too). */
1227 SCM_DEFINE (scm_array_set_x
, "array-set!", 2, 0, 1,
1228 (SCM v
, SCM obj
, SCM args
),
1229 "@deffnx {Scheme Procedure} uniform-array-set1! v obj args\n"
1230 "Set the element at the @code{(index1, index2)} element in @var{array} to\n"
1231 "@var{new-value}. The value returned by array-set! is unspecified.")
1232 #define FUNC_NAME s_scm_array_set_x
1236 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1239 pos
= scm_aind (v
, args
, FUNC_NAME
);
1240 v
= SCM_ARRAY_V (v
);
1244 unsigned long int length
;
1245 if (SCM_CONSP (args
))
1247 SCM_ASSERT (SCM_INUMP (SCM_CAR (args
)), args
, SCM_ARG3
, FUNC_NAME
);
1248 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1249 pos
= SCM_INUM (SCM_CAR (args
));
1253 pos
= scm_to_long (args
);
1255 length
= SCM_INUM (scm_uniform_vector_length (v
));
1256 SCM_ASRTGO (pos
>= 0 && pos
< length
, outrng
);
1258 switch (SCM_TYP7 (v
))
1261 SCM_WRONG_TYPE_ARG (1, v
);
1264 scm_out_of_range (FUNC_NAME
, SCM_I_MAKINUM (pos
));
1266 SCM_WRONG_NUM_ARGS ();
1267 case scm_tc7_smob
: /* enclosed */
1270 if (scm_is_false (obj
))
1271 SCM_BITVEC_CLR(v
, pos
);
1272 else if (SCM_EQ_P (obj
, SCM_BOOL_T
))
1273 SCM_BITVEC_SET(v
, pos
);
1275 badobj
:SCM_WRONG_TYPE_ARG (2, obj
);
1277 case scm_tc7_string
:
1278 SCM_ASRTGO (SCM_CHARP (obj
), badobj
);
1279 SCM_STRING_UCHARS (v
)[pos
] = SCM_CHAR (obj
);
1281 case scm_tc7_byvect
:
1282 if (SCM_CHARP (obj
))
1283 obj
= SCM_I_MAKINUM ((char) SCM_CHAR (obj
));
1284 SCM_ASRTGO (SCM_INUMP (obj
), badobj
);
1285 ((char *) SCM_UVECTOR_BASE (v
))[pos
] = SCM_INUM (obj
);
1288 ((unsigned long *) SCM_UVECTOR_BASE (v
))[pos
]
1289 = scm_num2ulong (obj
, SCM_ARG2
, FUNC_NAME
);
1292 ((long *) SCM_UVECTOR_BASE (v
))[pos
]
1293 = scm_num2long (obj
, SCM_ARG2
, FUNC_NAME
);
1296 SCM_ASRTGO (SCM_INUMP (obj
), badobj
);
1297 ((short *) SCM_UVECTOR_BASE (v
))[pos
] = SCM_INUM (obj
);
1299 #if SCM_SIZEOF_LONG_LONG != 0
1300 case scm_tc7_llvect
:
1301 ((long long *) SCM_UVECTOR_BASE (v
))[pos
]
1302 = scm_num2long_long (obj
, SCM_ARG2
, FUNC_NAME
);
1306 ((float *) SCM_UVECTOR_BASE (v
))[pos
]
1307 = (float) scm_num2dbl (obj
, FUNC_NAME
);
1310 ((double *) SCM_UVECTOR_BASE (v
))[pos
]
1311 = scm_num2dbl (obj
, FUNC_NAME
);
1314 SCM_ASRTGO (SCM_INEXACTP (obj
), badobj
);
1315 if (SCM_REALP (obj
)) {
1316 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
] = SCM_REAL_VALUE (obj
);
1317 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
+ 1] = 0.0;
1319 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
] = SCM_COMPLEX_REAL (obj
);
1320 ((double *) SCM_UVECTOR_BASE (v
))[2 * pos
+ 1] = SCM_COMPLEX_IMAG (obj
);
1323 case scm_tc7_vector
:
1325 SCM_VECTOR_SET (v
, pos
, obj
);
1328 return SCM_UNSPECIFIED
;
1332 /* attempts to unroll an array into a one-dimensional array.
1333 returns the unrolled array or #f if it can't be done. */
1334 /* if strict is not SCM_UNDEFINED, return #f if returned array
1335 wouldn't have contiguous elements. */
1336 SCM_DEFINE (scm_array_contents
, "array-contents", 1, 1, 0,
1337 (SCM ra
, SCM strict
),
1338 "If @var{array} may be @dfn{unrolled} into a one dimensional shared array\n"
1339 "without changing their order (last subscript changing fastest), then\n"
1340 "@code{array-contents} returns that shared array, otherwise it returns\n"
1341 "@code{#f}. All arrays made by @var{make-array} and\n"
1342 "@var{make-uniform-array} may be unrolled, some arrays made by\n"
1343 "@var{make-shared-array} may not be.\n\n"
1344 "If the optional argument @var{strict} is provided, a shared array will\n"
1345 "be returned only if its elements are stored internally contiguous in\n"
1347 #define FUNC_NAME s_scm_array_contents
1352 switch SCM_TYP7 (ra
)
1356 case scm_tc7_vector
:
1358 case scm_tc7_string
:
1360 case scm_tc7_byvect
:
1367 #if SCM_SIZEOF_LONG_LONG != 0
1368 case scm_tc7_llvect
:
1373 size_t k
, ndim
= SCM_ARRAY_NDIM (ra
), len
= 1;
1374 if (!SCM_ARRAYP (ra
) || !SCM_ARRAY_CONTP (ra
))
1376 for (k
= 0; k
< ndim
; k
++)
1377 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1378 if (!SCM_UNBNDP (strict
))
1380 if (ndim
&& (1 != SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
))
1382 if (scm_tc7_bvect
== SCM_TYP7 (SCM_ARRAY_V (ra
)))
1384 if (len
!= SCM_BITVECTOR_LENGTH (SCM_ARRAY_V (ra
)) ||
1385 SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
||
1392 SCM v
= SCM_ARRAY_V (ra
);
1393 unsigned long int length
= SCM_INUM (scm_uniform_vector_length (v
));
1394 if ((len
== length
) && 0 == SCM_ARRAY_BASE (ra
) && SCM_ARRAY_DIMS (ra
)->inc
)
1398 sra
= scm_make_ra (1);
1399 SCM_ARRAY_DIMS (sra
)->lbnd
= 0;
1400 SCM_ARRAY_DIMS (sra
)->ubnd
= len
- 1;
1401 SCM_ARRAY_V (sra
) = SCM_ARRAY_V (ra
);
1402 SCM_ARRAY_BASE (sra
) = SCM_ARRAY_BASE (ra
);
1403 SCM_ARRAY_DIMS (sra
)->inc
= (ndim
? SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
: 1);
1412 scm_ra2contig (SCM ra
, int copy
)
1417 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
1418 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1419 k
= SCM_ARRAY_NDIM (ra
);
1420 if (SCM_ARRAY_CONTP (ra
) && ((0 == k
) || (1 == SCM_ARRAY_DIMS (ra
)[k
- 1].inc
)))
1422 if (scm_tc7_bvect
!= SCM_TYP7 (SCM_ARRAY_V (ra
)))
1424 if ((len
== SCM_BITVECTOR_LENGTH (SCM_ARRAY_V (ra
)) &&
1425 0 == SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
&&
1426 0 == len
% SCM_LONG_BIT
))
1429 ret
= scm_make_ra (k
);
1430 SCM_ARRAY_BASE (ret
) = 0;
1433 SCM_ARRAY_DIMS (ret
)[k
].lbnd
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
;
1434 SCM_ARRAY_DIMS (ret
)[k
].ubnd
= SCM_ARRAY_DIMS (ra
)[k
].ubnd
;
1435 SCM_ARRAY_DIMS (ret
)[k
].inc
= inc
;
1436 inc
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1438 SCM_ARRAY_V (ret
) = scm_make_uve (inc
, scm_array_prototype (ra
));
1440 scm_array_copy_x (ra
, ret
);
1446 SCM_DEFINE (scm_uniform_array_read_x
, "uniform-array-read!", 1, 3, 0,
1447 (SCM ra
, SCM port_or_fd
, SCM start
, SCM end
),
1448 "@deffnx {Scheme Procedure} uniform-vector-read! uve [port-or-fdes] [start] [end]\n"
1449 "Attempt to read all elements of @var{ura}, in lexicographic order, as\n"
1450 "binary objects from @var{port-or-fdes}.\n"
1451 "If an end of file is encountered,\n"
1452 "the objects up to that point are put into @var{ura}\n"
1453 "(starting at the beginning) and the remainder of the array is\n"
1455 "The optional arguments @var{start} and @var{end} allow\n"
1456 "a specified region of a vector (or linearized array) to be read,\n"
1457 "leaving the remainder of the vector unchanged.\n\n"
1458 "@code{uniform-array-read!} returns the number of objects read.\n"
1459 "@var{port-or-fdes} may be omitted, in which case it defaults to the value\n"
1460 "returned by @code{(current-input-port)}.")
1461 #define FUNC_NAME s_scm_uniform_array_read_x
1463 SCM cra
= SCM_UNDEFINED
, v
= ra
;
1470 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1471 if (SCM_UNBNDP (port_or_fd
))
1472 port_or_fd
= scm_cur_inp
;
1474 SCM_ASSERT (SCM_INUMP (port_or_fd
)
1475 || (SCM_OPINPORTP (port_or_fd
)),
1476 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1477 vlen
= (SCM_TYP7 (v
) == scm_tc7_smob
1479 : SCM_INUM (scm_uniform_vector_length (v
)));
1485 badarg1
:SCM_WRONG_TYPE_ARG (SCM_ARG1
, v
);
1487 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1488 cra
= scm_ra2contig (ra
, 0);
1489 cstart
+= SCM_ARRAY_BASE (cra
);
1490 vlen
= SCM_ARRAY_DIMS (cra
)->inc
*
1491 (SCM_ARRAY_DIMS (cra
)->ubnd
- SCM_ARRAY_DIMS (cra
)->lbnd
+ 1);
1492 v
= SCM_ARRAY_V (cra
);
1494 case scm_tc7_string
:
1495 base
= SCM_STRING_CHARS (v
);
1499 base
= (char *) SCM_BITVECTOR_BASE (v
);
1500 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1501 cstart
/= SCM_LONG_BIT
;
1504 case scm_tc7_byvect
:
1505 base
= (char *) SCM_UVECTOR_BASE (v
);
1510 base
= (char *) SCM_UVECTOR_BASE (v
);
1514 base
= (char *) SCM_UVECTOR_BASE (v
);
1515 sz
= sizeof (short);
1517 #if SCM_SIZEOF_LONG_LONG != 0
1518 case scm_tc7_llvect
:
1519 base
= (char *) SCM_UVECTOR_BASE (v
);
1520 sz
= sizeof (long long);
1524 base
= (char *) SCM_UVECTOR_BASE (v
);
1525 sz
= sizeof (float);
1528 base
= (char *) SCM_UVECTOR_BASE (v
);
1529 sz
= sizeof (double);
1532 base
= (char *) SCM_UVECTOR_BASE (v
);
1533 sz
= 2 * sizeof (double);
1538 if (!SCM_UNBNDP (start
))
1541 SCM_NUM2LONG (3, start
);
1543 if (offset
< 0 || offset
>= cend
)
1544 scm_out_of_range (FUNC_NAME
, start
);
1546 if (!SCM_UNBNDP (end
))
1549 SCM_NUM2LONG (4, end
);
1551 if (tend
<= offset
|| tend
> cend
)
1552 scm_out_of_range (FUNC_NAME
, end
);
1557 if (SCM_NIMP (port_or_fd
))
1559 scm_t_port
*pt
= SCM_PTAB_ENTRY (port_or_fd
);
1560 int remaining
= (cend
- offset
) * sz
;
1561 char *dest
= base
+ (cstart
+ offset
) * sz
;
1563 if (pt
->rw_active
== SCM_PORT_WRITE
)
1564 scm_flush (port_or_fd
);
1566 ans
= cend
- offset
;
1567 while (remaining
> 0)
1569 if (pt
->read_pos
< pt
->read_end
)
1571 int to_copy
= min (pt
->read_end
- pt
->read_pos
,
1574 memcpy (dest
, pt
->read_pos
, to_copy
);
1575 pt
->read_pos
+= to_copy
;
1576 remaining
-= to_copy
;
1581 if (scm_fill_input (port_or_fd
) == EOF
)
1583 if (remaining
% sz
!= 0)
1585 SCM_MISC_ERROR ("unexpected EOF", SCM_EOL
);
1587 ans
-= remaining
/ sz
;
1594 pt
->rw_active
= SCM_PORT_READ
;
1596 else /* file descriptor. */
1598 SCM_SYSCALL (ans
= read (SCM_INUM (port_or_fd
),
1599 base
+ (cstart
+ offset
) * sz
,
1600 (sz
* (cend
- offset
))));
1604 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1605 ans
*= SCM_LONG_BIT
;
1607 if (!SCM_EQ_P (v
, ra
) && !SCM_EQ_P (cra
, ra
))
1608 scm_array_copy_x (cra
, ra
);
1610 return SCM_I_MAKINUM (ans
);
1614 SCM_DEFINE (scm_uniform_array_write
, "uniform-array-write", 1, 3, 0,
1615 (SCM v
, SCM port_or_fd
, SCM start
, SCM end
),
1616 "@deffnx {Scheme Procedure} uniform-vector-write uve [port-or-fdes] [start] [end]\n"
1617 "Writes all elements of @var{ura} as binary objects to\n"
1618 "@var{port-or-fdes}.\n\n"
1619 "The optional arguments @var{start}\n"
1620 "and @var{end} allow\n"
1621 "a specified region of a vector (or linearized array) to be written.\n\n"
1622 "The number of objects actually written is returned.\n"
1623 "@var{port-or-fdes} may be\n"
1624 "omitted, in which case it defaults to the value returned by\n"
1625 "@code{(current-output-port)}.")
1626 #define FUNC_NAME s_scm_uniform_array_write
1634 port_or_fd
= SCM_COERCE_OUTPORT (port_or_fd
);
1636 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1637 if (SCM_UNBNDP (port_or_fd
))
1638 port_or_fd
= scm_cur_outp
;
1640 SCM_ASSERT (SCM_INUMP (port_or_fd
)
1641 || (SCM_OPOUTPORTP (port_or_fd
)),
1642 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1643 vlen
= (SCM_TYP7 (v
) == scm_tc7_smob
1645 : SCM_INUM (scm_uniform_vector_length (v
)));
1651 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
1653 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1654 v
= scm_ra2contig (v
, 1);
1655 cstart
= SCM_ARRAY_BASE (v
);
1656 vlen
= (SCM_ARRAY_DIMS (v
)->inc
1657 * (SCM_ARRAY_DIMS (v
)->ubnd
- SCM_ARRAY_DIMS (v
)->lbnd
+ 1));
1658 v
= SCM_ARRAY_V (v
);
1660 case scm_tc7_string
:
1661 base
= SCM_STRING_CHARS (v
);
1665 base
= (char *) SCM_BITVECTOR_BASE (v
);
1666 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1667 cstart
/= SCM_LONG_BIT
;
1670 case scm_tc7_byvect
:
1671 base
= (char *) SCM_UVECTOR_BASE (v
);
1676 base
= (char *) SCM_UVECTOR_BASE (v
);
1680 base
= (char *) SCM_UVECTOR_BASE (v
);
1681 sz
= sizeof (short);
1683 #if SCM_SIZEOF_LONG_LONG != 0
1684 case scm_tc7_llvect
:
1685 base
= (char *) SCM_UVECTOR_BASE (v
);
1686 sz
= sizeof (long long);
1690 base
= (char *) SCM_UVECTOR_BASE (v
);
1691 sz
= sizeof (float);
1694 base
= (char *) SCM_UVECTOR_BASE (v
);
1695 sz
= sizeof (double);
1698 base
= (char *) SCM_UVECTOR_BASE (v
);
1699 sz
= 2 * sizeof (double);
1704 if (!SCM_UNBNDP (start
))
1707 SCM_NUM2LONG (3, start
);
1709 if (offset
< 0 || offset
>= cend
)
1710 scm_out_of_range (FUNC_NAME
, start
);
1712 if (!SCM_UNBNDP (end
))
1715 SCM_NUM2LONG (4, end
);
1717 if (tend
<= offset
|| tend
> cend
)
1718 scm_out_of_range (FUNC_NAME
, end
);
1723 if (SCM_NIMP (port_or_fd
))
1725 char *source
= base
+ (cstart
+ offset
) * sz
;
1727 ans
= cend
- offset
;
1728 scm_lfwrite (source
, ans
* sz
, port_or_fd
);
1730 else /* file descriptor. */
1732 SCM_SYSCALL (ans
= write (SCM_INUM (port_or_fd
),
1733 base
+ (cstart
+ offset
) * sz
,
1734 (sz
* (cend
- offset
))));
1738 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1739 ans
*= SCM_LONG_BIT
;
1741 return SCM_I_MAKINUM (ans
);
1746 static char cnt_tab
[16] =
1747 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1749 SCM_DEFINE (scm_bit_count
, "bit-count", 2, 0, 0,
1750 (SCM b
, SCM bitvector
),
1751 "Return the number of occurrences of the boolean @var{b} in\n"
1753 #define FUNC_NAME s_scm_bit_count
1755 SCM_VALIDATE_BOOL (1, b
);
1756 SCM_ASSERT (SCM_BITVECTOR_P (bitvector
), bitvector
, 2, FUNC_NAME
);
1757 if (SCM_BITVECTOR_LENGTH (bitvector
) == 0) {
1760 unsigned long int count
= 0;
1761 unsigned long int i
= (SCM_BITVECTOR_LENGTH (bitvector
) - 1) / SCM_LONG_BIT
;
1762 unsigned long int w
= SCM_UNPACK (SCM_VELTS (bitvector
)[i
]);
1763 if (scm_is_false (b
)) {
1766 w
<<= SCM_LONG_BIT
- 1 - ((SCM_BITVECTOR_LENGTH (bitvector
) - 1) % SCM_LONG_BIT
);
1769 count
+= cnt_tab
[w
& 0x0f];
1773 return SCM_I_MAKINUM (count
);
1776 w
= SCM_UNPACK (SCM_VELTS (bitvector
)[i
]);
1777 if (scm_is_false (b
)) {
1787 SCM_DEFINE (scm_bit_position
, "bit-position", 3, 0, 0,
1788 (SCM item
, SCM v
, SCM k
),
1789 "Return the index of the first occurrance of @var{item} in bit\n"
1790 "vector @var{v}, starting from @var{k}. If there is no\n"
1791 "@var{item} entry between @var{k} and the end of\n"
1792 "@var{bitvector}, then return @code{#f}. For example,\n"
1795 "(bit-position #t #*000101 0) @result{} 3\n"
1796 "(bit-position #f #*0001111 3) @result{} #f\n"
1798 #define FUNC_NAME s_scm_bit_position
1800 long i
, lenw
, xbits
, pos
;
1801 register unsigned long w
;
1803 SCM_VALIDATE_BOOL (1, item
);
1804 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG2
, FUNC_NAME
);
1805 pos
= scm_to_long (k
);
1806 SCM_ASSERT_RANGE (3, k
, (pos
<= SCM_BITVECTOR_LENGTH (v
)) && (pos
>= 0));
1808 if (pos
== SCM_BITVECTOR_LENGTH (v
))
1811 lenw
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
; /* watch for part words */
1812 i
= pos
/ SCM_LONG_BIT
;
1813 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1814 if (scm_is_false (item
))
1816 xbits
= (pos
% SCM_LONG_BIT
);
1818 w
= ((w
>> xbits
) << xbits
);
1819 xbits
= SCM_LONG_BIT
- 1 - (SCM_BITVECTOR_LENGTH (v
) - 1) % SCM_LONG_BIT
;
1822 if (w
&& (i
== lenw
))
1823 w
= ((w
<< xbits
) >> xbits
);
1829 return SCM_I_MAKINUM (pos
);
1834 return SCM_I_MAKINUM (pos
+ 1);
1837 return SCM_I_MAKINUM (pos
+ 2);
1839 return SCM_I_MAKINUM (pos
+ 3);
1846 pos
+= SCM_LONG_BIT
;
1847 w
= SCM_UNPACK (SCM_VELTS (v
)[i
]);
1848 if (scm_is_false (item
))
1856 SCM_DEFINE (scm_bit_set_star_x
, "bit-set*!", 3, 0, 0,
1857 (SCM v
, SCM kv
, SCM obj
),
1858 "Set entries of bit vector @var{v} to @var{obj}, with @var{kv}\n"
1859 "selecting the entries to change. The return value is\n"
1862 "If @var{kv} is a bit vector, then those entries where it has\n"
1863 "@code{#t} are the ones in @var{v} which are set to @var{obj}.\n"
1864 "@var{kv} and @var{v} must be the same length. When @var{obj}\n"
1865 "is @code{#t} it's like @var{kv} is OR'ed into @var{v}. Or when\n"
1866 "@var{obj} is @code{#f} it can be seen as an ANDNOT.\n"
1869 "(define bv #*01000010)\n"
1870 "(bit-set*! bv #*10010001 #t)\n"
1872 "@result{} #*11010011\n"
1875 "If @var{kv} is a uniform vector of unsigned long integers, then\n"
1876 "they're indexes into @var{v} which are set to @var{obj}.\n"
1879 "(define bv #*01000010)\n"
1880 "(bit-set*! bv #u(5 2 7) #t)\n"
1882 "@result{} #*01100111\n"
1884 #define FUNC_NAME s_scm_bit_set_star_x
1886 register long i
, k
, vlen
;
1887 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
1888 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1889 switch SCM_TYP7 (kv
)
1892 badarg2
:SCM_WRONG_TYPE_ARG (2, kv
);
1894 vlen
= SCM_BITVECTOR_LENGTH (v
);
1895 if (scm_is_false (obj
))
1896 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1898 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1900 scm_out_of_range (FUNC_NAME
, SCM_I_MAKINUM (k
));
1901 SCM_BITVEC_CLR(v
, k
);
1903 else if (SCM_EQ_P (obj
, SCM_BOOL_T
))
1904 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1906 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1908 scm_out_of_range (FUNC_NAME
, SCM_I_MAKINUM (k
));
1909 SCM_BITVEC_SET(v
, k
);
1912 badarg3
:SCM_WRONG_TYPE_ARG (3, obj
);
1915 SCM_ASSERT (SCM_BITVECTOR_LENGTH (v
) == SCM_BITVECTOR_LENGTH (kv
), v
, SCM_ARG1
, FUNC_NAME
);
1916 if (scm_is_false (obj
))
1917 for (k
= (SCM_BITVECTOR_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1918 SCM_BITVECTOR_BASE (v
) [k
] &= ~SCM_BITVECTOR_BASE (kv
) [k
];
1919 else if (SCM_EQ_P (obj
, SCM_BOOL_T
))
1920 for (k
= (SCM_BITVECTOR_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1921 SCM_BITVECTOR_BASE (v
) [k
] |= SCM_BITVECTOR_BASE (kv
) [k
];
1926 return SCM_UNSPECIFIED
;
1931 SCM_DEFINE (scm_bit_count_star
, "bit-count*", 3, 0, 0,
1932 (SCM v
, SCM kv
, SCM obj
),
1933 "Return a count of how many entries in bit vector @var{v} are\n"
1934 "equal to @var{obj}, with @var{kv} selecting the entries to\n"
1937 "If @var{kv} is a bit vector, then those entries where it has\n"
1938 "@code{#t} are the ones in @var{v} which are considered.\n"
1939 "@var{kv} and @var{v} must be the same length.\n"
1941 "If @var{kv} is a uniform vector of unsigned long integers, then\n"
1942 "it's the indexes in @var{v} to consider.\n"
1947 "(bit-count* #*01110111 #*11001101 #t) @result{} 3\n"
1948 "(bit-count* #*01110111 #u(7 0 4) #f) @result{} 2\n"
1950 #define FUNC_NAME s_scm_bit_count_star
1952 register long i
, vlen
, count
= 0;
1953 register unsigned long k
;
1956 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
1957 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1958 switch SCM_TYP7 (kv
)
1962 SCM_WRONG_TYPE_ARG (2, kv
);
1964 vlen
= SCM_BITVECTOR_LENGTH (v
);
1965 if (scm_is_false (obj
))
1966 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1968 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1970 scm_out_of_range (FUNC_NAME
, SCM_I_MAKINUM (k
));
1971 if (!SCM_BITVEC_REF(v
, k
))
1974 else if (SCM_EQ_P (obj
, SCM_BOOL_T
))
1975 for (i
= SCM_UVECTOR_LENGTH (kv
); i
;)
1977 k
= SCM_UNPACK (SCM_VELTS (kv
)[--i
]);
1979 scm_out_of_range (FUNC_NAME
, SCM_I_MAKINUM (k
));
1980 if (SCM_BITVEC_REF (v
, k
))
1984 badarg3
:SCM_WRONG_TYPE_ARG (3, obj
);
1987 SCM_ASSERT (SCM_BITVECTOR_LENGTH (v
) == SCM_BITVECTOR_LENGTH (kv
), v
, SCM_ARG1
, FUNC_NAME
);
1988 if (0 == SCM_BITVECTOR_LENGTH (v
))
1990 SCM_ASRTGO (scm_is_bool (obj
), badarg3
);
1991 fObj
= SCM_EQ_P (obj
, SCM_BOOL_T
);
1992 i
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
;
1993 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK (SCM_VELTS (v
)[i
]) : ~ SCM_UNPACK (SCM_VELTS (v
)[i
]));
1994 k
<<= SCM_LONG_BIT
- 1 - ((SCM_BITVECTOR_LENGTH (v
) - 1) % SCM_LONG_BIT
);
1998 count
+= cnt_tab
[k
& 0x0f];
2000 return SCM_I_MAKINUM (count
);
2002 /* urg. repetitive (see above.) */
2003 k
= SCM_UNPACK (SCM_VELTS (kv
)[i
]) & (fObj
? SCM_UNPACK(SCM_VELTS (v
)[i
]) : ~SCM_UNPACK (SCM_VELTS (v
)[i
]));
2006 return SCM_I_MAKINUM (count
);
2011 SCM_DEFINE (scm_bit_invert_x
, "bit-invert!", 1, 0, 0,
2013 "Modify the bit vector @var{v} by replacing each element with\n"
2015 #define FUNC_NAME s_scm_bit_invert_x
2019 SCM_ASSERT (SCM_BITVECTOR_P (v
), v
, SCM_ARG1
, FUNC_NAME
);
2021 k
= SCM_BITVECTOR_LENGTH (v
);
2022 for (k
= (k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
2023 SCM_BITVECTOR_BASE (v
) [k
] = ~SCM_BITVECTOR_BASE (v
) [k
];
2025 return SCM_UNSPECIFIED
;
2031 scm_istr2bve (char *str
, long len
)
2033 SCM v
= scm_make_uve (len
, SCM_BOOL_T
);
2034 long *data
= (long *) SCM_VELTS (v
);
2035 register unsigned long mask
;
2038 for (k
= 0; k
< (len
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
++)
2041 j
= len
- k
* SCM_LONG_BIT
;
2042 if (j
> SCM_LONG_BIT
)
2044 for (mask
= 1L; j
--; mask
<<= 1)
2062 ra2l (SCM ra
, unsigned long base
, unsigned long k
)
2064 register SCM res
= SCM_EOL
;
2065 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2067 if (SCM_ARRAY_DIMS (ra
)[k
].ubnd
< SCM_ARRAY_DIMS (ra
)[k
].lbnd
)
2069 i
= base
+ (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
) * inc
;
2070 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2075 res
= scm_cons (ra2l (ra
, i
, k
+ 1), res
);
2083 res
= scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra
), SCM_I_MAKINUM (i
)), res
);
2090 SCM_DEFINE (scm_array_to_list
, "array->list", 1, 0, 0,
2092 "Return a list consisting of all the elements, in order, of\n"
2094 #define FUNC_NAME s_scm_array_to_list
2098 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
2102 badarg1
:SCM_WRONG_TYPE_ARG (1, v
);
2104 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
2105 return ra2l (v
, SCM_ARRAY_BASE (v
), 0);
2106 case scm_tc7_vector
:
2108 return scm_vector_to_list (v
);
2109 case scm_tc7_string
:
2110 return scm_string_to_list (v
);
2113 long *data
= (long *) SCM_VELTS (v
);
2114 register unsigned long mask
;
2115 for (k
= (SCM_BITVECTOR_LENGTH (v
) - 1) / SCM_LONG_BIT
; k
> 0; k
--)
2116 for (mask
= 1UL << (SCM_LONG_BIT
- 1); mask
; mask
>>= 1)
2117 res
= scm_cons (scm_from_bool(((long *) data
)[k
] & mask
), res
);
2118 for (mask
= 1L << ((SCM_BITVECTOR_LENGTH (v
) % SCM_LONG_BIT
) - 1); mask
; mask
>>= 1)
2119 res
= scm_cons (scm_from_bool(((long *) data
)[k
] & mask
), res
);
2122 case scm_tc7_byvect
:
2124 signed char *data
= (signed char *) SCM_VELTS (v
);
2125 unsigned long k
= SCM_UVECTOR_LENGTH (v
);
2127 res
= scm_cons (SCM_I_MAKINUM (data
[--k
]), res
);
2132 long *data
= (long *)SCM_VELTS(v
);
2133 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2134 res
= scm_cons(scm_ulong2num(data
[k
]), res
);
2139 long *data
= (long *)SCM_VELTS(v
);
2140 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2141 res
= scm_cons(scm_long2num(data
[k
]), res
);
2146 short *data
= (short *)SCM_VELTS(v
);
2147 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2148 res
= scm_cons(scm_short2num (data
[k
]), res
);
2151 #if SCM_SIZEOF_LONG_LONG != 0
2152 case scm_tc7_llvect
:
2154 long long *data
= (long long *)SCM_VELTS(v
);
2155 for (k
= SCM_UVECTOR_LENGTH(v
) - 1; k
>= 0; k
--)
2156 res
= scm_cons(scm_long_long2num(data
[k
]), res
);
2162 float *data
= (float *) SCM_VELTS (v
);
2163 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2164 res
= scm_cons (scm_make_real (data
[k
]), res
);
2169 double *data
= (double *) SCM_VELTS (v
);
2170 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2171 res
= scm_cons (scm_make_real (data
[k
]), res
);
2176 double (*data
)[2] = (double (*)[2]) SCM_VELTS (v
);
2177 for (k
= SCM_UVECTOR_LENGTH (v
) - 1; k
>= 0; k
--)
2178 res
= scm_cons (scm_make_complex (data
[k
][0], data
[k
][1]), res
);
2186 static int l2ra(SCM lst
, SCM ra
, unsigned long base
, unsigned long k
);
2188 SCM_DEFINE (scm_list_to_uniform_array
, "list->uniform-array", 3, 0, 0,
2189 (SCM ndim
, SCM prot
, SCM lst
),
2190 "@deffnx {Scheme Procedure} list->uniform-vector prot lst\n"
2191 "Return a uniform array of the type indicated by prototype\n"
2192 "@var{prot} with elements the same as those of @var{lst}.\n"
2193 "Elements must be of the appropriate type, no coercions are\n"
2195 #define FUNC_NAME s_scm_list_to_uniform_array
2202 k
= scm_to_ulong (ndim
);
2205 n
= scm_ilength (row
);
2206 SCM_ASSERT (n
>= 0, lst
, SCM_ARG3
, FUNC_NAME
);
2207 shp
= scm_cons (SCM_I_MAKINUM (n
), shp
);
2209 row
= SCM_CAR (row
);
2211 ra
= scm_dimensions_to_uniform_array (scm_reverse (shp
), prot
,
2213 if (SCM_NULLP (shp
))
2215 SCM_ASRTGO (1 == scm_ilength (lst
), badlst
);
2216 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_EOL
);
2219 if (!SCM_ARRAYP (ra
))
2221 unsigned long int length
= SCM_INUM (scm_uniform_vector_length (ra
));
2222 for (k
= 0; k
< length
; k
++, lst
= SCM_CDR (lst
))
2223 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_I_MAKINUM (k
));
2226 if (l2ra (lst
, ra
, SCM_ARRAY_BASE (ra
), 0))
2229 badlst
:SCM_MISC_ERROR ("Bad scm_array contents list: ~S",
2235 l2ra (SCM lst
, SCM ra
, unsigned long base
, unsigned long k
)
2237 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2238 register long n
= (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
);
2241 return (SCM_NULLP (lst
));
2242 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2246 if (!SCM_CONSP (lst
))
2248 ok
= ok
&& l2ra (SCM_CAR (lst
), ra
, base
, k
+ 1);
2250 lst
= SCM_CDR (lst
);
2252 if (!SCM_NULLP (lst
))
2259 if (!SCM_CONSP (lst
))
2261 scm_array_set_x (SCM_ARRAY_V (ra
), SCM_CAR (lst
), SCM_I_MAKINUM (base
));
2263 lst
= SCM_CDR (lst
);
2265 if (!SCM_NULLP (lst
))
2273 rapr1 (SCM ra
, unsigned long j
, unsigned long k
, SCM port
, scm_print_state
*pstate
)
2276 long n
= (SCM_TYP7 (ra
) == scm_tc7_smob
2278 : SCM_INUM (scm_uniform_vector_length (ra
)));
2281 switch SCM_TYP7 (ra
)
2286 SCM_ARRAY_BASE (ra
) = j
;
2288 scm_iprin1 (ra
, port
, pstate
);
2289 for (j
+= inc
; n
-- > 0; j
+= inc
)
2291 scm_putc (' ', port
);
2292 SCM_ARRAY_BASE (ra
) = j
;
2293 scm_iprin1 (ra
, port
, pstate
);
2297 if (k
+ 1 < SCM_ARRAY_NDIM (ra
))
2300 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2301 for (i
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
; i
< SCM_ARRAY_DIMS (ra
)[k
].ubnd
; i
++)
2303 scm_putc ('(', port
);
2304 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2305 scm_puts (") ", port
);
2308 if (i
== SCM_ARRAY_DIMS (ra
)[k
].ubnd
)
2309 { /* could be zero size. */
2310 scm_putc ('(', port
);
2311 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2312 scm_putc (')', port
);
2316 if (SCM_ARRAY_NDIM (ra
) > 0)
2317 { /* Could be zero-dimensional */
2318 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2319 n
= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
2323 ra
= SCM_ARRAY_V (ra
);
2326 /* scm_tc7_bvect and scm_tc7_llvect only? */
2328 scm_iprin1 (scm_uniform_vector_ref (ra
, SCM_I_MAKINUM (j
)), port
, pstate
);
2329 for (j
+= inc
; n
-- > 0; j
+= inc
)
2331 scm_putc (' ', port
);
2332 scm_iprin1 (scm_cvref (ra
, j
, SCM_UNDEFINED
), port
, pstate
);
2335 case scm_tc7_string
:
2337 scm_iprin1 (SCM_MAKE_CHAR (SCM_STRING_UCHARS (ra
)[j
]), port
, pstate
);
2338 if (SCM_WRITINGP (pstate
))
2339 for (j
+= inc
; n
-- > 0; j
+= inc
)
2341 scm_putc (' ', port
);
2342 scm_iprin1 (SCM_MAKE_CHAR (SCM_STRING_UCHARS (ra
)[j
]), port
, pstate
);
2345 for (j
+= inc
; n
-- > 0; j
+= inc
)
2346 scm_putc (SCM_STRING_CHARS (ra
)[j
], port
);
2348 case scm_tc7_byvect
:
2350 scm_intprint (((char *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2351 for (j
+= inc
; n
-- > 0; j
+= inc
)
2353 scm_putc (' ', port
);
2354 scm_intprint (((char *)SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2364 /* intprint can't handle >= 2^31. */
2365 sprintf (str
, "%lu", ((unsigned long *) SCM_VELTS (ra
))[j
]);
2366 scm_puts (str
, port
);
2368 for (j
+= inc
; n
-- > 0; j
+= inc
)
2370 scm_putc (' ', port
);
2371 sprintf (str
, "%lu", ((unsigned long *) SCM_VELTS (ra
))[j
]);
2372 scm_puts (str
, port
);
2377 scm_intprint (((signed long *) SCM_VELTS (ra
))[j
], 10, port
);
2378 for (j
+= inc
; n
-- > 0; j
+= inc
)
2380 scm_putc (' ', port
);
2381 scm_intprint (((signed long *) SCM_VELTS (ra
))[j
], 10, port
);
2387 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2388 for (j
+= inc
; n
-- > 0; j
+= inc
)
2390 scm_putc (' ', port
);
2391 scm_intprint (((short *) SCM_CELL_WORD_1 (ra
))[j
], 10, port
);
2398 SCM z
= scm_make_real (1.0);
2399 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2400 scm_print_real (z
, port
, pstate
);
2401 for (j
+= inc
; n
-- > 0; j
+= inc
)
2403 scm_putc (' ', port
);
2404 SCM_REAL_VALUE (z
) = ((float *) SCM_VELTS (ra
))[j
];
2405 scm_print_real (z
, port
, pstate
);
2412 SCM z
= scm_make_real (1.0 / 3.0);
2413 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2414 scm_print_real (z
, port
, pstate
);
2415 for (j
+= inc
; n
-- > 0; j
+= inc
)
2417 scm_putc (' ', port
);
2418 SCM_REAL_VALUE (z
) = ((double *) SCM_VELTS (ra
))[j
];
2419 scm_print_real (z
, port
, pstate
);
2426 SCM cz
= scm_make_complex (0.0, 1.0), z
= scm_make_real (1.0 / 3.0);
2427 SCM_REAL_VALUE (z
) =
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
),
2432 for (j
+= inc
; n
-- > 0; j
+= inc
)
2434 scm_putc (' ', port
);
2436 = SCM_COMPLEX_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2437 SCM_COMPLEX_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2438 scm_print_complex ((0.0 == SCM_COMPLEX_IMAG (cz
) ? z
: cz
),
2449 scm_raprin1 (SCM exp
, SCM port
, scm_print_state
*pstate
)
2452 unsigned long base
= 0;
2453 scm_putc ('#', port
);
2459 long ndim
= SCM_ARRAY_NDIM (v
);
2460 base
= SCM_ARRAY_BASE (v
);
2461 v
= SCM_ARRAY_V (v
);
2465 scm_puts ("<enclosed-array ", port
);
2466 rapr1 (exp
, base
, 0, port
, pstate
);
2467 scm_putc ('>', port
);
2472 scm_intprint (ndim
, 10, port
);
2477 if (SCM_EQ_P (exp
, v
))
2478 { /* a uve, not an scm_array */
2479 register long i
, j
, w
;
2480 scm_putc ('*', port
);
2481 for (i
= 0; i
< (SCM_BITVECTOR_LENGTH (exp
)) / SCM_LONG_BIT
; i
++)
2483 scm_t_bits w
= SCM_UNPACK (SCM_VELTS (exp
)[i
]);
2484 for (j
= SCM_LONG_BIT
; j
; j
--)
2486 scm_putc (w
& 1 ? '1' : '0', port
);
2490 j
= SCM_BITVECTOR_LENGTH (exp
) % SCM_LONG_BIT
;
2493 w
= SCM_UNPACK (SCM_VELTS (exp
)[SCM_BITVECTOR_LENGTH (exp
) / SCM_LONG_BIT
]);
2496 scm_putc (w
& 1 ? '1' : '0', port
);
2503 scm_putc ('b', port
);
2505 case scm_tc7_string
:
2506 scm_putc ('a', port
);
2508 case scm_tc7_byvect
:
2509 scm_putc ('y', port
);
2512 scm_putc ('u', port
);
2515 scm_putc ('e', port
);
2518 scm_putc ('h', port
);
2520 #if SCM_SIZEOF_LONG_LONG != 0
2521 case scm_tc7_llvect
:
2522 scm_putc ('l', port
);
2526 scm_putc ('s', port
);
2529 scm_putc ('i', port
);
2532 scm_putc ('c', port
);
2535 scm_putc ('(', port
);
2536 rapr1 (exp
, base
, 0, port
, pstate
);
2537 scm_putc (')', port
);
2541 SCM_DEFINE (scm_array_prototype
, "array-prototype", 1, 0, 0,
2543 "Return an object that would produce an array of the same type\n"
2544 "as @var{array}, if used as the @var{prototype} for\n"
2545 "@code{make-uniform-array}.")
2546 #define FUNC_NAME s_scm_array_prototype
2549 SCM_ASRTGO (SCM_NIMP (ra
), badarg
);
2551 switch SCM_TYP7 (ra
)
2554 badarg
:SCM_WRONG_TYPE_ARG (1, ra
);
2556 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
2558 return SCM_UNSPECIFIED
;
2559 ra
= SCM_ARRAY_V (ra
);
2561 case scm_tc7_vector
:
2566 case scm_tc7_string
:
2567 return SCM_MAKE_CHAR ('a');
2568 case scm_tc7_byvect
:
2569 return SCM_MAKE_CHAR ('\0');
2571 return SCM_I_MAKINUM (1L);
2573 return SCM_I_MAKINUM (-1L);
2575 return scm_str2symbol ("s");
2576 #if SCM_SIZEOF_LONG_LONG != 0
2577 case scm_tc7_llvect
:
2578 return scm_str2symbol ("l");
2581 return scm_make_real (1.0);
2583 return exactly_one_third
;
2585 return scm_make_complex (0.0, 1.0);
2592 array_mark (SCM ptr
)
2594 return SCM_ARRAY_V (ptr
);
2599 array_free (SCM ptr
)
2601 scm_gc_free (SCM_ARRAY_MEM (ptr
),
2602 (sizeof (scm_t_array
)
2603 + SCM_ARRAY_NDIM (ptr
) * sizeof (scm_t_array_dim
)),
2611 scm_tc16_array
= scm_make_smob_type ("array", 0);
2612 scm_set_smob_mark (scm_tc16_array
, array_mark
);
2613 scm_set_smob_free (scm_tc16_array
, array_free
);
2614 scm_set_smob_print (scm_tc16_array
, scm_raprin1
);
2615 scm_set_smob_equalp (scm_tc16_array
, scm_array_equal_p
);
2616 exactly_one_third
= scm_permanent_object (scm_make_ratio (SCM_I_MAKINUM (1),
2617 SCM_I_MAKINUM (3)));
2618 scm_add_feature ("array");
2619 #include "libguile/unif.x"