1 /* Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
8 * This program 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
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
42 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
56 #include "scm_validate.h"
65 /* The set of uniform scm_vector types is:
67 * unsigned char string
74 * complex double cvect
81 /* return the size of an element in a uniform array or 0 if type not
84 scm_uniform_element_size (SCM obj
)
88 switch (SCM_TYP7 (obj
))
93 result
= sizeof (long);
97 result
= sizeof (char);
101 result
= sizeof (short);
104 #ifdef HAVE_LONG_LONGS
106 result
= sizeof (long_long
);
113 result
= sizeof (float);
118 result
= sizeof (double);
122 result
= 2 * sizeof (double);
145 SCM_SETCAR (z
, scm_tc_flo
);
155 scm_make_uve (long k
, SCM prot
)
159 if (SCM_BOOL_T
== prot
)
161 i
= sizeof (long) * ((k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
);
162 type
= scm_tc7_bvect
;
164 else if (SCM_ICHRP (prot
) && (prot
== SCM_MAKICHR ('\0')))
166 i
= sizeof (char) * k
;
167 type
= scm_tc7_byvect
;
169 else if (SCM_ICHRP (prot
))
171 i
= sizeof (char) * k
;
172 type
= scm_tc7_string
;
174 else if (SCM_INUMP (prot
))
176 i
= sizeof (long) * k
;
177 if (SCM_INUM (prot
) > 0)
178 type
= scm_tc7_uvect
;
180 type
= scm_tc7_ivect
;
182 else if (SCM_SYMBOLP (prot
) && (1 == SCM_LENGTH (prot
)))
186 s
= SCM_CHARS (prot
)[0];
189 i
= sizeof (short) * k
;
190 type
= scm_tc7_svect
;
192 #ifdef HAVE_LONG_LONGS
195 i
= sizeof (long_long
) * k
;
196 type
= scm_tc7_llvect
;
201 return scm_make_vector (SCM_MAKINUM (k
), SCM_UNDEFINED
);
206 if (SCM_IMP (prot
) || !SCM_INEXP (prot
))
208 /* Huge non-unif vectors are NOT supported. */
209 /* no special scm_vector */
210 return scm_make_vector (SCM_MAKINUM (k
), SCM_UNDEFINED
);
213 else if (SCM_SINGP (prot
))
216 i
= sizeof (float) * k
;
217 type
= scm_tc7_fvect
;
220 else if (SCM_CPLXP (prot
))
222 i
= 2 * sizeof (double) * k
;
223 type
= scm_tc7_cvect
;
227 i
= sizeof (double) * k
;
228 type
= scm_tc7_dvect
;
234 SCM_SETCHARS (v
, (char *) scm_must_malloc (i
? i
: 1, "vector"));
235 SCM_SETLENGTH (v
, (k
< SCM_LENGTH_MAX
? k
: SCM_LENGTH_MAX
), type
);
240 GUILE_PROC(scm_uniform_vector_length
, "uniform-vector-length", 1, 0, 0,
242 "Returns the number of elements in @var{uve}.")
243 #define FUNC_NAME s_scm_uniform_vector_length
245 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
250 badarg1
:SCM_WTA(1,v
);
262 #ifdef HAVE_LONG_LONGS
265 return SCM_MAKINUM (SCM_LENGTH (v
));
270 GUILE_PROC(scm_array_p
, "array?", 1, 1, 0,
272 "Returns @code{#t} if the @var{obj} is an array, and @code{#f} if not.
274 The @var{prototype} argument is used with uniform arrays and is described
276 #define FUNC_NAME s_scm_array_p
280 nprot
= SCM_UNBNDP (prot
);
285 switch (SCM_TYP7 (v
))
297 return nprot
|| SCM_BOOL(SCM_BOOL_T
==prot
);
299 return nprot
|| SCM_BOOL(SCM_ICHRP(prot
) && (prot
!= SCM_MAKICHR('\0')));
301 return nprot
|| SCM_BOOL(prot
== SCM_MAKICHR('\0'));
303 return nprot
|| SCM_BOOL(SCM_INUMP(prot
) && SCM_INUM(prot
)>0);
305 return nprot
|| SCM_BOOL(SCM_INUMP(prot
) && SCM_INUM(prot
)<=0);
309 && SCM_SYMBOLP (prot
)
310 && (1 == SCM_LENGTH (prot
))
311 && ('s' == SCM_CHARS (prot
)[0])));
312 #ifdef HAVE_LONG_LONGS
316 && SCM_SYMBOLP (prot
)
317 && (1 == SCM_LENGTH (prot
))
318 && ('s' == SCM_CHARS (prot
)[0])));
323 return nprot
|| SCM_BOOL(SCM_SINGP(prot
));
326 return nprot
|| SCM_BOOL(SCM_REALP(prot
));
328 return nprot
|| SCM_BOOL(SCM_CPLXP(prot
));
332 return nprot
|| SCM_BOOL(SCM_NULLP(prot
));
340 GUILE_PROC(scm_array_rank
, "array-rank", 1, 0, 0,
342 "Returns the number of dimensions of @var{obj}. If @var{obj} is not an
343 array, @code{0} is returned.")
344 #define FUNC_NAME s_scm_array_rank
348 switch (SCM_TYP7 (ra
))
361 #ifdef HAVE_LONG_LONGS
365 return SCM_MAKINUM (1L);
368 return SCM_MAKINUM (SCM_ARRAY_NDIM (ra
));
375 GUILE_PROC(scm_array_dimensions
, "array-dimensions", 1, 0, 0,
377 "@code{Array-dimensions} is similar to @code{array-shape} but replaces
378 elements with a @code{0} minimum with one greater than the maximum. So:
380 (array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5)
382 #define FUNC_NAME s_scm_array_dimensions
389 switch (SCM_TYP7 (ra
))
404 #ifdef HAVE_LONG_LONGS
407 return scm_cons (SCM_MAKINUM (SCM_LENGTH (ra
)), SCM_EOL
);
409 if (!SCM_ARRAYP (ra
))
411 k
= SCM_ARRAY_NDIM (ra
);
412 s
= SCM_ARRAY_DIMS (ra
);
414 res
= scm_cons (s
[k
].lbnd
? scm_cons2 (SCM_MAKINUM (s
[k
].lbnd
), SCM_MAKINUM (s
[k
].ubnd
), SCM_EOL
) :
415 SCM_MAKINUM (1 + (s
[k
].ubnd
))
423 static char s_bad_ind
[] = "Bad scm_array index";
427 scm_aind (SCM ra
, SCM args
, const char *what
)
431 register scm_sizet pos
= SCM_ARRAY_BASE (ra
);
432 register scm_sizet k
= SCM_ARRAY_NDIM (ra
);
433 scm_array_dim
*s
= SCM_ARRAY_DIMS (ra
);
434 if (SCM_INUMP (args
))
436 SCM_ASSERT (1 == k
, scm_makfrom0str (what
), SCM_WNA
, NULL
);
437 return pos
+ (SCM_INUM (args
) - s
->lbnd
) * (s
->inc
);
439 while (k
&& SCM_NIMP (args
))
441 ind
= SCM_CAR (args
);
442 args
= SCM_CDR (args
);
443 SCM_ASSERT (SCM_INUMP (ind
), ind
, s_bad_ind
, what
);
445 SCM_ASSERT (j
>= (s
->lbnd
) && j
<= (s
->ubnd
), ind
, SCM_OUTOFRANGE
, what
);
446 pos
+= (j
- s
->lbnd
) * (s
->inc
);
450 SCM_ASSERT (0 == k
&& SCM_NULLP (args
), scm_makfrom0str (what
), SCM_WNA
,
458 scm_make_ra (int ndim
)
463 SCM_NEWSMOB(ra
, ((long) ndim
<< 17) + scm_tc16_array
,
464 scm_must_malloc ((long) (sizeof (scm_array
) + ndim
* sizeof (scm_array_dim
)),
466 SCM_ARRAY_V (ra
) = scm_nullvect
;
471 static char s_bad_spec
[] = "Bad scm_array dimension";
472 /* Increments will still need to be set. */
476 scm_shap2ra (SCM args
, const char *what
)
480 int ndim
= scm_ilength (args
);
481 SCM_ASSERT (0 <= ndim
, args
, s_bad_spec
, what
);
482 ra
= scm_make_ra (ndim
);
483 SCM_ARRAY_BASE (ra
) = 0;
484 s
= SCM_ARRAY_DIMS (ra
);
485 for (; SCM_NIMP (args
); s
++, args
= SCM_CDR (args
))
487 spec
= SCM_CAR (args
);
491 SCM_ASSERT (SCM_INUMP (spec
) && SCM_INUM (spec
) >= 0, spec
,
494 s
->ubnd
= SCM_INUM (spec
) - 1;
499 SCM_ASSERT (SCM_CONSP (spec
) && SCM_INUMP (SCM_CAR (spec
)), spec
,
501 s
->lbnd
= SCM_INUM (SCM_CAR (spec
));
503 SCM_ASSERT (SCM_CONSP (sp
)
504 && SCM_INUMP (SCM_CAR (sp
)) && SCM_NULLP (SCM_CDR (sp
)),
505 spec
, s_bad_spec
, what
);
506 s
->ubnd
= SCM_INUM (SCM_CAR (sp
));
513 GUILE_PROC(scm_dimensions_to_uniform_array
, "dimensions->uniform-array", 2, 1, 0,
514 (SCM dims
, SCM prot
, SCM fill
),
515 "@deffnx primitive make-uniform-vector length prototype [fill]
516 Creates and returns a uniform array or vector of type corresponding to
517 @var{prototype} with dimensions @var{dims} or length @var{length}. If
518 @var{fill} is supplied, it's used to fill the array, otherwise
519 @var{prototype} is used.")
520 #define FUNC_NAME s_scm_dimensions_to_uniform_array
522 scm_sizet k
, vlen
= 1;
526 if (SCM_INUMP (dims
))
528 if (SCM_INUM (dims
) < SCM_LENGTH_MAX
)
530 SCM answer
= scm_make_uve (SCM_INUM (dims
), prot
);
532 if (!SCM_UNBNDP (fill
))
533 scm_array_fill_x (answer
, fill
);
534 else if (SCM_SYMBOLP (prot
))
535 scm_array_fill_x (answer
, SCM_MAKINUM (0));
537 scm_array_fill_x (answer
, prot
);
541 dims
= scm_cons (dims
, SCM_EOL
);
543 SCM_ASSERT (SCM_NULLP (dims
) || SCM_CONSP (dims
),
544 dims
, SCM_ARG1
, FUNC_NAME
);
545 ra
= scm_shap2ra (dims
, FUNC_NAME
);
546 SCM_SETOR_CAR (ra
, SCM_ARRAY_CONTIGUOUS
);
547 s
= SCM_ARRAY_DIMS (ra
);
548 k
= SCM_ARRAY_NDIM (ra
);
551 s
[k
].inc
= (rlen
> 0 ? rlen
: 0);
552 rlen
= (s
[k
].ubnd
- s
[k
].lbnd
+ 1) * s
[k
].inc
;
553 vlen
*= (s
[k
].ubnd
- s
[k
].lbnd
+ 1);
555 if (rlen
< SCM_LENGTH_MAX
)
556 SCM_ARRAY_V (ra
) = scm_make_uve ((rlen
> 0 ? rlen
: 0L), prot
);
560 switch (SCM_TYP7 (scm_make_uve (0L, prot
)))
572 bit
= sizeof (float) * SCM_CHAR_BIT
/ sizeof (char);
575 bit
= sizeof (double) * SCM_CHAR_BIT
/ sizeof (char);
578 bit
= 2 * sizeof (double) * SCM_CHAR_BIT
/ sizeof (char);
581 SCM_ARRAY_BASE (ra
) = (SCM_LONG_BIT
+ bit
- 1) / bit
;
582 rlen
+= SCM_ARRAY_BASE (ra
);
583 SCM_ARRAY_V (ra
) = scm_make_uve (rlen
, prot
);
584 *((long *) SCM_VELTS (SCM_ARRAY_V (ra
))) = rlen
;
586 if (!SCM_UNBNDP (fill
))
588 scm_array_fill_x (ra
, fill
);
590 else if (SCM_SYMBOLP (prot
))
591 scm_array_fill_x (ra
, SCM_MAKINUM (0));
593 scm_array_fill_x (ra
, prot
);
594 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
595 if (s
->ubnd
< s
->lbnd
|| (0 == s
->lbnd
&& 1 == s
->inc
))
596 return SCM_ARRAY_V (ra
);
603 scm_ra_set_contp (SCM ra
)
605 scm_sizet k
= SCM_ARRAY_NDIM (ra
);
608 long inc
= SCM_ARRAY_DIMS (ra
)[k
- 1].inc
;
611 if (inc
!= SCM_ARRAY_DIMS (ra
)[k
].inc
)
613 SCM_SETAND_CAR (ra
, ~SCM_ARRAY_CONTIGUOUS
);
616 inc
*= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
617 - SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
620 SCM_SETOR_CAR (ra
, SCM_ARRAY_CONTIGUOUS
);
624 GUILE_PROC(scm_make_shared_array
, "make-shared-array", 2, 0, 1,
625 (SCM oldra
, SCM mapfunc
, SCM dims
),
626 "@code{make-shared-array} can be used to create shared subarrays of other
627 arrays. The @var{mapper} is a function that translates coordinates in
628 the new array into coordinates in the old array. A @var{mapper} must be
629 linear, and its range must stay within the bounds of the old array, but
630 it can be otherwise arbitrary. A simple example:
632 (define fred (make-array #f 8 8))
633 (define freds-diagonal
634 (make-shared-array fred (lambda (i) (list i i)) 8))
635 (array-set! freds-diagonal 'foo 3)
636 (array-ref fred 3 3) @result{} foo
638 (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))
639 (array-ref freds-center 0 0) @result{} foo
641 #define FUNC_NAME s_scm_make_shared_array
647 long old_min
, new_min
, old_max
, new_max
;
649 SCM_VALIDATE_ARRAY(1,oldra
);
650 SCM_VALIDATE_PROC(2,mapfunc
);
651 ra
= scm_shap2ra (dims
, FUNC_NAME
);
652 if (SCM_ARRAYP (oldra
))
654 SCM_ARRAY_V (ra
) = SCM_ARRAY_V (oldra
);
655 old_min
= old_max
= SCM_ARRAY_BASE (oldra
);
656 s
= SCM_ARRAY_DIMS (oldra
);
657 k
= SCM_ARRAY_NDIM (oldra
);
661 old_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
663 old_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
668 SCM_ARRAY_V (ra
) = oldra
;
670 old_max
= (long) SCM_LENGTH (oldra
) - 1;
673 s
= SCM_ARRAY_DIMS (ra
);
674 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
676 inds
= scm_cons (SCM_MAKINUM (s
[k
].lbnd
), inds
);
677 if (s
[k
].ubnd
< s
[k
].lbnd
)
679 if (1 == SCM_ARRAY_NDIM (ra
))
680 ra
= scm_make_uve (0L, scm_array_prototype (ra
));
682 SCM_ARRAY_V (ra
) = scm_make_uve (0L, scm_array_prototype (ra
));
686 imap
= scm_apply (mapfunc
, scm_reverse (inds
), SCM_EOL
);
687 if (SCM_ARRAYP (oldra
))
688 i
= (scm_sizet
) scm_aind (oldra
, imap
, FUNC_NAME
);
691 if (SCM_NINUMP (imap
))
694 SCM_ASSERT (1 == scm_ilength (imap
) && SCM_INUMP (SCM_CAR (imap
)),
695 imap
, s_bad_ind
, FUNC_NAME
);
696 imap
= SCM_CAR (imap
);
700 SCM_ARRAY_BASE (ra
) = new_min
= new_max
= i
;
702 k
= SCM_ARRAY_NDIM (ra
);
705 if (s
[k
].ubnd
> s
[k
].lbnd
)
707 SCM_SETCAR (indptr
, SCM_MAKINUM (SCM_INUM (SCM_CAR (indptr
)) + 1));
708 imap
= scm_apply (mapfunc
, scm_reverse (inds
), SCM_EOL
);
709 if (SCM_ARRAYP (oldra
))
711 s
[k
].inc
= scm_aind (oldra
, imap
, FUNC_NAME
) - i
;
714 if (SCM_NINUMP (imap
))
717 SCM_ASSERT (1 == scm_ilength (imap
) && SCM_INUMP (SCM_CAR (imap
)),
718 imap
, s_bad_ind
, FUNC_NAME
);
719 imap
= SCM_CAR (imap
);
721 s
[k
].inc
= (long) SCM_INUM (imap
) - i
;
725 new_max
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
727 new_min
+= (s
[k
].ubnd
- s
[k
].lbnd
) * s
[k
].inc
;
730 s
[k
].inc
= new_max
- new_min
+ 1; /* contiguous by default */
731 indptr
= SCM_CDR (indptr
);
733 SCM_ASSERT (old_min
<= new_min
&& old_max
>= new_max
, SCM_UNDEFINED
,
734 "mapping out of range", FUNC_NAME
);
735 if (1 == SCM_ARRAY_NDIM (ra
) && 0 == SCM_ARRAY_BASE (ra
))
737 if (1 == s
->inc
&& 0 == s
->lbnd
738 && SCM_LENGTH (SCM_ARRAY_V (ra
)) == 1 + s
->ubnd
)
739 return SCM_ARRAY_V (ra
);
740 if (s
->ubnd
< s
->lbnd
)
741 return scm_make_uve (0L, scm_array_prototype (ra
));
743 scm_ra_set_contp (ra
);
749 /* args are RA . DIMS */
750 GUILE_PROC(scm_transpose_array
, "transpose-array", 0, 0, 1,
752 "Returns an array sharing contents with @var{array}, but with dimensions
753 arranged in a different order. There must be one @var{dim} argument for
754 each dimension of @var{array}. @var{dim0}, @var{dim1}, @dots{} should
755 be integers between 0 and the rank of the array to be returned. Each
756 integer in that range must appear at least once in the argument list.
758 The values of @var{dim0}, @var{dim1}, @dots{} correspond to dimensions
759 in the array to be returned, their positions in the argument list to
760 dimensions of @var{array}. Several @var{dim}s may have the same value,
761 in which case the returned array will have smaller rank than
766 (transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))
767 (transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)
768 (transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}
769 #2((a 4) (b 5) (c 6))
771 #define FUNC_NAME s_scm_transpose_array
773 SCM ra
, res
, vargs
, *ve
= &vargs
;
774 scm_array_dim
*s
, *r
;
776 SCM_ASSERT (SCM_NNULLP (args
), scm_makfrom0str (FUNC_NAME
),
779 SCM_ASSERT (SCM_NIMP (ra
), ra
, SCM_ARG1
, FUNC_NAME
);
780 args
= SCM_CDR (args
);
781 switch (SCM_TYP7 (ra
))
784 badarg
:SCM_WTA (1,ra
);
794 #ifdef HAVE_LONG_LONGS
797 SCM_ASSERT (SCM_NIMP (args
) && SCM_NULLP (SCM_CDR (args
)),
798 scm_makfrom0str (FUNC_NAME
), SCM_WNA
, NULL
);
799 SCM_ASSERT (SCM_INUMP (SCM_CAR (args
)), SCM_CAR (args
), SCM_ARG2
,
801 SCM_ASSERT (SCM_INUM0
== SCM_CAR (args
), SCM_CAR (args
), SCM_OUTOFRANGE
,
805 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
806 vargs
= scm_vector (args
);
807 SCM_ASSERT (SCM_LENGTH (vargs
) == SCM_ARRAY_NDIM (ra
),
808 scm_makfrom0str (FUNC_NAME
), SCM_WNA
, NULL
);
809 ve
= SCM_VELTS (vargs
);
811 for (k
= 0; k
< SCM_ARRAY_NDIM (ra
); k
++)
813 SCM_ASSERT (SCM_INUMP (ve
[k
]), ve
[k
], (SCM_ARG2
+ k
),
815 i
= SCM_INUM (ve
[k
]);
816 SCM_ASSERT (i
>= 0 && i
< SCM_ARRAY_NDIM (ra
), ve
[k
],
817 SCM_OUTOFRANGE
, FUNC_NAME
);
822 res
= scm_make_ra (ndim
);
823 SCM_ARRAY_V (res
) = SCM_ARRAY_V (ra
);
824 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra
);
827 SCM_ARRAY_DIMS (res
)[k
].lbnd
= 0;
828 SCM_ARRAY_DIMS (res
)[k
].ubnd
= -1;
830 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
832 i
= SCM_INUM (ve
[k
]);
833 s
= &(SCM_ARRAY_DIMS (ra
)[k
]);
834 r
= &(SCM_ARRAY_DIMS (res
)[i
]);
835 if (r
->ubnd
< r
->lbnd
)
844 if (r
->ubnd
> s
->ubnd
)
846 if (r
->lbnd
< s
->lbnd
)
848 SCM_ARRAY_BASE (res
) += (s
->lbnd
- r
->lbnd
) * r
->inc
;
854 SCM_ASSERT (ndim
<= 0, args
, "bad argument list", FUNC_NAME
);
855 scm_ra_set_contp (res
);
861 /* args are RA . AXES */
862 GUILE_PROC(scm_enclose_array
, "enclose-array", 0, 0, 1,
864 "@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than
865 the rank of @var{array}. @var{enclose-array} returns an array
866 resembling an array of shared arrays. The dimensions of each shared
867 array are the same as the @var{dim}th dimensions of the original array,
868 the dimensions of the outer array are the same as those of the original
869 array that did not match a @var{dim}.
871 An enclosed array is not a general Scheme array. Its elements may not
872 be set using @code{array-set!}. Two references to the same element of
873 an enclosed array will be @code{equal?} but will not in general be
874 @code{eq?}. The value returned by @var{array-prototype} when given an
875 enclosed array is unspecified.
879 (enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) @result{}
880 #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>
882 (enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{}
883 #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>
885 #define FUNC_NAME s_scm_enclose_array
887 SCM axv
, ra
, res
, ra_inr
;
888 scm_array_dim vdim
, *s
= &vdim
;
889 int ndim
, j
, k
, ninr
, noutr
;
890 SCM_ASSERT (SCM_NIMP (axes
), scm_makfrom0str (FUNC_NAME
), SCM_WNA
,
893 axes
= SCM_CDR (axes
);
894 if (SCM_NULLP (axes
))
895 axes
= scm_cons ((SCM_ARRAYP (ra
) ? SCM_MAKINUM (SCM_ARRAY_NDIM (ra
) - 1) : SCM_INUM0
), SCM_EOL
);
896 ninr
= scm_ilength (axes
);
897 ra_inr
= scm_make_ra (ninr
);
898 SCM_ASRTGO (SCM_NIMP (ra
), badarg1
);
903 badarg1
:SCM_WTA (1,ra
);
915 #ifdef HAVE_LONG_LONGS
919 s
->ubnd
= SCM_LENGTH (ra
) - 1;
921 SCM_ARRAY_V (ra_inr
) = ra
;
922 SCM_ARRAY_BASE (ra_inr
) = 0;
926 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg1
);
927 s
= SCM_ARRAY_DIMS (ra
);
928 SCM_ARRAY_V (ra_inr
) = SCM_ARRAY_V (ra
);
929 SCM_ARRAY_BASE (ra_inr
) = SCM_ARRAY_BASE (ra
);
930 ndim
= SCM_ARRAY_NDIM (ra
);
934 axv
= scm_make_string (SCM_MAKINUM (ndim
), SCM_MAKICHR (0));
935 SCM_ASSERT (0 <= noutr
&& 0 <= ninr
, scm_makfrom0str (FUNC_NAME
),
937 res
= scm_make_ra (noutr
);
938 SCM_ARRAY_BASE (res
) = SCM_ARRAY_BASE (ra_inr
);
939 SCM_ARRAY_V (res
) = ra_inr
;
940 for (k
= 0; k
< ninr
; k
++, axes
= SCM_CDR (axes
))
942 SCM_ASSERT (SCM_INUMP (SCM_CAR (axes
)), SCM_CAR (axes
), "bad axis", FUNC_NAME
);
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_CHARS (axv
)[j
] = 1;
949 for (j
= 0, k
= 0; k
< noutr
; k
++, j
++)
951 while (SCM_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 GUILE_PROC(scm_array_in_bounds_p
, "array-in-bounds?", 0, 0, 1,
967 "Returns @code{#t} if its arguments would be acceptable to array-ref.")
968 #define FUNC_NAME s_scm_array_in_bounds_p
970 SCM v
, ind
= SCM_EOL
;
972 register scm_sizet k
;
975 SCM_ASSERT (SCM_NIMP (args
), scm_makfrom0str (FUNC_NAME
),
978 args
= SCM_CDR (args
);
979 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
983 ind
= SCM_CAR (args
);
984 args
= SCM_CDR (args
);
985 SCM_ASSERT (SCM_INUMP (ind
), ind
, SCM_ARG2
, FUNC_NAME
);
986 pos
= SCM_INUM (ind
);
993 badarg1
:SCM_WTA (1,v
);
994 wna
: scm_wrong_num_args (scm_makfrom0str (FUNC_NAME
));
996 k
= SCM_ARRAY_NDIM (v
);
997 s
= SCM_ARRAY_DIMS (v
);
998 pos
= SCM_ARRAY_BASE (v
);
1001 SCM_ASRTGO (SCM_NULLP (ind
), wna
);
1008 if (!(j
>= (s
->lbnd
) && j
<= (s
->ubnd
)))
1010 SCM_ASRTGO (--k
== scm_ilength (args
), wna
);
1013 pos
+= (j
- s
->lbnd
) * (s
->inc
);
1014 if (!(--k
&& SCM_NIMP (args
)))
1016 ind
= SCM_CAR (args
);
1017 args
= SCM_CDR (args
);
1019 SCM_ASSERT (SCM_INUMP (ind
), ind
, s_bad_ind
, FUNC_NAME
);
1021 SCM_ASRTGO (0 == k
, wna
);
1022 v
= SCM_ARRAY_V (v
);
1025 case scm_tc7_string
:
1026 case scm_tc7_byvect
:
1033 #ifdef HAVE_LONG_LONGS
1034 case scm_tc7_llvect
:
1036 case scm_tc7_vector
:
1038 SCM_ASRTGO (SCM_NULLP (args
) && SCM_INUMP (ind
), wna
);
1039 return SCM_BOOL(pos
>= 0 && pos
< SCM_LENGTH (v
));
1045 SCM_REGISTER_PROC(s_array_ref
, "array-ref", 1, 0, 1, scm_uniform_vector_ref
);
1048 GUILE_PROC(scm_uniform_vector_ref
, "uniform-vector-ref", 2, 0, 0,
1050 "Returns the element at the @code{(index1, index2)} element in @var{array}.")
1051 #define FUNC_NAME s_scm_uniform_vector_ref
1057 SCM_ASRTGO (SCM_NULLP (args
), badarg
);
1060 else if (SCM_ARRAYP (v
))
1062 pos
= scm_aind (v
, args
, FUNC_NAME
);
1063 v
= SCM_ARRAY_V (v
);
1067 if (SCM_NIMP (args
))
1070 SCM_ASSERT (SCM_CONSP (args
) && SCM_INUMP (SCM_CAR (args
)), args
, SCM_ARG2
, FUNC_NAME
);
1071 pos
= SCM_INUM (SCM_CAR (args
));
1072 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1076 SCM_VALIDATE_INT(2,args
);
1077 pos
= SCM_INUM (args
);
1079 SCM_ASRTGO (pos
>= 0 && pos
< SCM_LENGTH (v
), outrng
);
1085 if (SCM_NULLP (args
))
1090 outrng
:scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (pos
));
1091 wna
: scm_wrong_num_args (SCM_FUNC_NAME
);
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_VELTS (v
)[pos
/ SCM_LONG_BIT
] & (1L << (pos
% SCM_LONG_BIT
)))
1111 case scm_tc7_string
:
1112 return SCM_MAKICHR (SCM_UCHARS (v
)[pos
]);
1113 case scm_tc7_byvect
:
1114 return SCM_MAKINUM (((char *)SCM_CHARS (v
))[pos
]);
1115 # ifdef SCM_INUMS_ONLY
1118 return SCM_MAKINUM (SCM_VELTS (v
)[pos
]);
1121 return scm_ulong2num(SCM_VELTS(v
)[pos
]);
1123 return scm_long2num(SCM_VELTS(v
)[pos
]);
1127 return SCM_MAKINUM (((short *) SCM_CDR (v
))[pos
]);
1128 #ifdef HAVE_LONG_LONGS
1129 case scm_tc7_llvect
:
1130 return scm_long_long2num (((long_long
*) SCM_CDR (v
))[pos
]);
1136 return scm_makflo (((float *) SCM_CDR (v
))[pos
]);
1139 return scm_makdbl (((double *) SCM_CDR (v
))[pos
], 0.0);
1141 return scm_makdbl (((double *) SCM_CDR (v
))[2 * pos
],
1142 ((double *) SCM_CDR (v
))[2 * pos
+ 1]);
1144 case scm_tc7_vector
:
1146 return SCM_VELTS (v
)[pos
];
1151 /* Internal version of scm_uniform_vector_ref for uves that does no error checking and
1152 tries to recycle conses. (Make *sure* you want them recycled.) */
1155 scm_cvref (SCM v
, scm_sizet pos
, SCM last
)
1160 scm_wta (v
, (char *) SCM_ARG1
, "PROGRAMMING ERROR: scm_cvref");
1162 if (SCM_VELTS (v
)[pos
/ SCM_LONG_BIT
] & (1L << (pos
% SCM_LONG_BIT
)))
1166 case scm_tc7_string
:
1167 return SCM_MAKICHR (SCM_UCHARS (v
)[pos
]);
1168 case scm_tc7_byvect
:
1169 return SCM_MAKINUM (((char *)SCM_CHARS (v
))[pos
]);
1170 # ifdef SCM_INUMS_ONLY
1173 return SCM_MAKINUM (SCM_VELTS (v
)[pos
]);
1176 return scm_ulong2num(SCM_VELTS(v
)[pos
]);
1178 return scm_long2num(SCM_VELTS(v
)[pos
]);
1181 return SCM_MAKINUM (((short *) SCM_CDR (v
))[pos
]);
1182 #ifdef HAVE_LONG_LONGS
1183 case scm_tc7_llvect
:
1184 return scm_long_long2num (((long_long
*) SCM_CDR (v
))[pos
]);
1189 if (SCM_NIMP (last
) && (last
!= scm_flo0
) && (scm_tc_flo
== SCM_CAR (last
)))
1191 SCM_FLO (last
) = ((float *) SCM_CDR (v
))[pos
];
1194 return scm_makflo (((float *) SCM_CDR (v
))[pos
]);
1198 if (SCM_NIMP (last
) && scm_tc_dblr
== SCM_CAR (last
))
1200 if (SCM_NIMP (last
) && (last
!= scm_flo0
) && (scm_tc_dblr
== SCM_CAR (last
)))
1203 SCM_REAL (last
) = ((double *) SCM_CDR (v
))[pos
];
1206 return scm_makdbl (((double *) SCM_CDR (v
))[pos
], 0.0);
1208 if (SCM_NIMP (last
) && scm_tc_dblc
== SCM_CAR (last
))
1210 SCM_REAL (last
) = ((double *) SCM_CDR (v
))[2 * pos
];
1211 SCM_IMAG (last
) = ((double *) SCM_CDR (v
))[2 * pos
+ 1];
1214 return scm_makdbl (((double *) SCM_CDR (v
))[2 * pos
],
1215 ((double *) SCM_CDR (v
))[2 * pos
+ 1]);
1217 case scm_tc7_vector
:
1219 return SCM_VELTS (v
)[pos
];
1221 { /* enclosed scm_array */
1222 int k
= SCM_ARRAY_NDIM (v
);
1223 SCM res
= scm_make_ra (k
);
1224 SCM_ARRAY_V (res
) = SCM_ARRAY_V (v
);
1225 SCM_ARRAY_BASE (res
) = pos
;
1228 SCM_ARRAY_DIMS (res
)[k
].ubnd
= SCM_ARRAY_DIMS (v
)[k
].ubnd
;
1229 SCM_ARRAY_DIMS (res
)[k
].lbnd
= SCM_ARRAY_DIMS (v
)[k
].lbnd
;
1230 SCM_ARRAY_DIMS (res
)[k
].inc
= SCM_ARRAY_DIMS (v
)[k
].inc
;
1237 SCM_REGISTER_PROC(s_uniform_array_set1_x
, "uniform-array-set1!", 3, 0, 0, scm_array_set_x
);
1240 /* Note that args may be a list or an immediate object, depending which
1241 PROC is used (and it's called from C too). */
1242 GUILE_PROC(scm_array_set_x
, "array-set!", 2, 0, 1,
1243 (SCM v
, SCM obj
, SCM args
),
1244 "Sets the element at the @code{(index1, index2)} element in @var{array} to
1245 @var{new-value}. The value returned by array-set! is unspecified.")
1246 #define FUNC_NAME s_scm_array_set_x
1249 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1252 pos
= scm_aind (v
, args
, FUNC_NAME
);
1253 v
= SCM_ARRAY_V (v
);
1257 if (SCM_NIMP (args
))
1259 SCM_ASSERT (SCM_CONSP(args
) && SCM_INUMP (SCM_CAR (args
)), args
,
1260 SCM_ARG3
, FUNC_NAME
);
1261 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args
)), wna
);
1262 pos
= SCM_INUM (SCM_CAR (args
));
1266 SCM_VALIDATE_INT_COPY(3,args
,pos
);
1268 SCM_ASRTGO (pos
>= 0 && pos
< SCM_LENGTH (v
), outrng
);
1270 switch (SCM_TYP7 (v
))
1275 outrng
:scm_out_of_range (FUNC_NAME
, SCM_MAKINUM (pos
));
1276 wna
: scm_wrong_num_args (SCM_FUNC_NAME
);
1277 case scm_tc7_smob
: /* enclosed */
1280 if (SCM_BOOL_F
== obj
)
1281 SCM_VELTS (v
)[pos
/ SCM_LONG_BIT
] &= ~(1L << (pos
% SCM_LONG_BIT
));
1282 else if (SCM_BOOL_T
== obj
)
1283 SCM_VELTS (v
)[pos
/ SCM_LONG_BIT
] |= (1L << (pos
% SCM_LONG_BIT
));
1285 badobj
:SCM_WTA (2,obj
);
1287 case scm_tc7_string
:
1288 SCM_ASRTGO (SCM_ICHRP (obj
), badobj
);
1289 SCM_UCHARS (v
)[pos
] = SCM_ICHR (obj
);
1291 case scm_tc7_byvect
:
1292 if (SCM_ICHRP (obj
))
1293 obj
= SCM_MAKINUM ((char) SCM_ICHR (obj
));
1294 SCM_ASRTGO (SCM_INUMP (obj
), badobj
);
1295 ((char *)SCM_CHARS (v
))[pos
] = SCM_INUM (obj
);
1297 # ifdef SCM_INUMS_ONLY
1299 SCM_ASRTGO (SCM_INUM (obj
) >= 0, badobj
);
1302 SCM_ASRTGO(SCM_INUMP(obj
), badobj
); SCM_VELTS(v
)[pos
] = SCM_INUM(obj
); break;
1305 SCM_VELTS(v
)[pos
] = scm_num2ulong(obj
, (char *)SCM_ARG2
, FUNC_NAME
); break;
1307 SCM_VELTS(v
)[pos
] = scm_num2long(obj
, (char *)SCM_ARG2
, FUNC_NAME
); break;
1310 SCM_ASRTGO (SCM_INUMP (obj
), badobj
);
1311 ((short *) SCM_CDR (v
))[pos
] = SCM_INUM (obj
);
1313 #ifdef HAVE_LONG_LONGS
1314 case scm_tc7_llvect
:
1315 ((long_long
*) SCM_CDR (v
))[pos
] = scm_num2long_long (obj
, (char *)SCM_ARG2
, FUNC_NAME
);
1323 ((float *) SCM_CDR (v
))[pos
] = (float)scm_num2dbl(obj
, FUNC_NAME
); break;
1327 ((double *) SCM_CDR (v
))[pos
] = scm_num2dbl(obj
, FUNC_NAME
); break;
1330 SCM_ASRTGO (SCM_INEXP (obj
), badobj
);
1331 ((double *) SCM_CDR (v
))[2 * pos
] = SCM_REALPART (obj
);
1332 ((double *) SCM_CDR (v
))[2 * pos
+ 1] = SCM_CPLXP (obj
) ? SCM_IMAG (obj
) : 0.0;
1335 case scm_tc7_vector
:
1337 SCM_VELTS (v
)[pos
] = obj
;
1340 return SCM_UNSPECIFIED
;
1344 /* attempts to unroll an array into a one-dimensional array.
1345 returns the unrolled array or #f if it can't be done. */
1346 /* if strict is not SCM_UNDEFINED, return #f if returned array
1347 wouldn't have contiguous elements. */
1348 GUILE_PROC(scm_array_contents
, "array-contents", 1, 1, 0,
1349 (SCM ra
, SCM strict
),
1350 "@deffnx primitive array-contents array strict
1351 If @var{array} may be @dfn{unrolled} into a one dimensional shared array
1352 without changing their order (last subscript changing fastest), then
1353 @code{array-contents} returns that shared array, otherwise it returns
1354 @code{#f}. All arrays made by @var{make-array} and
1355 @var{make-uniform-array} may be unrolled, some arrays made by
1356 @var{make-shared-array} may not be.
1358 If the optional argument @var{strict} is provided, a shared array will
1359 be returned only if its elements are stored internally contiguous in
1361 #define FUNC_NAME s_scm_array_contents
1366 switch SCM_TYP7 (ra
)
1370 case scm_tc7_vector
:
1372 case scm_tc7_string
:
1374 case scm_tc7_byvect
:
1381 #ifdef HAVE_LONG_LONGS
1382 case scm_tc7_llvect
:
1387 scm_sizet k
, ndim
= SCM_ARRAY_NDIM (ra
), len
= 1;
1388 if (!SCM_ARRAYP (ra
) || !SCM_ARRAY_CONTP (ra
))
1390 for (k
= 0; k
< ndim
; k
++)
1391 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1392 if (!SCM_UNBNDP (strict
))
1394 if (ndim
&& (1 != SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
))
1396 if (scm_tc7_bvect
== SCM_TYP7 (SCM_ARRAY_V (ra
)))
1398 if (len
!= SCM_LENGTH (SCM_ARRAY_V (ra
)) ||
1399 SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
||
1404 if ((len
== SCM_LENGTH (SCM_ARRAY_V (ra
))) && 0 == SCM_ARRAY_BASE (ra
) && SCM_ARRAY_DIMS (ra
)->inc
)
1405 return SCM_ARRAY_V (ra
);
1406 sra
= scm_make_ra (1);
1407 SCM_ARRAY_DIMS (sra
)->lbnd
= 0;
1408 SCM_ARRAY_DIMS (sra
)->ubnd
= len
- 1;
1409 SCM_ARRAY_V (sra
) = SCM_ARRAY_V (ra
);
1410 SCM_ARRAY_BASE (sra
) = SCM_ARRAY_BASE (ra
);
1411 SCM_ARRAY_DIMS (sra
)->inc
= (ndim
? SCM_ARRAY_DIMS (ra
)[ndim
- 1].inc
: 1);
1420 scm_ra2contig (SCM ra
, int copy
)
1424 scm_sizet k
, len
= 1;
1425 for (k
= SCM_ARRAY_NDIM (ra
); k
--;)
1426 len
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1427 k
= SCM_ARRAY_NDIM (ra
);
1428 if (SCM_ARRAY_CONTP (ra
) && ((0 == k
) || (1 == SCM_ARRAY_DIMS (ra
)[k
- 1].inc
)))
1430 if (scm_tc7_bvect
!= SCM_TYP7 (ra
))
1432 if ((len
== SCM_LENGTH (SCM_ARRAY_V (ra
)) &&
1433 0 == SCM_ARRAY_BASE (ra
) % SCM_LONG_BIT
&&
1434 0 == len
% SCM_LONG_BIT
))
1437 ret
= scm_make_ra (k
);
1438 SCM_ARRAY_BASE (ret
) = 0;
1441 SCM_ARRAY_DIMS (ret
)[k
].lbnd
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
;
1442 SCM_ARRAY_DIMS (ret
)[k
].ubnd
= SCM_ARRAY_DIMS (ra
)[k
].ubnd
;
1443 SCM_ARRAY_DIMS (ret
)[k
].inc
= inc
;
1444 inc
*= SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1;
1446 SCM_ARRAY_V (ret
) = scm_make_uve ((inc
- 1), scm_array_prototype (ra
));
1448 scm_array_copy_x (ra
, ret
);
1454 GUILE_PROC(scm_uniform_array_read_x
, "uniform-array-read!", 1, 3, 0,
1455 (SCM ra
, SCM port_or_fd
, SCM start
, SCM end
),
1456 "@deffnx primitive uniform-vector-read! uve [port-or-fdes] [start] [end]
1457 Attempts to read all elements of @var{ura}, in lexicographic order, as
1458 binary objects from @var{port-or-fdes}.
1459 If an end of file is encountered during
1460 uniform-array-read! the objects up to that point only are put into @var{ura}
1461 (starting at the beginning) and the remainder of the array is
1464 The optional arguments @var{start} and @var{end} allow
1465 a specified region of a vector (or linearized array) to be read,
1466 leaving the remainder of the vector unchanged.
1468 @code{uniform-array-read!} returns the number of objects read.
1469 @var{port-or-fdes} may be omitted, in which case it defaults to the value
1470 returned by @code{(current-input-port)}.")
1471 #define FUNC_NAME s_scm_uniform_array_read_x
1473 SCM cra
= SCM_UNDEFINED
, v
= ra
;
1479 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1480 if (SCM_UNBNDP (port_or_fd
))
1481 port_or_fd
= scm_cur_inp
;
1483 SCM_ASSERT (SCM_INUMP (port_or_fd
)
1484 || (SCM_OPINPORTP (port_or_fd
)),
1485 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1486 vlen
= SCM_LENGTH (v
);
1492 badarg1
:scm_wta (v
, (char *) SCM_ARG1
, FUNC_NAME
);
1494 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1495 cra
= scm_ra2contig (ra
, 0);
1496 cstart
+= SCM_ARRAY_BASE (cra
);
1497 vlen
= SCM_ARRAY_DIMS (cra
)->inc
*
1498 (SCM_ARRAY_DIMS (cra
)->ubnd
- SCM_ARRAY_DIMS (cra
)->lbnd
+ 1);
1499 v
= SCM_ARRAY_V (cra
);
1501 case scm_tc7_string
:
1502 case scm_tc7_byvect
:
1506 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1507 cstart
/= SCM_LONG_BIT
;
1513 sz
= sizeof (short);
1515 #ifdef HAVE_LONG_LONGS
1516 case scm_tc7_llvect
:
1517 sz
= sizeof (long_long
);
1523 sz
= sizeof (float);
1527 sz
= sizeof (double);
1530 sz
= 2 * sizeof (double);
1536 if (!SCM_UNBNDP (start
))
1539 scm_num2long (start
, (char *) SCM_ARG3
, FUNC_NAME
);
1541 if (offset
< 0 || offset
>= cend
)
1542 scm_out_of_range (FUNC_NAME
, start
);
1544 if (!SCM_UNBNDP (end
))
1547 scm_num2long (end
, (char *) SCM_ARG4
, FUNC_NAME
);
1549 if (tend
<= offset
|| tend
> cend
)
1550 scm_out_of_range (FUNC_NAME
, end
);
1555 if (SCM_NIMP (port_or_fd
))
1557 scm_port
*pt
= SCM_PTAB_ENTRY (port_or_fd
);
1558 int remaining
= (cend
- offset
) * sz
;
1559 char *dest
= SCM_CHARS (v
) + (cstart
+ offset
) * sz
;
1561 if (pt
->rw_active
== SCM_PORT_WRITE
)
1562 scm_flush (port_or_fd
);
1564 ans
= cend
- offset
;
1565 while (remaining
> 0)
1567 if (pt
->read_pos
< pt
->read_end
)
1569 int to_copy
= min (pt
->read_end
- pt
->read_pos
,
1572 memcpy (dest
, pt
->read_pos
, to_copy
);
1573 pt
->read_pos
+= to_copy
;
1574 remaining
-= to_copy
;
1579 if (scm_fill_input (port_or_fd
) == EOF
)
1581 if (remaining
% sz
!= 0)
1583 scm_misc_error (FUNC_NAME
,
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 SCM_CHARS (v
) + (cstart
+ offset
) * sz
,
1600 (scm_sizet
) (sz
* (cend
- offset
))));
1604 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1605 ans
*= SCM_LONG_BIT
;
1607 if (v
!= ra
&& cra
!= ra
)
1608 scm_array_copy_x (cra
, ra
);
1610 return SCM_MAKINUM (ans
);
1614 GUILE_PROC(scm_uniform_array_write
, "uniform-array-write", 1, 3, 0,
1615 (SCM v
, SCM port_or_fd
, SCM start
, SCM end
),
1616 "@deffnx primitive uniform-vector-write uve [port-or-fdes] [start] [end]
1617 Writes all elements of @var{ura} as binary objects to
1620 The optional arguments @var{start}
1622 a specified region of a vector (or linearized array) to be written.
1624 The number of objects actually written is returned.
1625 @var{port-or-fdes} may be
1626 omitted, in which case it defaults to the value returned by
1627 @code{(current-output-port)}.")
1628 #define FUNC_NAME s_scm_uniform_array_write
1635 port_or_fd
= SCM_COERCE_OUTPORT (port_or_fd
);
1637 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1638 if (SCM_UNBNDP (port_or_fd
))
1639 port_or_fd
= scm_cur_outp
;
1641 SCM_ASSERT (SCM_INUMP (port_or_fd
)
1642 || (SCM_OPOUTPORTP (port_or_fd
)),
1643 port_or_fd
, SCM_ARG2
, FUNC_NAME
);
1644 vlen
= SCM_LENGTH (v
);
1650 badarg1
:scm_wta (v
, (char *) SCM_ARG1
, FUNC_NAME
);
1652 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
1653 v
= scm_ra2contig (v
, 1);
1654 cstart
= SCM_ARRAY_BASE (v
);
1655 vlen
= SCM_ARRAY_DIMS (v
)->inc
1656 * (SCM_ARRAY_DIMS (v
)->ubnd
- SCM_ARRAY_DIMS (v
)->lbnd
+ 1);
1657 v
= SCM_ARRAY_V (v
);
1659 case scm_tc7_string
:
1660 case scm_tc7_byvect
:
1664 vlen
= (vlen
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
;
1665 cstart
/= SCM_LONG_BIT
;
1671 sz
= sizeof (short);
1673 #ifdef HAVE_LONG_LONGS
1674 case scm_tc7_llvect
:
1675 sz
= sizeof (long_long
);
1681 sz
= sizeof (float);
1685 sz
= sizeof (double);
1688 sz
= 2 * sizeof (double);
1694 if (!SCM_UNBNDP (start
))
1697 scm_num2long (start
, (char *) SCM_ARG3
, FUNC_NAME
);
1699 if (offset
< 0 || offset
>= cend
)
1700 scm_out_of_range (FUNC_NAME
, start
);
1702 if (!SCM_UNBNDP (end
))
1705 scm_num2long (end
, (char *) SCM_ARG4
, FUNC_NAME
);
1707 if (tend
<= offset
|| tend
> cend
)
1708 scm_out_of_range (FUNC_NAME
, end
);
1713 if (SCM_NIMP (port_or_fd
))
1715 char *source
= SCM_CHARS (v
) + (cstart
+ offset
) * sz
;
1717 ans
= cend
- offset
;
1718 scm_lfwrite (source
, ans
* sz
, port_or_fd
);
1720 else /* file descriptor. */
1722 SCM_SYSCALL (ans
= write (SCM_INUM (port_or_fd
),
1723 SCM_CHARS (v
) + (cstart
+ offset
) * sz
,
1724 (scm_sizet
) (sz
* (cend
- offset
))));
1728 if (SCM_TYP7 (v
) == scm_tc7_bvect
)
1729 ans
*= SCM_LONG_BIT
;
1731 return SCM_MAKINUM (ans
);
1736 static char cnt_tab
[16] =
1737 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1739 GUILE_PROC(scm_bit_count
, "bit-count", 2, 0, 0,
1740 (SCM item
, SCM seq
),
1741 "Returns the number occurrences of @var{bool} in @var{bv}.")
1742 #define FUNC_NAME s_scm_bit_count
1745 register unsigned long cnt
= 0, w
;
1746 SCM_VALIDATE_INT(2,seq
);
1747 switch SCM_TYP7 (seq
)
1752 if (0 == SCM_LENGTH (seq
))
1754 i
= (SCM_LENGTH (seq
) - 1) / SCM_LONG_BIT
;
1755 w
= SCM_VELTS (seq
)[i
];
1756 if (SCM_FALSEP (item
))
1758 w
<<= SCM_LONG_BIT
- 1 - ((SCM_LENGTH (seq
) - 1) % SCM_LONG_BIT
);
1762 cnt
+= cnt_tab
[w
& 0x0f];
1764 return SCM_MAKINUM (cnt
);
1765 w
= SCM_VELTS (seq
)[i
];
1766 if (SCM_FALSEP (item
))
1774 GUILE_PROC(scm_bit_position
, "bit-position", 3, 0, 0,
1775 (SCM item
, SCM v
, SCM k
),
1776 "Returns the minimum index of an occurrence of @var{bool} in @var{bv}
1777 which is at least @var{k}. If no @var{bool} occurs within the specified
1778 range @code{#f} is returned.")
1779 #define FUNC_NAME s_scm_bit_position
1781 long i
, lenw
, xbits
, pos
;
1782 register unsigned long w
;
1783 SCM_VALIDATE_NIM (2,v
);
1784 SCM_VALIDATE_INT_COPY(3,k
,pos
);
1785 SCM_ASSERT ((pos
<= SCM_LENGTH (v
)) && (pos
>= 0),
1786 k
, SCM_OUTOFRANGE
, FUNC_NAME
);
1787 if (pos
== SCM_LENGTH (v
))
1794 if (0 == SCM_LENGTH (v
))
1795 return SCM_MAKINUM (-1L);
1796 lenw
= (SCM_LENGTH (v
) - 1) / SCM_LONG_BIT
; /* watch for part words */
1797 i
= pos
/ SCM_LONG_BIT
;
1798 w
= SCM_VELTS (v
)[i
];
1799 if (SCM_FALSEP (item
))
1801 xbits
= (pos
% SCM_LONG_BIT
);
1803 w
= ((w
>> xbits
) << xbits
);
1804 xbits
= SCM_LONG_BIT
- 1 - (SCM_LENGTH (v
) - 1) % SCM_LONG_BIT
;
1807 if (w
&& (i
== lenw
))
1808 w
= ((w
<< xbits
) >> xbits
);
1814 return SCM_MAKINUM (pos
);
1819 return SCM_MAKINUM (pos
+ 1);
1822 return SCM_MAKINUM (pos
+ 2);
1824 return SCM_MAKINUM (pos
+ 3);
1831 pos
+= SCM_LONG_BIT
;
1832 w
= SCM_VELTS (v
)[i
];
1833 if (SCM_FALSEP (item
))
1842 GUILE_PROC(scm_bit_set_star_x
, "bit-set*!", 3, 0, 0,
1843 (SCM v
, SCM kv
, SCM obj
),
1844 "If uve is a bit-vector @var{bv} and uve must be of the same length. If
1845 @var{bool} is @code{#t}, uve is OR'ed into @var{bv}; If @var{bool} is @code{#f}, the
1846 inversion of uve is AND'ed into @var{bv}.
1848 If uve is a unsigned integer vector all the elements of uve must be
1849 between 0 and the @code{LENGTH} of @var{bv}. The bits of @var{bv}
1850 corresponding to the indexes in uve are set to @var{bool}.
1852 The return value is unspecified.")
1853 #define FUNC_NAME s_scm_bit_set_star_x
1855 register long i
, k
, vlen
;
1856 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1857 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1858 switch SCM_TYP7 (kv
)
1861 badarg2
:SCM_WTA (2,kv
);
1866 badarg1
:SCM_WTA (1,v
);
1868 vlen
= SCM_LENGTH (v
);
1869 if (SCM_BOOL_F
== obj
)
1870 for (i
= SCM_LENGTH (kv
); i
;)
1872 k
= SCM_VELTS (kv
)[--i
];
1873 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1874 SCM_VELTS (v
)[k
/ SCM_LONG_BIT
] &= ~(1L << (k
% SCM_LONG_BIT
));
1876 else if (SCM_BOOL_T
== obj
)
1877 for (i
= SCM_LENGTH (kv
); i
;)
1879 k
= SCM_VELTS (kv
)[--i
];
1880 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1881 SCM_VELTS (v
)[k
/ SCM_LONG_BIT
] |= (1L << (k
% SCM_LONG_BIT
));
1884 badarg3
:SCM_WTA (3,obj
);
1888 SCM_ASRTGO (SCM_TYP7 (v
) == scm_tc7_bvect
&& SCM_LENGTH (v
) == SCM_LENGTH (kv
), badarg1
);
1889 if (SCM_BOOL_F
== obj
)
1890 for (k
= (SCM_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1891 SCM_VELTS (v
)[k
] &= ~(SCM_VELTS (kv
)[k
]);
1892 else if (SCM_BOOL_T
== obj
)
1893 for (k
= (SCM_LENGTH (v
) + SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1894 SCM_VELTS (v
)[k
] |= SCM_VELTS (kv
)[k
];
1899 return SCM_UNSPECIFIED
;
1904 GUILE_PROC(scm_bit_count_star
, "bit-count*", 3, 0, 0,
1905 (SCM v
, SCM kv
, SCM obj
),
1908 (bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t).
1910 @var{bv} is not modified.")
1911 #define FUNC_NAME s_scm_bit_count_star
1913 register long i
, vlen
, count
= 0;
1914 register unsigned long k
;
1915 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1916 SCM_ASRTGO (SCM_NIMP (kv
), badarg2
);
1917 switch SCM_TYP7 (kv
)
1920 badarg2
:SCM_WTA (2,kv
);
1926 badarg1
:SCM_WTA (1,v
);
1928 vlen
= SCM_LENGTH (v
);
1929 if (SCM_BOOL_F
== obj
)
1930 for (i
= SCM_LENGTH (kv
); i
;)
1932 k
= SCM_VELTS (kv
)[--i
];
1933 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1934 if (!(SCM_VELTS (v
)[k
/ SCM_LONG_BIT
] & (1L << (k
% SCM_LONG_BIT
))))
1937 else if (SCM_BOOL_T
== obj
)
1938 for (i
= SCM_LENGTH (kv
); i
;)
1940 k
= SCM_VELTS (kv
)[--i
];
1941 SCM_ASSERT ((k
< vlen
), SCM_MAKINUM (k
), SCM_OUTOFRANGE
, FUNC_NAME
);
1942 if (SCM_VELTS (v
)[k
/ SCM_LONG_BIT
] & (1L << (k
% SCM_LONG_BIT
)))
1946 badarg3
:SCM_WTA (3,obj
);
1950 SCM_ASRTGO (SCM_TYP7 (v
) == scm_tc7_bvect
&& SCM_LENGTH (v
) == SCM_LENGTH (kv
), badarg1
);
1951 if (0 == SCM_LENGTH (v
))
1953 SCM_ASRTGO (SCM_BOOL_T
== obj
|| SCM_BOOL_F
== obj
, badarg3
);
1954 obj
= (SCM_BOOL_T
== obj
);
1955 i
= (SCM_LENGTH (v
) - 1) / SCM_LONG_BIT
;
1956 k
= SCM_VELTS (kv
)[i
] & (obj
? SCM_VELTS (v
)[i
] : ~SCM_VELTS (v
)[i
]);
1957 k
<<= SCM_LONG_BIT
- 1 - ((SCM_LENGTH (v
) - 1) % SCM_LONG_BIT
);
1961 count
+= cnt_tab
[k
& 0x0f];
1963 return SCM_MAKINUM (count
);
1964 k
= SCM_VELTS (kv
)[i
] & (obj
? SCM_VELTS (v
)[i
] : ~SCM_VELTS (v
)[i
]);
1967 return SCM_MAKINUM (count
);
1972 GUILE_PROC(scm_bit_invert_x
, "bit-invert!", 1, 0, 0,
1974 "Modifies @var{bv} by replacing each element with its negation.")
1975 #define FUNC_NAME s_scm_bit_invert_x
1978 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
1984 for (k
= (k
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
--;)
1985 SCM_VELTS (v
)[k
] = ~SCM_VELTS (v
)[k
];
1988 badarg1
:SCM_WTA (1,v
);
1990 return SCM_UNSPECIFIED
;
1996 scm_istr2bve (char *str
, long len
)
1998 SCM v
= scm_make_uve (len
, SCM_BOOL_T
);
1999 long *data
= (long *) SCM_VELTS (v
);
2000 register unsigned long mask
;
2003 for (k
= 0; k
< (len
+ SCM_LONG_BIT
- 1) / SCM_LONG_BIT
; k
++)
2006 j
= len
- k
* SCM_LONG_BIT
;
2007 if (j
> SCM_LONG_BIT
)
2009 for (mask
= 1L; j
--; mask
<<= 1)
2027 ra2l (SCM ra
,scm_sizet base
,scm_sizet k
)
2029 register SCM res
= SCM_EOL
;
2030 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2031 register scm_sizet i
;
2032 if (SCM_ARRAY_DIMS (ra
)[k
].ubnd
< SCM_ARRAY_DIMS (ra
)[k
].lbnd
)
2034 i
= base
+ (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
) * inc
;
2035 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2040 res
= scm_cons (ra2l (ra
, i
, k
+ 1), res
);
2048 res
= scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra
), SCM_MAKINUM (i
)), res
);
2055 GUILE_PROC(scm_array_to_list
, "array->list", 1, 0, 0,
2057 "Returns a list consisting of all the elements, in order, of @var{array}.")
2058 #define FUNC_NAME s_scm_array_to_list
2062 SCM_ASRTGO (SCM_NIMP (v
), badarg1
);
2067 badarg1
:SCM_WTA (1,v
);
2069 SCM_ASRTGO (SCM_ARRAYP (v
), badarg1
);
2070 return ra2l (v
, SCM_ARRAY_BASE (v
), 0);
2071 case scm_tc7_vector
:
2073 return scm_vector_to_list (v
);
2074 case scm_tc7_string
:
2075 return scm_string_to_list (v
);
2078 long *data
= (long *) SCM_VELTS (v
);
2079 register unsigned long mask
;
2080 for (k
= (SCM_LENGTH (v
) - 1) / SCM_LONG_BIT
; k
> 0; k
--)
2081 for (mask
= 1UL << (SCM_LONG_BIT
- 1); mask
; mask
>>= 1)
2082 res
= scm_cons (SCM_BOOL(((long *) data
)[k
] & mask
), res
);
2083 for (mask
= 1L << ((SCM_LENGTH (v
) % SCM_LONG_BIT
) - 1); mask
; mask
>>= 1)
2084 res
= scm_cons (SCM_BOOL(((long *) data
)[k
] & mask
), res
);
2087 # ifdef SCM_INUMS_ONLY
2091 long *data
= (long *) SCM_VELTS (v
);
2092 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2093 res
= scm_cons (SCM_MAKINUM (data
[k
]), res
);
2097 case scm_tc7_uvect
: {
2098 long *data
= (long *)SCM_VELTS(v
);
2099 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2100 res
= scm_cons(scm_ulong2num(data
[k
]), res
);
2103 case scm_tc7_ivect
: {
2104 long *data
= (long *)SCM_VELTS(v
);
2105 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2106 res
= scm_cons(scm_long2num(data
[k
]), res
);
2110 case scm_tc7_svect
: {
2112 data
= (short *)SCM_VELTS(v
);
2113 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2114 res
= scm_cons(SCM_MAKINUM (data
[k
]), res
);
2117 #ifdef HAVE_LONG_LONGS
2118 case scm_tc7_llvect
: {
2120 data
= (long_long
*)SCM_VELTS(v
);
2121 for (k
= SCM_LENGTH(v
) - 1; k
>= 0; k
--)
2122 res
= scm_cons(scm_long_long2num(data
[k
]), res
);
2132 float *data
= (float *) SCM_VELTS (v
);
2133 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2134 res
= scm_cons (scm_makflo (data
[k
]), res
);
2137 #endif /*SCM_SINGLES*/
2140 double *data
= (double *) SCM_VELTS (v
);
2141 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2142 res
= scm_cons (scm_makdbl (data
[k
], 0.0), res
);
2147 double (*data
)[2] = (double (*)[2]) SCM_VELTS (v
);
2148 for (k
= SCM_LENGTH (v
) - 1; k
>= 0; k
--)
2149 res
= scm_cons (scm_makdbl (data
[k
][0], data
[k
][1]), res
);
2152 #endif /*SCM_FLOATS*/
2158 static char s_bad_ralst
[] = "Bad scm_array contents list";
2160 static int l2ra(SCM lst
, SCM ra
, scm_sizet base
, scm_sizet k
);
2162 GUILE_PROC(scm_list_to_uniform_array
, "list->uniform-array", 3, 0, 0,
2163 (SCM ndim
, SCM prot
, SCM lst
),
2164 "@deffnx procedure list->uniform-vector prot lst
2165 Returns a uniform array of the type indicated by prototype @var{prot}
2166 with elements the same as those of @var{lst}. Elements must be of the
2167 appropriate type, no coercions are done.")
2168 #define FUNC_NAME s_scm_list_to_uniform_array
2175 SCM_VALIDATE_INT_COPY(1,ndim
,k
);
2178 n
= scm_ilength (row
);
2179 SCM_ASSERT (n
>= 0, lst
, SCM_ARG3
, FUNC_NAME
);
2180 shp
= scm_cons (SCM_MAKINUM (n
), shp
);
2182 row
= SCM_CAR (row
);
2184 ra
= scm_dimensions_to_uniform_array (scm_reverse (shp
), prot
,
2186 if (SCM_NULLP (shp
))
2189 SCM_ASRTGO (1 == scm_ilength (lst
), badlst
);
2190 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_EOL
);
2193 if (!SCM_ARRAYP (ra
))
2195 for (k
= 0; k
< SCM_LENGTH (ra
); k
++, lst
= SCM_CDR (lst
))
2196 scm_array_set_x (ra
, SCM_CAR (lst
), SCM_MAKINUM (k
));
2199 if (l2ra (lst
, ra
, SCM_ARRAY_BASE (ra
), 0))
2202 badlst
:scm_wta (lst
, s_bad_ralst
, FUNC_NAME
);
2208 l2ra (SCM lst
, SCM ra
, scm_sizet base
, scm_sizet k
)
2210 register long inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2211 register long n
= (1 + SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
);
2214 return (SCM_EOL
== lst
);
2215 if (k
< SCM_ARRAY_NDIM (ra
) - 1)
2219 if (SCM_IMP (lst
) || SCM_NCONSP (lst
))
2221 ok
= ok
&& l2ra (SCM_CAR (lst
), ra
, base
, k
+ 1);
2223 lst
= SCM_CDR (lst
);
2225 if (SCM_NNULLP (lst
))
2232 if (SCM_IMP (lst
) || SCM_NCONSP (lst
))
2234 ok
= ok
&& scm_array_set_x (SCM_ARRAY_V (ra
), SCM_CAR (lst
), SCM_MAKINUM (base
));
2236 lst
= SCM_CDR (lst
);
2238 if (SCM_NNULLP (lst
))
2246 rapr1 (SCM ra
,scm_sizet j
,scm_sizet k
,SCM port
,scm_print_state
*pstate
)
2249 long n
= SCM_LENGTH (ra
);
2252 switch SCM_TYP7 (ra
)
2257 SCM_ARRAY_BASE (ra
) = j
;
2259 scm_iprin1 (ra
, port
, pstate
);
2260 for (j
+= inc
; n
-- > 0; j
+= inc
)
2262 scm_putc (' ', port
);
2263 SCM_ARRAY_BASE (ra
) = j
;
2264 scm_iprin1 (ra
, port
, pstate
);
2268 if (k
+ 1 < SCM_ARRAY_NDIM (ra
))
2271 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2272 for (i
= SCM_ARRAY_DIMS (ra
)[k
].lbnd
; i
< SCM_ARRAY_DIMS (ra
)[k
].ubnd
; i
++)
2274 scm_putc ('(', port
);
2275 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2276 scm_puts (") ", port
);
2279 if (i
== SCM_ARRAY_DIMS (ra
)[k
].ubnd
)
2280 { /* could be zero size. */
2281 scm_putc ('(', port
);
2282 rapr1 (ra
, j
, k
+ 1, port
, pstate
);
2283 scm_putc (')', port
);
2289 { /* Could be zero-dimensional */
2290 inc
= SCM_ARRAY_DIMS (ra
)[k
].inc
;
2291 n
= (SCM_ARRAY_DIMS (ra
)[k
].ubnd
- SCM_ARRAY_DIMS (ra
)[k
].lbnd
+ 1);
2295 ra
= SCM_ARRAY_V (ra
);
2298 /* scm_tc7_bvect and scm_tc7_llvect only? */
2300 scm_iprin1 (scm_uniform_vector_ref (ra
, SCM_MAKINUM (j
)), port
, pstate
);
2301 for (j
+= inc
; n
-- > 0; j
+= inc
)
2303 scm_putc (' ', port
);
2304 scm_iprin1 (scm_cvref (ra
, j
, SCM_UNDEFINED
), port
, pstate
);
2307 case scm_tc7_string
:
2309 scm_iprin1 (SCM_MAKICHR (SCM_UCHARS (ra
)[j
]), port
, pstate
);
2310 if (SCM_WRITINGP (pstate
))
2311 for (j
+= inc
; n
-- > 0; j
+= inc
)
2313 scm_putc (' ', port
);
2314 scm_iprin1 (SCM_MAKICHR (SCM_UCHARS (ra
)[j
]), port
, pstate
);
2317 for (j
+= inc
; n
-- > 0; j
+= inc
)
2318 scm_putc (SCM_CHARS (ra
)[j
], port
);
2320 case scm_tc7_byvect
:
2322 scm_intprint (((char *)SCM_CDR (ra
))[j
], 10, port
);
2323 for (j
+= inc
; n
-- > 0; j
+= inc
)
2325 scm_putc (' ', port
);
2326 scm_intprint (((char *)SCM_CDR (ra
))[j
], 10, port
);
2336 /* intprint can't handle >= 2^31. */
2337 sprintf (str
, "%lu", (unsigned long) SCM_VELTS (ra
)[j
]);
2338 scm_puts (str
, port
);
2340 for (j
+= inc
; n
-- > 0; j
+= inc
)
2342 scm_putc (' ', port
);
2343 sprintf (str
, "%lu", (unsigned long) SCM_VELTS (ra
)[j
]);
2344 scm_puts (str
, port
);
2349 scm_intprint (SCM_VELTS (ra
)[j
], 10, port
);
2350 for (j
+= inc
; n
-- > 0; j
+= inc
)
2352 scm_putc (' ', port
);
2353 scm_intprint (SCM_VELTS (ra
)[j
], 10, port
);
2359 scm_intprint (((short *)SCM_CDR (ra
))[j
], 10, port
);
2360 for (j
+= inc
; n
-- > 0; j
+= inc
)
2362 scm_putc (' ', port
);
2363 scm_intprint (((short *)SCM_CDR (ra
))[j
], 10, port
);
2372 SCM z
= scm_makflo (1.0);
2373 SCM_FLO (z
) = ((float *) SCM_VELTS (ra
))[j
];
2374 scm_floprint (z
, port
, pstate
);
2375 for (j
+= inc
; n
-- > 0; j
+= inc
)
2377 scm_putc (' ', port
);
2378 SCM_FLO (z
) = ((float *) SCM_VELTS (ra
))[j
];
2379 scm_floprint (z
, port
, pstate
);
2383 #endif /*SCM_SINGLES*/
2387 SCM z
= scm_makdbl (1.0 / 3.0, 0.0);
2388 SCM_REAL (z
) = ((double *) SCM_VELTS (ra
))[j
];
2389 scm_floprint (z
, port
, pstate
);
2390 for (j
+= inc
; n
-- > 0; j
+= inc
)
2392 scm_putc (' ', port
);
2393 SCM_REAL (z
) = ((double *) SCM_VELTS (ra
))[j
];
2394 scm_floprint (z
, port
, pstate
);
2401 SCM cz
= scm_makdbl (0.0, 1.0), z
= scm_makdbl (1.0 / 3.0, 0.0);
2402 SCM_REAL (z
) = SCM_REAL (cz
) = (((double *) SCM_VELTS (ra
))[2 * j
]);
2403 SCM_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2404 scm_floprint ((0.0 == SCM_IMAG (cz
) ? z
: cz
), port
, pstate
);
2405 for (j
+= inc
; n
-- > 0; j
+= inc
)
2407 scm_putc (' ', port
);
2408 SCM_REAL (z
) = SCM_REAL (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
];
2409 SCM_IMAG (cz
) = ((double *) SCM_VELTS (ra
))[2 * j
+ 1];
2410 scm_floprint ((0.0 == SCM_IMAG (cz
) ? z
: cz
), port
, pstate
);
2414 #endif /*SCM_FLOATS*/
2421 scm_raprin1 (SCM exp
, SCM port
, scm_print_state
*pstate
)
2425 scm_putc ('#', port
);
2431 long ndim
= SCM_ARRAY_NDIM (v
);
2432 base
= SCM_ARRAY_BASE (v
);
2433 v
= SCM_ARRAY_V (v
);
2437 scm_puts ("<enclosed-array ", port
);
2438 rapr1 (exp
, base
, 0, port
, pstate
);
2439 scm_putc ('>', port
);
2444 scm_intprint (ndim
, 10, port
);
2450 { /* a uve, not an scm_array */
2451 register long i
, j
, w
;
2452 scm_putc ('*', port
);
2453 for (i
= 0; i
< (SCM_LENGTH (exp
)) / SCM_LONG_BIT
; i
++)
2455 w
= SCM_VELTS (exp
)[i
];
2456 for (j
= SCM_LONG_BIT
; j
; j
--)
2458 scm_putc (w
& 1 ? '1' : '0', port
);
2462 j
= SCM_LENGTH (exp
) % SCM_LONG_BIT
;
2465 w
= SCM_VELTS (exp
)[SCM_LENGTH (exp
) / SCM_LONG_BIT
];
2468 scm_putc (w
& 1 ? '1' : '0', port
);
2475 scm_putc ('b', port
);
2477 case scm_tc7_string
:
2478 scm_putc ('a', port
);
2480 case scm_tc7_byvect
:
2481 scm_putc ('y', port
);
2484 scm_putc ('u', port
);
2487 scm_putc ('e', port
);
2490 scm_putc ('h', port
);
2492 #ifdef HAVE_LONG_LONGS
2493 case scm_tc7_llvect
:
2494 scm_putc ('l', port
);
2500 scm_putc ('s', port
);
2502 #endif /*SCM_SINGLES*/
2504 scm_putc ('i', port
);
2507 scm_putc ('c', port
);
2509 #endif /*SCM_FLOATS*/
2511 scm_putc ('(', port
);
2512 rapr1 (exp
, base
, 0, port
, pstate
);
2513 scm_putc (')', port
);
2517 GUILE_PROC(scm_array_prototype
, "array-prototype", 1, 0, 0,
2519 "Returns an object that would produce an array of the same type as
2520 @var{array}, if used as the @var{prototype} for
2521 @code{make-uniform-array}.")
2522 #define FUNC_NAME s_scm_array_prototype
2525 SCM_ASRTGO (SCM_NIMP (ra
), badarg
);
2531 badarg
:SCM_WTA (1,ra
);
2533 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
2535 return SCM_UNSPECIFIED
;
2536 ra
= SCM_ARRAY_V (ra
);
2538 case scm_tc7_vector
:
2543 case scm_tc7_string
:
2544 return SCM_MAKICHR ('a');
2545 case scm_tc7_byvect
:
2546 return SCM_MAKICHR ('\0');
2548 return SCM_MAKINUM (1L);
2550 return SCM_MAKINUM (-1L);
2552 return SCM_CDR (scm_intern ("s", 1));
2553 #ifdef HAVE_LONG_LONGS
2554 case scm_tc7_llvect
:
2555 return SCM_CDR (scm_intern ("l", 1));
2560 return scm_makflo (1.0);
2563 return scm_makdbl (1.0 / 3.0, 0.0);
2565 return scm_makdbl (0.0, 1.0);
2575 return SCM_ARRAY_V (ptr
);
2582 scm_must_free (SCM_CHARS (ptr
));
2583 return sizeof (scm_array
) + SCM_ARRAY_NDIM (ptr
) * sizeof (scm_array_dim
);
2589 scm_tc16_array
= scm_make_smob_type_mfpe ("array", 0,
2594 scm_add_feature ("array");