mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
* Makefile.am (libguile_la_SOURCES): Removed extchrs.c, mbstrings.c. (modinclude_HEADERS): Removed extchrs.h, mbstrings.h. * unif.c (scm_vector_set_length_x): Don't handle multibyte strings. * tag.c (scm_utag_mb_string, scm_utag_mb_substring): Removed. (scm_tag): Don't handle multibyte strings. * read.c: Don't include mbstrings.h. (scm_lreadr): Don't handle multibyte ports. * kw.c: Don't include mbstrings.h. * init.c: Don't include mbstrings.h. (scm_boot_guile_1): Don't init mbstrings module. * hash.c (scm_hasher): Don't handle mbstrings. * gscm.c (gscm_run_scm): Don't init mbstrings module. * gc.c (scm_gc_mark): Don't handle mbstrings. (scm_gc_sweep): Likewise. * eval.c (SCM_CEVAL): Don't handle mbstrings. * eq.c (scm_equal_p): Use SCM_TYP7S, not SCM_TYP7SD. * tags.h (SCM_TYP7SD): Removed. (SCM_TYP7D): Removed. (scm_tc7_mb_string): Removed. (scm_tc7_mb_substring): Removed. * print.c (scm_iprin1): Handle char printing directly. Don't handle mbstrings. Don't include "mbstrings.h". * symbols.c (scm_intern_obarray_soft, scm_string_to_symbol, scm_string_to_obarray_symbol, msymbolize): Don't set symbol's multi-byte flag. Don't include "mbstrings.h". * symbols.h (SCM_SYMBOL_MULTI_BYTE_STRINGP): Removed. (SCM_SYMBOL_SLOTS): Define as 4. (SCM_ROSTRINGP): Use SCM_TYP7S, not SCM_TYP7SD. * arbiters.c, backtrace.c, debug.c, dynl.c, eval.c, fluids.c, gc.c, gsubr.c, ioext.c, kw.c, mallocs.c, numbers.c, ports.c, print.c, read.c, regex-posix.c, root.c, srcprop.c, stackchk.c, struct.c, threads.c, throw.c, unif.c, variable.c: Use new ("gen"-less) I/O function names. * ports.c (scm_add_to_port_table): Don't set port's representation. * ports.h (scm_port_representation_type): Removed. (scm_string_representation_type): Removed. (struct scm_port_table ): Removed representation field. (SCM_PORT_REPRESENTATION): Removed. (SCM_SET_PORT_REPRESENTATION): Removed. * genio.h: Use new function names. * genio.c: Don't include "extchrs.h". (scm_gen_putc, scm_gen_puts, scm_gen_write, scm_get_getc): Removed. (scm_putc, scm_puts, scm_lfwrite): No longer static. (scm_getc): No longer static; handle line and column changes. (scm_ungetc): Renamed from scm_gen_ungetc. (scm_do_read_line): Renamed from scm_gen_read_line. * libguile.h: Don't include "extchrs.h" or "mbstrings.h" * extchrs.h, extchrs.c, mbstrings.h, mbstrings.c: Removed.
2590 lines
63 KiB
C
2590 lines
63 KiB
C
/* Copyright (C) 1995,1996,1997 Free Software Foundation, Inc.
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2, or (at your option)
|
||
* any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this software; see the file COPYING. If not, write to
|
||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||
* Boston, MA 02111-1307 USA
|
||
*
|
||
* As a special exception, the Free Software Foundation gives permission
|
||
* for additional uses of the text contained in its release of GUILE.
|
||
*
|
||
* The exception is that, if you link the GUILE library with other files
|
||
* to produce an executable, this does not by itself cause the
|
||
* resulting executable to be covered by the GNU General Public License.
|
||
* Your use of that executable is in no way restricted on account of
|
||
* linking the GUILE library code into it.
|
||
*
|
||
* This exception does not however invalidate any other reasons why
|
||
* the executable file might be covered by the GNU General Public License.
|
||
*
|
||
* This exception applies only to the code released by the
|
||
* Free Software Foundation under the name GUILE. If you copy
|
||
* code from other Free Software Foundation releases into a copy of
|
||
* GUILE, as the General Public License permits, the exception does
|
||
* not apply to the code that you add in this way. To avoid misleading
|
||
* anyone as to the status of such modified files, you must delete
|
||
* this exception notice from them.
|
||
*
|
||
* If you write modifications of your own for GUILE, it is your choice
|
||
* whether to permit this exception to apply to your modifications.
|
||
* If you do not wish that, delete this exception notice. */
|
||
|
||
|
||
#include <stdio.h>
|
||
#include "_scm.h"
|
||
#include "chars.h"
|
||
#include "eval.h"
|
||
#include "genio.h"
|
||
#include "smob.h"
|
||
#include "strop.h"
|
||
#include "feature.h"
|
||
|
||
#include "unif.h"
|
||
#include "ramap.h"
|
||
|
||
#ifdef HAVE_UNISTD_H
|
||
#include <unistd.h>
|
||
#endif
|
||
|
||
|
||
/* The set of uniform scm_vector types is:
|
||
* Vector of: Called:
|
||
* unsigned char string
|
||
* char byvect
|
||
* boolean bvect
|
||
* signed int ivect
|
||
* unsigned int uvect
|
||
* float fvect
|
||
* double dvect
|
||
* complex double cvect
|
||
* short svect
|
||
* long_long llvect
|
||
*/
|
||
|
||
long scm_tc16_array;
|
||
|
||
/*
|
||
* This complicates things too much if allowed on any array.
|
||
* C code can safely call it on arrays known to be used in a single
|
||
* threaded manner.
|
||
*
|
||
* SCM_PROC(s_vector_set_length_x, "vector-set-length!", 2, 0, 0, scm_vector_set_length_x);
|
||
*/
|
||
static char s_vector_set_length_x[] = "vector-set-length!";
|
||
|
||
|
||
SCM
|
||
scm_vector_set_length_x (vect, len)
|
||
SCM vect;
|
||
SCM len;
|
||
{
|
||
long l;
|
||
scm_sizet siz;
|
||
scm_sizet sz;
|
||
|
||
l = SCM_INUM (len);
|
||
SCM_ASRTGO (SCM_NIMP (vect), badarg1);
|
||
switch (SCM_TYP7 (vect))
|
||
{
|
||
default:
|
||
badarg1: scm_wta (vect, (char *) SCM_ARG1, s_vector_set_length_x);
|
||
case scm_tc7_string:
|
||
SCM_ASRTGO (vect != scm_nullstr, badarg1);
|
||
sz = sizeof (char);
|
||
l++;
|
||
break;
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
SCM_ASRTGO (vect != scm_nullvect, badarg1);
|
||
sz = sizeof (SCM);
|
||
break;
|
||
#ifdef ARRAYS
|
||
case scm_tc7_bvect:
|
||
l = (l + SCM_LONG_BIT - 1) / SCM_LONG_BIT;
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
sz = sizeof (long);
|
||
break;
|
||
case scm_tc7_byvect:
|
||
sz = sizeof (char);
|
||
break;
|
||
|
||
case scm_tc7_svect:
|
||
sz = sizeof (short);
|
||
break;
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
sz = sizeof (long_long);
|
||
break;
|
||
#endif
|
||
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
sz = sizeof (float);
|
||
break;
|
||
#endif
|
||
case scm_tc7_dvect:
|
||
sz = sizeof (double);
|
||
break;
|
||
case scm_tc7_cvect:
|
||
sz = 2 * sizeof (double);
|
||
break;
|
||
#endif
|
||
#endif
|
||
}
|
||
SCM_ASSERT (SCM_INUMP (len), len, SCM_ARG2, s_vector_set_length_x);
|
||
if (!l)
|
||
l = 1L;
|
||
siz = l * sz;
|
||
if (siz != l * sz)
|
||
scm_wta (SCM_MAKINUM (l * sz), (char *) SCM_NALLOC, s_vector_set_length_x);
|
||
SCM_REDEFER_INTS;
|
||
SCM_SETCHARS (vect,
|
||
((char *)
|
||
scm_must_realloc (SCM_CHARS (vect),
|
||
(long) SCM_LENGTH (vect) * sz,
|
||
(long) siz,
|
||
s_vector_set_length_x)));
|
||
if (SCM_VECTORP (vect))
|
||
{
|
||
sz = SCM_LENGTH (vect);
|
||
while (l > sz)
|
||
SCM_VELTS (vect)[--l] = SCM_UNSPECIFIED;
|
||
}
|
||
else if (SCM_STRINGP (vect))
|
||
SCM_CHARS (vect)[l - 1] = 0;
|
||
SCM_SETLENGTH (vect, SCM_INUM (len), SCM_TYP7 (vect));
|
||
SCM_REALLOW_INTS;
|
||
return vect;
|
||
}
|
||
|
||
|
||
#ifdef ARRAYS
|
||
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
|
||
|
||
SCM
|
||
scm_makflo (float x)
|
||
{
|
||
SCM z;
|
||
if (x == 0.0)
|
||
return scm_flo0;
|
||
SCM_NEWCELL (z);
|
||
SCM_DEFER_INTS;
|
||
SCM_SETCAR (z, scm_tc_flo);
|
||
SCM_FLO (z) = x;
|
||
SCM_ALLOW_INTS;
|
||
return z;
|
||
}
|
||
#endif
|
||
#endif
|
||
|
||
|
||
SCM
|
||
scm_make_uve (k, prot)
|
||
long k;
|
||
SCM prot;
|
||
{
|
||
SCM v;
|
||
long i, type;
|
||
if (SCM_BOOL_T == prot)
|
||
{
|
||
i = sizeof (long) * ((k + SCM_LONG_BIT - 1) / SCM_LONG_BIT);
|
||
type = scm_tc7_bvect;
|
||
}
|
||
else if (SCM_ICHRP (prot) && (prot == SCM_MAKICHR ('\0')))
|
||
{
|
||
i = sizeof (char) * k;
|
||
type = scm_tc7_byvect;
|
||
}
|
||
else if (SCM_ICHRP (prot))
|
||
{
|
||
i = sizeof (char) * k;
|
||
type = scm_tc7_string;
|
||
}
|
||
else if (SCM_INUMP (prot))
|
||
{
|
||
i = sizeof (long) * k;
|
||
if (SCM_INUM (prot) > 0)
|
||
type = scm_tc7_uvect;
|
||
else
|
||
type = scm_tc7_ivect;
|
||
}
|
||
else if (SCM_NIMP (prot) && SCM_SYMBOLP (prot) && (1 == SCM_LENGTH (prot)))
|
||
{
|
||
char s;
|
||
|
||
s = SCM_CHARS (prot)[0];
|
||
if (s == 's')
|
||
{
|
||
i = sizeof (short) * k;
|
||
type = scm_tc7_svect;
|
||
}
|
||
#ifdef LONGLONGS
|
||
else if (s == 'l')
|
||
{
|
||
i = sizeof (long_long) * k;
|
||
type = scm_tc7_llvect;
|
||
}
|
||
#endif
|
||
else
|
||
{
|
||
return scm_make_vector (SCM_MAKINUM (k), SCM_UNDEFINED, SCM_UNDEFINED);
|
||
}
|
||
}
|
||
else
|
||
#ifdef SCM_FLOATS
|
||
if (SCM_IMP (prot) || !SCM_INEXP (prot))
|
||
#endif
|
||
/* Huge non-unif vectors are NOT supported. */
|
||
return scm_make_vector (SCM_MAKINUM (k), SCM_UNDEFINED, SCM_UNDEFINED); /* no special scm_vector */
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
else if (SCM_SINGP (prot))
|
||
|
||
{
|
||
i = sizeof (float) * k;
|
||
type = scm_tc7_fvect;
|
||
}
|
||
#endif
|
||
else if (SCM_CPLXP (prot))
|
||
{
|
||
i = 2 * sizeof (double) * k;
|
||
type = scm_tc7_cvect;
|
||
}
|
||
else
|
||
{
|
||
i = sizeof (double) * k;
|
||
type = scm_tc7_dvect;
|
||
}
|
||
#endif
|
||
|
||
SCM_NEWCELL (v);
|
||
SCM_DEFER_INTS;
|
||
{
|
||
char *m;
|
||
m = scm_must_malloc ((i ? i : 1L), "vector");
|
||
SCM_SETCHARS (v, (char *) m);
|
||
}
|
||
SCM_SETLENGTH (v, (k < SCM_LENGTH_MAX ? k : SCM_LENGTH_MAX), type);
|
||
SCM_ALLOW_INTS;
|
||
return v;
|
||
}
|
||
|
||
SCM_PROC(s_uniform_vector_length, "uniform-vector-length", 1, 0, 0, scm_uniform_vector_length);
|
||
|
||
SCM
|
||
scm_uniform_vector_length (v)
|
||
SCM v;
|
||
{
|
||
SCM_ASRTGO (SCM_NIMP (v), badarg1);
|
||
switch SCM_TYP7
|
||
(v)
|
||
{
|
||
default:
|
||
badarg1:scm_wta (v, (char *) SCM_ARG1, s_uniform_vector_length);
|
||
case scm_tc7_bvect:
|
||
case scm_tc7_string:
|
||
case scm_tc7_byvect:
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
case scm_tc7_fvect:
|
||
case scm_tc7_dvect:
|
||
case scm_tc7_cvect:
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
case scm_tc7_svect:
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
#endif
|
||
return SCM_MAKINUM (SCM_LENGTH (v));
|
||
}
|
||
}
|
||
|
||
SCM_PROC(s_array_p, "array?", 1, 1, 0, scm_array_p);
|
||
|
||
SCM
|
||
scm_array_p (v, prot)
|
||
SCM v;
|
||
SCM prot;
|
||
{
|
||
int nprot;
|
||
int enclosed;
|
||
nprot = SCM_UNBNDP (prot);
|
||
enclosed = 0;
|
||
if (SCM_IMP (v))
|
||
return SCM_BOOL_F;
|
||
loop:
|
||
switch (SCM_TYP7 (v))
|
||
{
|
||
case scm_tc7_smob:
|
||
if (!SCM_ARRAYP (v))
|
||
return SCM_BOOL_F;
|
||
if (nprot)
|
||
return SCM_BOOL_T;
|
||
if (enclosed++)
|
||
return SCM_BOOL_F;
|
||
v = SCM_ARRAY_V (v);
|
||
goto loop;
|
||
case scm_tc7_bvect:
|
||
return nprot || SCM_BOOL_T==prot ? SCM_BOOL_T : SCM_BOOL_F;
|
||
case scm_tc7_string:
|
||
return nprot || (SCM_ICHRP(prot) && (prot != SCM_MAKICHR('\0'))) ? SCM_BOOL_T : SCM_BOOL_F;
|
||
case scm_tc7_byvect:
|
||
return nprot || (prot == SCM_MAKICHR('\0')) ? SCM_BOOL_T : SCM_BOOL_F;
|
||
case scm_tc7_uvect:
|
||
return nprot || (SCM_INUMP(prot) && SCM_INUM(prot)>0) ? SCM_BOOL_T : SCM_BOOL_F;
|
||
case scm_tc7_ivect:
|
||
return nprot || (SCM_INUMP(prot) && SCM_INUM(prot)<=0) ? SCM_BOOL_T : SCM_BOOL_F;
|
||
case scm_tc7_svect:
|
||
return ( nprot
|
||
|| (SCM_NIMP (prot)
|
||
&& SCM_SYMBOLP (prot)
|
||
&& (1 == SCM_LENGTH (prot))
|
||
&& ('s' == SCM_CHARS (prot)[0])));
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
return ( nprot
|
||
|| (SCM_NIMP (prot)
|
||
&& SCM_SYMBOLP (prot)
|
||
&& (1 == SCM_LENGTH (prot))
|
||
&& ('s' == SCM_CHARS (prot)[0])));
|
||
#endif
|
||
# ifdef SCM_FLOATS
|
||
# ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
return nprot || (SCM_NIMP(prot) && SCM_SINGP(prot)) ? SCM_BOOL_T : SCM_BOOL_F;
|
||
# endif
|
||
case scm_tc7_dvect:
|
||
return nprot || (SCM_NIMP(prot) && SCM_REALP(prot)) ? SCM_BOOL_T : SCM_BOOL_F;
|
||
case scm_tc7_cvect:
|
||
return nprot || (SCM_NIMP(prot) && SCM_CPLXP(prot)) ? SCM_BOOL_T : SCM_BOOL_F;
|
||
# endif
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
return nprot || SCM_NULLP(prot) ? SCM_BOOL_T : SCM_BOOL_F;
|
||
default:;
|
||
}
|
||
return SCM_BOOL_F;
|
||
}
|
||
|
||
|
||
SCM_PROC(s_array_rank, "array-rank", 1, 0, 0, scm_array_rank);
|
||
|
||
SCM
|
||
scm_array_rank (ra)
|
||
SCM ra;
|
||
{
|
||
if (SCM_IMP (ra))
|
||
return SCM_INUM0;
|
||
switch (SCM_TYP7 (ra))
|
||
{
|
||
default:
|
||
return SCM_INUM0;
|
||
case scm_tc7_string:
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
case scm_tc7_byvect:
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
case scm_tc7_fvect:
|
||
case scm_tc7_cvect:
|
||
case scm_tc7_dvect:
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
#endif
|
||
case scm_tc7_svect:
|
||
return SCM_MAKINUM (1L);
|
||
case scm_tc7_smob:
|
||
if (SCM_ARRAYP (ra))
|
||
return SCM_MAKINUM (SCM_ARRAY_NDIM (ra));
|
||
return SCM_INUM0;
|
||
}
|
||
}
|
||
|
||
|
||
SCM_PROC(s_array_dimensions, "array-dimensions", 1, 0, 0, scm_array_dimensions);
|
||
|
||
SCM
|
||
scm_array_dimensions (ra)
|
||
SCM ra;
|
||
{
|
||
SCM res = SCM_EOL;
|
||
scm_sizet k;
|
||
scm_array_dim *s;
|
||
if (SCM_IMP (ra))
|
||
return SCM_BOOL_F;
|
||
switch (SCM_TYP7 (ra))
|
||
{
|
||
default:
|
||
return SCM_BOOL_F;
|
||
case scm_tc7_string:
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
case scm_tc7_bvect:
|
||
case scm_tc7_byvect:
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
case scm_tc7_fvect:
|
||
case scm_tc7_cvect:
|
||
case scm_tc7_dvect:
|
||
case scm_tc7_svect:
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
#endif
|
||
return scm_cons (SCM_MAKINUM (SCM_LENGTH (ra)), SCM_EOL);
|
||
case scm_tc7_smob:
|
||
if (!SCM_ARRAYP (ra))
|
||
return SCM_BOOL_F;
|
||
k = SCM_ARRAY_NDIM (ra);
|
||
s = SCM_ARRAY_DIMS (ra);
|
||
while (k--)
|
||
res = scm_cons (s[k].lbnd ? scm_cons2 (SCM_MAKINUM (s[k].lbnd), SCM_MAKINUM (s[k].ubnd), SCM_EOL) :
|
||
SCM_MAKINUM (1 + (s[k].ubnd))
|
||
, res);
|
||
return res;
|
||
}
|
||
}
|
||
|
||
|
||
static char s_bad_ind[] = "Bad scm_array index";
|
||
|
||
|
||
long
|
||
scm_aind (ra, args, what)
|
||
SCM ra;
|
||
SCM args;
|
||
char *what;
|
||
{
|
||
SCM ind;
|
||
register long j;
|
||
register scm_sizet pos = SCM_ARRAY_BASE (ra);
|
||
register scm_sizet k = SCM_ARRAY_NDIM (ra);
|
||
scm_array_dim *s = SCM_ARRAY_DIMS (ra);
|
||
if (SCM_INUMP (args))
|
||
{
|
||
SCM_ASSERT (1 == k, scm_makfrom0str (what), SCM_WNA, NULL);
|
||
return pos + (SCM_INUM (args) - s->lbnd) * (s->inc);
|
||
}
|
||
while (k && SCM_NIMP (args))
|
||
{
|
||
ind = SCM_CAR (args);
|
||
args = SCM_CDR (args);
|
||
SCM_ASSERT (SCM_INUMP (ind), ind, s_bad_ind, what);
|
||
j = SCM_INUM (ind);
|
||
SCM_ASSERT (j >= (s->lbnd) && j <= (s->ubnd), ind, SCM_OUTOFRANGE, what);
|
||
pos += (j - s->lbnd) * (s->inc);
|
||
k--;
|
||
s++;
|
||
}
|
||
SCM_ASSERT (0 == k && SCM_NULLP (args), scm_makfrom0str (what), SCM_WNA,
|
||
NULL);
|
||
return pos;
|
||
}
|
||
|
||
|
||
|
||
SCM
|
||
scm_make_ra (ndim)
|
||
int ndim;
|
||
{
|
||
SCM ra;
|
||
SCM_NEWCELL (ra);
|
||
SCM_DEFER_INTS;
|
||
SCM_SETCDR (ra, scm_must_malloc ((long) (sizeof (scm_array) + ndim * sizeof (scm_array_dim)),
|
||
"array"));
|
||
SCM_SETCAR (ra, ((long) ndim << 17) + scm_tc16_array);
|
||
SCM_ARRAY_V (ra) = scm_nullvect;
|
||
SCM_ALLOW_INTS;
|
||
return ra;
|
||
}
|
||
|
||
static char s_bad_spec[] = "Bad scm_array dimension";
|
||
/* Increments will still need to be set. */
|
||
|
||
|
||
SCM
|
||
scm_shap2ra (args, what)
|
||
SCM args;
|
||
char *what;
|
||
{
|
||
scm_array_dim *s;
|
||
SCM ra, spec, sp;
|
||
int ndim = scm_ilength (args);
|
||
SCM_ASSERT (0 <= ndim, args, s_bad_spec, what);
|
||
ra = scm_make_ra (ndim);
|
||
SCM_ARRAY_BASE (ra) = 0;
|
||
s = SCM_ARRAY_DIMS (ra);
|
||
for (; SCM_NIMP (args); s++, args = SCM_CDR (args))
|
||
{
|
||
spec = SCM_CAR (args);
|
||
if (SCM_IMP (spec))
|
||
|
||
{
|
||
SCM_ASSERT (SCM_INUMP (spec) && SCM_INUM (spec) >= 0, spec,
|
||
s_bad_spec, what);
|
||
s->lbnd = 0;
|
||
s->ubnd = SCM_INUM (spec) - 1;
|
||
s->inc = 1;
|
||
}
|
||
else
|
||
{
|
||
SCM_ASSERT (SCM_CONSP (spec) && SCM_INUMP (SCM_CAR (spec)), spec,
|
||
s_bad_spec, what);
|
||
s->lbnd = SCM_INUM (SCM_CAR (spec));
|
||
sp = SCM_CDR (spec);
|
||
SCM_ASSERT (SCM_NIMP (sp) && SCM_CONSP (sp)
|
||
&& SCM_INUMP (SCM_CAR (sp)) && SCM_NULLP (SCM_CDR (sp)),
|
||
spec, s_bad_spec, what);
|
||
s->ubnd = SCM_INUM (SCM_CAR (sp));
|
||
s->inc = 1;
|
||
}
|
||
}
|
||
return ra;
|
||
}
|
||
|
||
SCM_PROC(s_dimensions_to_uniform_array, "dimensions->uniform-array", 2, 0, 1, scm_dimensions_to_uniform_array);
|
||
|
||
SCM
|
||
scm_dimensions_to_uniform_array (dims, prot, fill)
|
||
SCM dims;
|
||
SCM prot;
|
||
SCM fill;
|
||
{
|
||
scm_sizet k, vlen = 1;
|
||
long rlen = 1;
|
||
scm_array_dim *s;
|
||
SCM ra;
|
||
if (SCM_INUMP (dims))
|
||
if (SCM_INUM (dims) < SCM_LENGTH_MAX)
|
||
{
|
||
SCM answer;
|
||
answer = scm_make_uve (SCM_INUM (dims), prot);
|
||
if (SCM_NNULLP (fill))
|
||
{
|
||
SCM_ASSERT (1 == scm_ilength (fill),
|
||
scm_makfrom0str (s_dimensions_to_uniform_array),
|
||
SCM_WNA, NULL);
|
||
scm_array_fill_x (answer, SCM_CAR (fill));
|
||
}
|
||
else if (SCM_NIMP (prot) && SCM_SYMBOLP (prot))
|
||
scm_array_fill_x (answer, SCM_MAKINUM (0));
|
||
else
|
||
scm_array_fill_x (answer, prot);
|
||
return answer;
|
||
}
|
||
else
|
||
dims = scm_cons (dims, SCM_EOL);
|
||
SCM_ASSERT (SCM_NULLP (dims) || (SCM_NIMP (dims) && SCM_CONSP (dims)),
|
||
dims, SCM_ARG1, s_dimensions_to_uniform_array);
|
||
ra = scm_shap2ra (dims, s_dimensions_to_uniform_array);
|
||
SCM_SETOR_CAR (ra, SCM_ARRAY_CONTIGUOUS);
|
||
s = SCM_ARRAY_DIMS (ra);
|
||
k = SCM_ARRAY_NDIM (ra);
|
||
while (k--)
|
||
{
|
||
s[k].inc = (rlen > 0 ? rlen : 0);
|
||
rlen = (s[k].ubnd - s[k].lbnd + 1) * s[k].inc;
|
||
vlen *= (s[k].ubnd - s[k].lbnd + 1);
|
||
}
|
||
if (rlen < SCM_LENGTH_MAX)
|
||
SCM_ARRAY_V (ra) = scm_make_uve ((rlen > 0 ? rlen : 0L), prot);
|
||
else
|
||
{
|
||
scm_sizet bit;
|
||
switch (SCM_TYP7 (scm_make_uve (0L, prot)))
|
||
{
|
||
default:
|
||
bit = SCM_LONG_BIT;
|
||
break;
|
||
case scm_tc7_bvect:
|
||
bit = 1;
|
||
break;
|
||
case scm_tc7_string:
|
||
bit = SCM_CHAR_BIT;
|
||
break;
|
||
case scm_tc7_fvect:
|
||
bit = sizeof (float) * SCM_CHAR_BIT / sizeof (char);
|
||
break;
|
||
case scm_tc7_dvect:
|
||
bit = sizeof (double) * SCM_CHAR_BIT / sizeof (char);
|
||
break;
|
||
case scm_tc7_cvect:
|
||
bit = 2 * sizeof (double) * SCM_CHAR_BIT / sizeof (char);
|
||
break;
|
||
}
|
||
SCM_ARRAY_BASE (ra) = (SCM_LONG_BIT + bit - 1) / bit;
|
||
rlen += SCM_ARRAY_BASE (ra);
|
||
SCM_ARRAY_V (ra) = scm_make_uve (rlen, prot);
|
||
*((long *) SCM_VELTS (SCM_ARRAY_V (ra))) = rlen;
|
||
}
|
||
if (SCM_NNULLP (fill))
|
||
{
|
||
SCM_ASSERT (1 == scm_ilength (fill),
|
||
scm_makfrom0str (s_dimensions_to_uniform_array), SCM_WNA,
|
||
NULL);
|
||
scm_array_fill_x (ra, SCM_CAR (fill));
|
||
}
|
||
else if (SCM_NIMP (prot) && SCM_SYMBOLP (prot))
|
||
scm_array_fill_x (ra, SCM_MAKINUM (0));
|
||
else
|
||
scm_array_fill_x (ra, prot);
|
||
if (1 == SCM_ARRAY_NDIM (ra) && 0 == SCM_ARRAY_BASE (ra))
|
||
if (s->ubnd < s->lbnd || (0 == s->lbnd && 1 == s->inc))
|
||
return SCM_ARRAY_V (ra);
|
||
return ra;
|
||
}
|
||
|
||
|
||
void
|
||
scm_ra_set_contp (ra)
|
||
SCM ra;
|
||
{
|
||
scm_sizet k = SCM_ARRAY_NDIM (ra);
|
||
if (k)
|
||
{
|
||
long inc = SCM_ARRAY_DIMS (ra)[k - 1].inc;
|
||
while (k--)
|
||
{
|
||
if (inc != SCM_ARRAY_DIMS (ra)[k].inc)
|
||
{
|
||
SCM_SETAND_CAR (ra, ~SCM_ARRAY_CONTIGUOUS);
|
||
return;
|
||
}
|
||
inc *= (SCM_ARRAY_DIMS (ra)[k].ubnd
|
||
- SCM_ARRAY_DIMS (ra)[k].lbnd + 1);
|
||
}
|
||
}
|
||
SCM_SETOR_CAR (ra, SCM_ARRAY_CONTIGUOUS);
|
||
}
|
||
|
||
|
||
SCM_PROC(s_make_shared_array, "make-shared-array", 2, 0, 1, scm_make_shared_array);
|
||
|
||
SCM
|
||
scm_make_shared_array (oldra, mapfunc, dims)
|
||
SCM oldra;
|
||
SCM mapfunc;
|
||
SCM dims;
|
||
{
|
||
SCM ra;
|
||
SCM inds, indptr;
|
||
SCM imap;
|
||
scm_sizet i, k;
|
||
long old_min, new_min, old_max, new_max;
|
||
scm_array_dim *s;
|
||
SCM_ASSERT (SCM_BOOL_T == scm_procedure_p (mapfunc), mapfunc, SCM_ARG2, s_make_shared_array);
|
||
SCM_ASSERT (SCM_NIMP (oldra) && (SCM_BOOL_F != scm_array_p (oldra, SCM_UNDEFINED)), oldra, SCM_ARG1, s_make_shared_array);
|
||
ra = scm_shap2ra (dims, s_make_shared_array);
|
||
if (SCM_ARRAYP (oldra))
|
||
{
|
||
SCM_ARRAY_V (ra) = SCM_ARRAY_V (oldra);
|
||
old_min = old_max = SCM_ARRAY_BASE (oldra);
|
||
s = SCM_ARRAY_DIMS (oldra);
|
||
k = SCM_ARRAY_NDIM (oldra);
|
||
while (k--)
|
||
{
|
||
if (s[k].inc > 0)
|
||
old_max += (s[k].ubnd - s[k].lbnd) * s[k].inc;
|
||
else
|
||
old_min += (s[k].ubnd - s[k].lbnd) * s[k].inc;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SCM_ARRAY_V (ra) = oldra;
|
||
old_min = 0;
|
||
old_max = (long) SCM_LENGTH (oldra) - 1;
|
||
}
|
||
inds = SCM_EOL;
|
||
s = SCM_ARRAY_DIMS (ra);
|
||
for (k = 0; k < SCM_ARRAY_NDIM (ra); k++)
|
||
{
|
||
inds = scm_cons (SCM_MAKINUM (s[k].lbnd), inds);
|
||
if (s[k].ubnd < s[k].lbnd)
|
||
{
|
||
if (1 == SCM_ARRAY_NDIM (ra))
|
||
ra = scm_make_uve (0L, scm_array_prototype (ra));
|
||
else
|
||
SCM_ARRAY_V (ra) = scm_make_uve (0L, scm_array_prototype (ra));
|
||
return ra;
|
||
}
|
||
}
|
||
imap = scm_apply (mapfunc, scm_reverse (inds), SCM_EOL);
|
||
if (SCM_ARRAYP (oldra))
|
||
i = (scm_sizet) scm_aind (oldra, imap, s_make_shared_array);
|
||
else
|
||
{
|
||
if (SCM_NINUMP (imap))
|
||
|
||
{
|
||
SCM_ASSERT (1 == scm_ilength (imap) && SCM_INUMP (SCM_CAR (imap)),
|
||
imap, s_bad_ind, s_make_shared_array);
|
||
imap = SCM_CAR (imap);
|
||
}
|
||
i = SCM_INUM (imap);
|
||
}
|
||
SCM_ARRAY_BASE (ra) = new_min = new_max = i;
|
||
indptr = inds;
|
||
k = SCM_ARRAY_NDIM (ra);
|
||
while (k--)
|
||
{
|
||
if (s[k].ubnd > s[k].lbnd)
|
||
{
|
||
SCM_SETCAR (indptr, SCM_MAKINUM (SCM_INUM (SCM_CAR (indptr)) + 1));
|
||
imap = scm_apply (mapfunc, scm_reverse (inds), SCM_EOL);
|
||
if (SCM_ARRAYP (oldra))
|
||
|
||
s[k].inc = scm_aind (oldra, imap, s_make_shared_array) - i;
|
||
else
|
||
{
|
||
if (SCM_NINUMP (imap))
|
||
|
||
{
|
||
SCM_ASSERT (1 == scm_ilength (imap) && SCM_INUMP (SCM_CAR (imap)),
|
||
imap, s_bad_ind, s_make_shared_array);
|
||
imap = SCM_CAR (imap);
|
||
}
|
||
s[k].inc = (long) SCM_INUM (imap) - i;
|
||
}
|
||
i += s[k].inc;
|
||
if (s[k].inc > 0)
|
||
new_max += (s[k].ubnd - s[k].lbnd) * s[k].inc;
|
||
else
|
||
new_min += (s[k].ubnd - s[k].lbnd) * s[k].inc;
|
||
}
|
||
else
|
||
s[k].inc = new_max - new_min + 1; /* contiguous by default */
|
||
indptr = SCM_CDR (indptr);
|
||
}
|
||
SCM_ASSERT (old_min <= new_min && old_max >= new_max, SCM_UNDEFINED,
|
||
"mapping out of range", s_make_shared_array);
|
||
if (1 == SCM_ARRAY_NDIM (ra) && 0 == SCM_ARRAY_BASE (ra))
|
||
{
|
||
if (1 == s->inc && 0 == s->lbnd
|
||
&& SCM_LENGTH (SCM_ARRAY_V (ra)) == 1 + s->ubnd)
|
||
return SCM_ARRAY_V (ra);
|
||
if (s->ubnd < s->lbnd)
|
||
return scm_make_uve (0L, scm_array_prototype (ra));
|
||
}
|
||
scm_ra_set_contp (ra);
|
||
return ra;
|
||
}
|
||
|
||
|
||
/* args are RA . DIMS */
|
||
SCM_PROC(s_transpose_array, "transpose-array", 0, 0, 1, scm_transpose_array);
|
||
|
||
SCM
|
||
scm_transpose_array (args)
|
||
SCM args;
|
||
{
|
||
SCM ra, res, vargs, *ve = &vargs;
|
||
scm_array_dim *s, *r;
|
||
int ndim, i, k;
|
||
SCM_ASSERT (SCM_NNULLP (args), scm_makfrom0str (s_transpose_array),
|
||
SCM_WNA, NULL);
|
||
ra = SCM_CAR (args);
|
||
SCM_ASSERT (SCM_NIMP (ra), ra, SCM_ARG1, s_transpose_array);
|
||
args = SCM_CDR (args);
|
||
switch (SCM_TYP7 (ra))
|
||
{
|
||
default:
|
||
badarg:scm_wta (ra, (char *) SCM_ARG1, s_transpose_array);
|
||
case scm_tc7_bvect:
|
||
case scm_tc7_string:
|
||
case scm_tc7_byvect:
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
case scm_tc7_fvect:
|
||
case scm_tc7_dvect:
|
||
case scm_tc7_cvect:
|
||
case scm_tc7_svect:
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
#endif
|
||
SCM_ASSERT (SCM_NIMP (args) && SCM_NULLP (SCM_CDR (args)),
|
||
scm_makfrom0str (s_transpose_array), SCM_WNA, NULL);
|
||
SCM_ASSERT (SCM_INUMP (SCM_CAR (args)), SCM_CAR (args), SCM_ARG2,
|
||
s_transpose_array);
|
||
SCM_ASSERT (SCM_INUM0 == SCM_CAR (args), SCM_CAR (args), SCM_OUTOFRANGE,
|
||
s_transpose_array);
|
||
return ra;
|
||
case scm_tc7_smob:
|
||
SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
|
||
vargs = scm_vector (args);
|
||
SCM_ASSERT (SCM_LENGTH (vargs) == SCM_ARRAY_NDIM (ra),
|
||
scm_makfrom0str (s_transpose_array), SCM_WNA, NULL);
|
||
ve = SCM_VELTS (vargs);
|
||
ndim = 0;
|
||
for (k = 0; k < SCM_ARRAY_NDIM (ra); k++)
|
||
{
|
||
SCM_ASSERT (SCM_INUMP (ve[k]), ve[k], (SCM_ARG2 + k),
|
||
s_transpose_array);
|
||
i = SCM_INUM (ve[k]);
|
||
SCM_ASSERT (i >= 0 && i < SCM_ARRAY_NDIM (ra), ve[k],
|
||
SCM_OUTOFRANGE, s_transpose_array);
|
||
if (ndim < i)
|
||
ndim = i;
|
||
}
|
||
ndim++;
|
||
res = scm_make_ra (ndim);
|
||
SCM_ARRAY_V (res) = SCM_ARRAY_V (ra);
|
||
SCM_ARRAY_BASE (res) = SCM_ARRAY_BASE (ra);
|
||
for (k = ndim; k--;)
|
||
{
|
||
SCM_ARRAY_DIMS (res)[k].lbnd = 0;
|
||
SCM_ARRAY_DIMS (res)[k].ubnd = -1;
|
||
}
|
||
for (k = SCM_ARRAY_NDIM (ra); k--;)
|
||
{
|
||
i = SCM_INUM (ve[k]);
|
||
s = &(SCM_ARRAY_DIMS (ra)[k]);
|
||
r = &(SCM_ARRAY_DIMS (res)[i]);
|
||
if (r->ubnd < r->lbnd)
|
||
{
|
||
r->lbnd = s->lbnd;
|
||
r->ubnd = s->ubnd;
|
||
r->inc = s->inc;
|
||
ndim--;
|
||
}
|
||
else
|
||
{
|
||
if (r->ubnd > s->ubnd)
|
||
r->ubnd = s->ubnd;
|
||
if (r->lbnd < s->lbnd)
|
||
{
|
||
SCM_ARRAY_BASE (res) += (s->lbnd - r->lbnd) * r->inc;
|
||
r->lbnd = s->lbnd;
|
||
}
|
||
r->inc += s->inc;
|
||
}
|
||
}
|
||
SCM_ASSERT (ndim <= 0, args, "bad argument list", s_transpose_array);
|
||
scm_ra_set_contp (res);
|
||
return res;
|
||
}
|
||
}
|
||
|
||
/* args are RA . AXES */
|
||
SCM_PROC(s_enclose_array, "enclose-array", 0, 0, 1, scm_enclose_array);
|
||
|
||
SCM
|
||
scm_enclose_array (axes)
|
||
SCM axes;
|
||
{
|
||
SCM axv, ra, res, ra_inr;
|
||
scm_array_dim vdim, *s = &vdim;
|
||
int ndim, j, k, ninr, noutr;
|
||
SCM_ASSERT (SCM_NIMP (axes), scm_makfrom0str (s_enclose_array), SCM_WNA,
|
||
NULL);
|
||
ra = SCM_CAR (axes);
|
||
axes = SCM_CDR (axes);
|
||
if (SCM_NULLP (axes))
|
||
|
||
axes = scm_cons ((SCM_ARRAYP (ra) ? SCM_MAKINUM (SCM_ARRAY_NDIM (ra) - 1) : SCM_INUM0), SCM_EOL);
|
||
ninr = scm_ilength (axes);
|
||
ra_inr = scm_make_ra (ninr);
|
||
SCM_ASRTGO (SCM_NIMP (ra), badarg1);
|
||
switch SCM_TYP7
|
||
(ra)
|
||
{
|
||
default:
|
||
badarg1:scm_wta (ra, (char *) SCM_ARG1, s_enclose_array);
|
||
case scm_tc7_string:
|
||
case scm_tc7_bvect:
|
||
case scm_tc7_byvect:
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
case scm_tc7_fvect:
|
||
case scm_tc7_dvect:
|
||
case scm_tc7_cvect:
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
case scm_tc7_svect:
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
#endif
|
||
s->lbnd = 0;
|
||
s->ubnd = SCM_LENGTH (ra) - 1;
|
||
s->inc = 1;
|
||
SCM_ARRAY_V (ra_inr) = ra;
|
||
SCM_ARRAY_BASE (ra_inr) = 0;
|
||
ndim = 1;
|
||
break;
|
||
case scm_tc7_smob:
|
||
SCM_ASRTGO (SCM_ARRAYP (ra), badarg1);
|
||
s = SCM_ARRAY_DIMS (ra);
|
||
SCM_ARRAY_V (ra_inr) = SCM_ARRAY_V (ra);
|
||
SCM_ARRAY_BASE (ra_inr) = SCM_ARRAY_BASE (ra);
|
||
ndim = SCM_ARRAY_NDIM (ra);
|
||
break;
|
||
}
|
||
noutr = ndim - ninr;
|
||
axv = scm_make_string (SCM_MAKINUM (ndim), SCM_MAKICHR (0));
|
||
SCM_ASSERT (0 <= noutr && 0 <= ninr, scm_makfrom0str (s_enclose_array),
|
||
SCM_WNA, NULL);
|
||
res = scm_make_ra (noutr);
|
||
SCM_ARRAY_BASE (res) = SCM_ARRAY_BASE (ra_inr);
|
||
SCM_ARRAY_V (res) = ra_inr;
|
||
for (k = 0; k < ninr; k++, axes = SCM_CDR (axes))
|
||
{
|
||
SCM_ASSERT (SCM_INUMP (SCM_CAR (axes)), SCM_CAR (axes), "bad axis", s_enclose_array);
|
||
j = SCM_INUM (SCM_CAR (axes));
|
||
SCM_ARRAY_DIMS (ra_inr)[k].lbnd = s[j].lbnd;
|
||
SCM_ARRAY_DIMS (ra_inr)[k].ubnd = s[j].ubnd;
|
||
SCM_ARRAY_DIMS (ra_inr)[k].inc = s[j].inc;
|
||
SCM_CHARS (axv)[j] = 1;
|
||
}
|
||
for (j = 0, k = 0; k < noutr; k++, j++)
|
||
{
|
||
while (SCM_CHARS (axv)[j])
|
||
j++;
|
||
SCM_ARRAY_DIMS (res)[k].lbnd = s[j].lbnd;
|
||
SCM_ARRAY_DIMS (res)[k].ubnd = s[j].ubnd;
|
||
SCM_ARRAY_DIMS (res)[k].inc = s[j].inc;
|
||
}
|
||
scm_ra_set_contp (ra_inr);
|
||
scm_ra_set_contp (res);
|
||
return res;
|
||
}
|
||
|
||
|
||
|
||
SCM_PROC(s_array_in_bounds_p, "array-in-bounds?", 0, 0, 1, scm_array_in_bounds_p);
|
||
|
||
SCM
|
||
scm_array_in_bounds_p (args)
|
||
SCM args;
|
||
{
|
||
SCM v, ind = SCM_EOL;
|
||
long pos = 0;
|
||
register scm_sizet k;
|
||
register long j;
|
||
scm_array_dim *s;
|
||
SCM_ASSERT (SCM_NIMP (args), scm_makfrom0str (s_array_in_bounds_p),
|
||
SCM_WNA, NULL);
|
||
v = SCM_CAR (args);
|
||
args = SCM_CDR (args);
|
||
SCM_ASRTGO (SCM_NIMP (v), badarg1);
|
||
if (SCM_NIMP (args))
|
||
|
||
{
|
||
ind = SCM_CAR (args);
|
||
args = SCM_CDR (args);
|
||
SCM_ASSERT (SCM_INUMP (ind), ind, SCM_ARG2, s_array_in_bounds_p);
|
||
pos = SCM_INUM (ind);
|
||
}
|
||
tail:
|
||
switch SCM_TYP7
|
||
(v)
|
||
{
|
||
default:
|
||
badarg1:scm_wta (v, (char *) SCM_ARG1, s_array_in_bounds_p);
|
||
wna: scm_wrong_num_args (scm_makfrom0str (s_array_in_bounds_p));
|
||
case scm_tc7_smob:
|
||
k = SCM_ARRAY_NDIM (v);
|
||
s = SCM_ARRAY_DIMS (v);
|
||
pos = SCM_ARRAY_BASE (v);
|
||
if (!k)
|
||
{
|
||
SCM_ASRTGO (SCM_NULLP (ind), wna);
|
||
ind = SCM_INUM0;
|
||
}
|
||
else
|
||
while (!0)
|
||
{
|
||
j = SCM_INUM (ind);
|
||
if (!(j >= (s->lbnd) && j <= (s->ubnd)))
|
||
{
|
||
SCM_ASRTGO (--k == scm_ilength (args), wna);
|
||
return SCM_BOOL_F;
|
||
}
|
||
pos += (j - s->lbnd) * (s->inc);
|
||
if (!(--k && SCM_NIMP (args)))
|
||
break;
|
||
ind = SCM_CAR (args);
|
||
args = SCM_CDR (args);
|
||
s++;
|
||
SCM_ASSERT (SCM_INUMP (ind), ind, s_bad_ind, s_array_in_bounds_p);
|
||
}
|
||
SCM_ASRTGO (0 == k, wna);
|
||
v = SCM_ARRAY_V (v);
|
||
goto tail;
|
||
case scm_tc7_bvect:
|
||
case scm_tc7_string:
|
||
case scm_tc7_byvect:
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
case scm_tc7_fvect:
|
||
case scm_tc7_dvect:
|
||
case scm_tc7_cvect:
|
||
case scm_tc7_svect:
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
#endif
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
SCM_ASRTGO (SCM_NULLP (args) && SCM_INUMP (ind), wna);
|
||
return pos >= 0 && pos < SCM_LENGTH (v) ? SCM_BOOL_T : SCM_BOOL_F;
|
||
}
|
||
}
|
||
|
||
|
||
SCM_PROC(s_array_ref, "array-ref", 1, 0, 1, scm_uniform_vector_ref);
|
||
SCM_PROC(s_uniform_vector_ref, "uniform-vector-ref", 2, 0, 0, scm_uniform_vector_ref);
|
||
|
||
SCM
|
||
scm_uniform_vector_ref (v, args)
|
||
SCM v;
|
||
SCM args;
|
||
{
|
||
long pos;
|
||
|
||
if (SCM_IMP (v))
|
||
{
|
||
SCM_ASRTGO (SCM_NULLP (args), badarg);
|
||
return v;
|
||
}
|
||
else if (SCM_ARRAYP (v))
|
||
{
|
||
pos = scm_aind (v, args, s_uniform_vector_ref);
|
||
v = SCM_ARRAY_V (v);
|
||
}
|
||
else
|
||
{
|
||
if (SCM_NIMP (args))
|
||
|
||
{
|
||
SCM_ASSERT (SCM_CONSP (args) && SCM_INUMP (SCM_CAR (args)), args, SCM_ARG2, s_uniform_vector_ref);
|
||
pos = SCM_INUM (SCM_CAR (args));
|
||
SCM_ASRTGO (SCM_NULLP (SCM_CDR (args)), wna);
|
||
}
|
||
else
|
||
{
|
||
SCM_ASSERT (SCM_INUMP (args), args, SCM_ARG2, s_uniform_vector_ref);
|
||
pos = SCM_INUM (args);
|
||
}
|
||
SCM_ASRTGO (pos >= 0 && pos < SCM_LENGTH (v), outrng);
|
||
}
|
||
switch SCM_TYP7
|
||
(v)
|
||
{
|
||
default:
|
||
if (SCM_NULLP (args))
|
||
return v;
|
||
badarg:
|
||
scm_wta (v, (char *) SCM_ARG1, s_uniform_vector_ref);
|
||
abort ();
|
||
outrng:scm_out_of_range (s_uniform_vector_ref, SCM_MAKINUM (pos));
|
||
wna: scm_wrong_num_args (scm_makfrom0str (s_uniform_vector_ref));
|
||
case scm_tc7_smob:
|
||
{ /* enclosed */
|
||
int k = SCM_ARRAY_NDIM (v);
|
||
SCM res = scm_make_ra (k);
|
||
SCM_ARRAY_V (res) = SCM_ARRAY_V (v);
|
||
SCM_ARRAY_BASE (res) = pos;
|
||
while (k--)
|
||
{
|
||
SCM_ARRAY_DIMS (res)[k].lbnd = SCM_ARRAY_DIMS (v)[k].lbnd;
|
||
SCM_ARRAY_DIMS (res)[k].ubnd = SCM_ARRAY_DIMS (v)[k].ubnd;
|
||
SCM_ARRAY_DIMS (res)[k].inc = SCM_ARRAY_DIMS (v)[k].inc;
|
||
}
|
||
return res;
|
||
}
|
||
case scm_tc7_bvect:
|
||
if (SCM_VELTS (v)[pos / SCM_LONG_BIT] & (1L << (pos % SCM_LONG_BIT)))
|
||
return SCM_BOOL_T;
|
||
else
|
||
return SCM_BOOL_F;
|
||
case scm_tc7_string:
|
||
return SCM_MAKICHR (SCM_CHARS (v)[pos]);
|
||
case scm_tc7_byvect:
|
||
return SCM_MAKINUM (((char *)SCM_CHARS (v))[pos]);
|
||
# ifdef SCM_INUMS_ONLY
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
return SCM_MAKINUM (SCM_VELTS (v)[pos]);
|
||
# else
|
||
case scm_tc7_uvect:
|
||
return scm_ulong2num(SCM_VELTS(v)[pos]);
|
||
case scm_tc7_ivect:
|
||
return scm_long2num(SCM_VELTS(v)[pos]);
|
||
# endif
|
||
|
||
case scm_tc7_svect:
|
||
return SCM_MAKINUM (((short *) SCM_CDR (v))[pos]);
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
return scm_long_long2num (((long_long *) SCM_CDR (v))[pos]);
|
||
#endif
|
||
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
return scm_makflo (((float *) SCM_CDR (v))[pos]);
|
||
#endif
|
||
case scm_tc7_dvect:
|
||
return scm_makdbl (((double *) SCM_CDR (v))[pos], 0.0);
|
||
case scm_tc7_cvect:
|
||
return scm_makdbl (((double *) SCM_CDR (v))[2 * pos],
|
||
((double *) SCM_CDR (v))[2 * pos + 1]);
|
||
#endif
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
return SCM_VELTS (v)[pos];
|
||
}
|
||
}
|
||
|
||
/* Internal version of scm_uniform_vector_ref for uves that does no error checking and
|
||
tries to recycle conses. (Make *sure* you want them recycled.) */
|
||
|
||
SCM
|
||
scm_cvref (v, pos, last)
|
||
SCM v;
|
||
scm_sizet pos;
|
||
SCM last;
|
||
{
|
||
switch SCM_TYP7
|
||
(v)
|
||
{
|
||
default:
|
||
scm_wta (v, (char *) SCM_ARG1, "PROGRAMMING ERROR: scm_cvref");
|
||
case scm_tc7_bvect:
|
||
if (SCM_VELTS (v)[pos / SCM_LONG_BIT] & (1L << (pos % SCM_LONG_BIT)))
|
||
return SCM_BOOL_T;
|
||
else
|
||
return SCM_BOOL_F;
|
||
case scm_tc7_string:
|
||
return SCM_MAKICHR (SCM_CHARS (v)[pos]);
|
||
case scm_tc7_byvect:
|
||
return SCM_MAKINUM (((char *)SCM_CHARS (v))[pos]);
|
||
# ifdef SCM_INUMS_ONLY
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
return SCM_MAKINUM (SCM_VELTS (v)[pos]);
|
||
# else
|
||
case scm_tc7_uvect:
|
||
return scm_ulong2num(SCM_VELTS(v)[pos]);
|
||
case scm_tc7_ivect:
|
||
return scm_long2num(SCM_VELTS(v)[pos]);
|
||
# endif
|
||
case scm_tc7_svect:
|
||
return SCM_MAKINUM (((short *) SCM_CDR (v))[pos]);
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
return scm_long_long2num (((long_long *) SCM_CDR (v))[pos]);
|
||
#endif
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
if (SCM_NIMP (last) && (last != scm_flo0) && (scm_tc_flo == SCM_CAR (last)))
|
||
{
|
||
SCM_FLO (last) = ((float *) SCM_CDR (v))[pos];
|
||
return last;
|
||
}
|
||
return scm_makflo (((float *) SCM_CDR (v))[pos]);
|
||
#endif
|
||
case scm_tc7_dvect:
|
||
#ifdef SCM_SINGLES
|
||
if (SCM_NIMP (last) && scm_tc_dblr == SCM_CAR (last))
|
||
#else
|
||
if (SCM_NIMP (last) && (last != scm_flo0) && (scm_tc_dblr == SCM_CAR (last)))
|
||
#endif
|
||
{
|
||
SCM_REAL (last) = ((double *) SCM_CDR (v))[pos];
|
||
return last;
|
||
}
|
||
return scm_makdbl (((double *) SCM_CDR (v))[pos], 0.0);
|
||
case scm_tc7_cvect:
|
||
if (SCM_NIMP (last) && scm_tc_dblc == SCM_CAR (last))
|
||
{
|
||
SCM_REAL (last) = ((double *) SCM_CDR (v))[2 * pos];
|
||
SCM_IMAG (last) = ((double *) SCM_CDR (v))[2 * pos + 1];
|
||
return last;
|
||
}
|
||
return scm_makdbl (((double *) SCM_CDR (v))[2 * pos],
|
||
((double *) SCM_CDR (v))[2 * pos + 1]);
|
||
#endif
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
return SCM_VELTS (v)[pos];
|
||
case scm_tc7_smob:
|
||
{ /* enclosed scm_array */
|
||
int k = SCM_ARRAY_NDIM (v);
|
||
SCM res = scm_make_ra (k);
|
||
SCM_ARRAY_V (res) = SCM_ARRAY_V (v);
|
||
SCM_ARRAY_BASE (res) = pos;
|
||
while (k--)
|
||
{
|
||
SCM_ARRAY_DIMS (res)[k].ubnd = SCM_ARRAY_DIMS (v)[k].ubnd;
|
||
SCM_ARRAY_DIMS (res)[k].lbnd = SCM_ARRAY_DIMS (v)[k].lbnd;
|
||
SCM_ARRAY_DIMS (res)[k].inc = SCM_ARRAY_DIMS (v)[k].inc;
|
||
}
|
||
return res;
|
||
}
|
||
}
|
||
}
|
||
|
||
SCM_PROC(s_uniform_array_set1_x, "uniform-array-set1!", 3, 0, 0, scm_array_set_x);
|
||
SCM_PROC(s_array_set_x, "array-set!", 2, 0, 1, scm_array_set_x);
|
||
|
||
/* Note that args may be a list or an immediate object, depending which
|
||
PROC is used (and it's called from C too). */
|
||
SCM
|
||
scm_array_set_x (v, obj, args)
|
||
SCM v;
|
||
SCM obj;
|
||
SCM args;
|
||
{
|
||
long pos;
|
||
SCM_ASRTGO (SCM_NIMP (v), badarg1);
|
||
if (SCM_ARRAYP (v))
|
||
{
|
||
pos = scm_aind (v, args, s_array_set_x);
|
||
v = SCM_ARRAY_V (v);
|
||
}
|
||
else
|
||
{
|
||
if (SCM_NIMP (args))
|
||
{
|
||
SCM_ASSERT (SCM_CONSP(args) && SCM_INUMP (SCM_CAR (args)), args,
|
||
SCM_ARG3, s_array_set_x);
|
||
SCM_ASRTGO (SCM_NULLP (SCM_CDR (args)), wna);
|
||
pos = SCM_INUM (SCM_CAR (args));
|
||
}
|
||
else
|
||
{
|
||
SCM_ASSERT (SCM_INUMP (args), args, SCM_ARG3, s_array_set_x);
|
||
pos = SCM_INUM (args);
|
||
}
|
||
SCM_ASRTGO (pos >= 0 && pos < SCM_LENGTH (v), outrng);
|
||
}
|
||
switch (SCM_TYP7 (v))
|
||
{
|
||
default: badarg1:
|
||
scm_wta (v, (char *) SCM_ARG1, s_array_set_x);
|
||
abort ();
|
||
outrng:scm_out_of_range (s_array_set_x, SCM_MAKINUM (pos));
|
||
wna: scm_wrong_num_args (scm_makfrom0str (s_array_set_x));
|
||
case scm_tc7_smob: /* enclosed */
|
||
goto badarg1;
|
||
case scm_tc7_bvect:
|
||
if (SCM_BOOL_F == obj)
|
||
SCM_VELTS (v)[pos / SCM_LONG_BIT] &= ~(1L << (pos % SCM_LONG_BIT));
|
||
else if (SCM_BOOL_T == obj)
|
||
SCM_VELTS (v)[pos / SCM_LONG_BIT] |= (1L << (pos % SCM_LONG_BIT));
|
||
else
|
||
badobj:scm_wta (obj, (char *) SCM_ARG2, s_array_set_x);
|
||
break;
|
||
case scm_tc7_string:
|
||
SCM_ASRTGO (SCM_ICHRP (obj), badobj);
|
||
SCM_CHARS (v)[pos] = SCM_ICHR (obj);
|
||
break;
|
||
case scm_tc7_byvect:
|
||
if (SCM_ICHRP (obj))
|
||
obj = SCM_MAKINUM ((char) SCM_ICHR (obj));
|
||
SCM_ASRTGO (SCM_INUMP (obj), badobj);
|
||
((char *)SCM_CHARS (v))[pos] = SCM_INUM (obj);
|
||
break;
|
||
# ifdef SCM_INUMS_ONLY
|
||
case scm_tc7_uvect:
|
||
SCM_ASRTGO (SCM_INUM (obj) >= 0, badobj);
|
||
case scm_tc7_ivect:
|
||
SCM_ASRTGO(SCM_INUMP(obj), badobj); SCM_VELTS(v)[pos] = SCM_INUM(obj); break;
|
||
# else
|
||
case scm_tc7_uvect:
|
||
SCM_VELTS(v)[pos] = scm_num2ulong(obj, (char *)SCM_ARG2, s_array_set_x); break;
|
||
case scm_tc7_ivect:
|
||
SCM_VELTS(v)[pos] = num2long(obj, (char *)SCM_ARG2, s_array_set_x); break;
|
||
# endif
|
||
break;
|
||
|
||
case scm_tc7_svect:
|
||
SCM_ASRTGO (SCM_INUMP (obj), badobj);
|
||
((short *) SCM_CDR (v))[pos] = SCM_INUM (obj);
|
||
break;
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
((long_long *) SCM_CDR (v))[pos] = scm_num2long_long (obj, (char *)SCM_ARG2, s_array_set_x);
|
||
break;
|
||
#endif
|
||
|
||
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
SCM_ASRTGO (SCM_NIMP (obj) && SCM_REALP (obj), badobj);
|
||
((float *) SCM_CDR (v))[pos] = SCM_REALPART (obj);
|
||
break;
|
||
#endif
|
||
case scm_tc7_dvect:
|
||
SCM_ASRTGO (SCM_NIMP (obj) && SCM_REALP (obj), badobj);
|
||
((double *) SCM_CDR (v))[pos] = SCM_REALPART (obj);
|
||
break;
|
||
case scm_tc7_cvect:
|
||
SCM_ASRTGO (SCM_NIMP (obj) && SCM_INEXP (obj), badobj);
|
||
((double *) SCM_CDR (v))[2 * pos] = SCM_REALPART (obj);
|
||
((double *) SCM_CDR (v))[2 * pos + 1] = SCM_CPLXP (obj) ? SCM_IMAG (obj) : 0.0;
|
||
break;
|
||
#endif
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
SCM_VELTS (v)[pos] = obj;
|
||
break;
|
||
}
|
||
return SCM_UNSPECIFIED;
|
||
}
|
||
|
||
SCM_PROC(s_array_contents, "array-contents", 1, 1, 0, scm_array_contents);
|
||
|
||
SCM
|
||
scm_array_contents (ra, strict)
|
||
SCM ra;
|
||
SCM strict;
|
||
{
|
||
SCM sra;
|
||
if (SCM_IMP (ra))
|
||
return SCM_BOOL_F;
|
||
switch SCM_TYP7
|
||
(ra)
|
||
{
|
||
default:
|
||
return SCM_BOOL_F;
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
case scm_tc7_string:
|
||
case scm_tc7_bvect:
|
||
case scm_tc7_byvect:
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
case scm_tc7_fvect:
|
||
case scm_tc7_dvect:
|
||
case scm_tc7_cvect:
|
||
case scm_tc7_svect:
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
#endif
|
||
return ra;
|
||
case scm_tc7_smob:
|
||
{
|
||
scm_sizet k, ndim = SCM_ARRAY_NDIM (ra), len = 1;
|
||
if (!SCM_ARRAYP (ra) || !SCM_ARRAY_CONTP (ra))
|
||
return SCM_BOOL_F;
|
||
for (k = 0; k < ndim; k++)
|
||
len *= SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1;
|
||
if (!SCM_UNBNDP (strict))
|
||
{
|
||
if SCM_ARRAY_BASE
|
||
(ra) return SCM_BOOL_F;
|
||
if (ndim && (1 != SCM_ARRAY_DIMS (ra)[ndim - 1].inc))
|
||
return SCM_BOOL_F;
|
||
if (scm_tc7_bvect == SCM_TYP7 (SCM_ARRAY_V (ra)))
|
||
{
|
||
if (len != SCM_LENGTH (SCM_ARRAY_V (ra)) ||
|
||
SCM_ARRAY_BASE (ra) % SCM_LONG_BIT ||
|
||
len % SCM_LONG_BIT)
|
||
return SCM_BOOL_F;
|
||
}
|
||
}
|
||
if ((len == SCM_LENGTH (SCM_ARRAY_V (ra))) && 0 == SCM_ARRAY_BASE (ra) && SCM_ARRAY_DIMS (ra)->inc)
|
||
return SCM_ARRAY_V (ra);
|
||
sra = scm_make_ra (1);
|
||
SCM_ARRAY_DIMS (sra)->lbnd = 0;
|
||
SCM_ARRAY_DIMS (sra)->ubnd = len - 1;
|
||
SCM_ARRAY_V (sra) = SCM_ARRAY_V (ra);
|
||
SCM_ARRAY_BASE (sra) = SCM_ARRAY_BASE (ra);
|
||
SCM_ARRAY_DIMS (sra)->inc = (ndim ? SCM_ARRAY_DIMS (ra)[ndim - 1].inc : 1);
|
||
return sra;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
SCM
|
||
scm_ra2contig (ra, copy)
|
||
SCM ra;
|
||
int copy;
|
||
{
|
||
SCM ret;
|
||
long inc = 1;
|
||
scm_sizet k, len = 1;
|
||
for (k = SCM_ARRAY_NDIM (ra); k--;)
|
||
len *= SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1;
|
||
k = SCM_ARRAY_NDIM (ra);
|
||
if (SCM_ARRAY_CONTP (ra) && ((0 == k) || (1 == SCM_ARRAY_DIMS (ra)[k - 1].inc)))
|
||
{
|
||
if (scm_tc7_bvect != SCM_TYP7 (ra))
|
||
return ra;
|
||
if ((len == SCM_LENGTH (SCM_ARRAY_V (ra)) &&
|
||
0 == SCM_ARRAY_BASE (ra) % SCM_LONG_BIT &&
|
||
0 == len % SCM_LONG_BIT))
|
||
return ra;
|
||
}
|
||
ret = scm_make_ra (k);
|
||
SCM_ARRAY_BASE (ret) = 0;
|
||
while (k--)
|
||
{
|
||
SCM_ARRAY_DIMS (ret)[k].lbnd = SCM_ARRAY_DIMS (ra)[k].lbnd;
|
||
SCM_ARRAY_DIMS (ret)[k].ubnd = SCM_ARRAY_DIMS (ra)[k].ubnd;
|
||
SCM_ARRAY_DIMS (ret)[k].inc = inc;
|
||
inc *= SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1;
|
||
}
|
||
SCM_ARRAY_V (ret) = scm_make_uve ((inc - 1), scm_array_prototype (ra));
|
||
if (copy)
|
||
scm_array_copy_x (ra, ret);
|
||
return ret;
|
||
}
|
||
|
||
|
||
|
||
SCM_PROC(s_uniform_array_read_x, "uniform-array-read!", 1, 3, 0, scm_uniform_array_read_x);
|
||
|
||
SCM
|
||
scm_uniform_array_read_x (ra, port_or_fd, start, end)
|
||
SCM ra;
|
||
SCM port_or_fd;
|
||
SCM start;
|
||
SCM end;
|
||
{
|
||
SCM cra = SCM_UNDEFINED, v = ra;
|
||
long sz, vlen, ans;
|
||
long cstart = 0;
|
||
long cend;
|
||
long offset = 0;
|
||
|
||
SCM_ASRTGO (SCM_NIMP (v), badarg1);
|
||
if (SCM_UNBNDP (port_or_fd))
|
||
port_or_fd = scm_cur_inp;
|
||
else
|
||
SCM_ASSERT (SCM_INUMP (port_or_fd)
|
||
|| (SCM_NIMP (port_or_fd) && SCM_OPINFPORTP (port_or_fd)),
|
||
port_or_fd, SCM_ARG2, s_uniform_array_read_x);
|
||
vlen = SCM_LENGTH (v);
|
||
|
||
loop:
|
||
switch SCM_TYP7 (v)
|
||
{
|
||
default:
|
||
badarg1:scm_wta (v, (char *) SCM_ARG1, s_uniform_array_read_x);
|
||
case scm_tc7_smob:
|
||
SCM_ASRTGO (SCM_ARRAYP (v), badarg1);
|
||
cra = scm_ra2contig (ra, 0);
|
||
cstart += SCM_ARRAY_BASE (cra);
|
||
vlen = SCM_ARRAY_DIMS (cra)->inc *
|
||
(SCM_ARRAY_DIMS (cra)->ubnd - SCM_ARRAY_DIMS (cra)->lbnd + 1);
|
||
v = SCM_ARRAY_V (cra);
|
||
goto loop;
|
||
case scm_tc7_string:
|
||
case scm_tc7_byvect:
|
||
sz = sizeof (char);
|
||
break;
|
||
case scm_tc7_bvect:
|
||
vlen = (vlen + SCM_LONG_BIT - 1) / SCM_LONG_BIT;
|
||
cstart /= SCM_LONG_BIT;
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
sz = sizeof (long);
|
||
break;
|
||
case scm_tc7_svect:
|
||
sz = sizeof (short);
|
||
break;
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
sz = sizeof (long_long);
|
||
break;
|
||
#endif
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
sz = sizeof (float);
|
||
break;
|
||
#endif
|
||
case scm_tc7_dvect:
|
||
sz = sizeof (double);
|
||
break;
|
||
case scm_tc7_cvect:
|
||
sz = 2 * sizeof (double);
|
||
break;
|
||
#endif
|
||
}
|
||
|
||
cend = vlen;
|
||
if (!SCM_UNBNDP (start))
|
||
{
|
||
offset =
|
||
scm_num2long (start, (char *) SCM_ARG3, s_uniform_array_read_x);
|
||
|
||
if (offset < 0 || offset >= cend)
|
||
scm_out_of_range (s_uniform_array_read_x, start);
|
||
|
||
if (!SCM_UNBNDP (end))
|
||
{
|
||
long tend =
|
||
scm_num2long (end, (char *) SCM_ARG4, s_uniform_array_read_x);
|
||
|
||
if (tend <= offset || tend > cend)
|
||
scm_out_of_range (s_uniform_array_read_x, end);
|
||
cend = tend;
|
||
}
|
||
}
|
||
|
||
if (SCM_NIMP (port_or_fd))
|
||
{
|
||
/* if we have stored a character from the port in our own buffer,
|
||
push it back onto the stream. */
|
||
/* An ungetc before an fread will not work on some systems if
|
||
setbuf(0). do #define NOSETBUF in scmfig.h to fix this. */
|
||
if (SCM_CRDYP (port_or_fd))
|
||
{
|
||
ungetc (SCM_CGETUN (port_or_fd), (FILE *)SCM_STREAM (port_or_fd));
|
||
SCM_CLRDY (port_or_fd); /* Clear ungetted char */
|
||
}
|
||
SCM_SYSCALL (ans = fread (SCM_CHARS (v) + (cstart + offset) * sz,
|
||
(scm_sizet) sz, (scm_sizet) (cend - offset),
|
||
(FILE *)SCM_STREAM (port_or_fd)));
|
||
}
|
||
else /* file descriptor. */
|
||
{
|
||
SCM_SYSCALL (ans = read (SCM_INUM (port_or_fd),
|
||
SCM_CHARS (v) + (cstart + offset) * sz,
|
||
(scm_sizet) (sz * (cend - offset))));
|
||
if (ans == -1)
|
||
scm_syserror (s_uniform_array_read_x);
|
||
}
|
||
if (SCM_TYP7 (v) == scm_tc7_bvect)
|
||
ans *= SCM_LONG_BIT;
|
||
|
||
if (v != ra && cra != ra)
|
||
scm_array_copy_x (cra, ra);
|
||
|
||
return SCM_MAKINUM (ans);
|
||
}
|
||
|
||
SCM_PROC(s_uniform_array_write, "uniform-array-write", 1, 3, 0, scm_uniform_array_write);
|
||
|
||
SCM
|
||
scm_uniform_array_write (v, port_or_fd, start, end)
|
||
SCM v;
|
||
SCM port_or_fd;
|
||
SCM start;
|
||
SCM end;
|
||
{
|
||
long sz, vlen, ans;
|
||
long offset = 0;
|
||
long cstart = 0;
|
||
long cend;
|
||
|
||
SCM_ASRTGO (SCM_NIMP (v), badarg1);
|
||
if (SCM_UNBNDP (port_or_fd))
|
||
port_or_fd = scm_cur_outp;
|
||
else
|
||
SCM_ASSERT (SCM_INUMP (port_or_fd)
|
||
|| (SCM_NIMP (port_or_fd) && SCM_OPOUTFPORTP (port_or_fd)),
|
||
port_or_fd, SCM_ARG2, s_uniform_array_write);
|
||
vlen = SCM_LENGTH (v);
|
||
|
||
loop:
|
||
switch SCM_TYP7 (v)
|
||
{
|
||
default:
|
||
badarg1:scm_wta (v, (char *) SCM_ARG1, s_uniform_array_write);
|
||
case scm_tc7_smob:
|
||
SCM_ASRTGO (SCM_ARRAYP (v), badarg1);
|
||
v = scm_ra2contig (v, 1);
|
||
cstart = SCM_ARRAY_BASE (v);
|
||
vlen = SCM_ARRAY_DIMS (v)->inc
|
||
* (SCM_ARRAY_DIMS (v)->ubnd - SCM_ARRAY_DIMS (v)->lbnd + 1);
|
||
v = SCM_ARRAY_V (v);
|
||
goto loop;
|
||
case scm_tc7_string:
|
||
case scm_tc7_byvect:
|
||
sz = sizeof (char);
|
||
break;
|
||
case scm_tc7_bvect:
|
||
vlen = (vlen + SCM_LONG_BIT - 1) / SCM_LONG_BIT;
|
||
cstart /= SCM_LONG_BIT;
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
sz = sizeof (long);
|
||
break;
|
||
case scm_tc7_svect:
|
||
sz = sizeof (short);
|
||
break;
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
sz = sizeof (long_long);
|
||
break;
|
||
#endif
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
sz = sizeof (float);
|
||
break;
|
||
#endif
|
||
case scm_tc7_dvect:
|
||
sz = sizeof (double);
|
||
break;
|
||
case scm_tc7_cvect:
|
||
sz = 2 * sizeof (double);
|
||
break;
|
||
#endif
|
||
}
|
||
|
||
cend = vlen;
|
||
if (!SCM_UNBNDP (start))
|
||
{
|
||
offset =
|
||
scm_num2long (start, (char *) SCM_ARG3, s_uniform_array_write);
|
||
|
||
if (offset < 0 || offset >= cend)
|
||
scm_out_of_range (s_uniform_array_write, start);
|
||
|
||
if (!SCM_UNBNDP (end))
|
||
{
|
||
long tend =
|
||
scm_num2long (end, (char *) SCM_ARG4, s_uniform_array_write);
|
||
|
||
if (tend <= offset || tend > cend)
|
||
scm_out_of_range (s_uniform_array_write, end);
|
||
cend = tend;
|
||
}
|
||
}
|
||
|
||
if (SCM_NIMP (port_or_fd))
|
||
{
|
||
SCM_SYSCALL (ans = fwrite (SCM_CHARS (v) + (cstart + offset) * sz,
|
||
(scm_sizet) sz, (scm_sizet) (cend - offset),
|
||
(FILE *)SCM_STREAM (port_or_fd)));
|
||
}
|
||
else /* file descriptor. */
|
||
{
|
||
SCM_SYSCALL (ans = write (SCM_INUM (port_or_fd),
|
||
SCM_CHARS (v) + (cstart + offset) * sz,
|
||
(scm_sizet) (sz * (cend - offset))));
|
||
if (ans == -1)
|
||
scm_syserror (s_uniform_array_write);
|
||
}
|
||
if (SCM_TYP7 (v) == scm_tc7_bvect)
|
||
ans *= SCM_LONG_BIT;
|
||
|
||
return SCM_MAKINUM (ans);
|
||
}
|
||
|
||
|
||
static char cnt_tab[16] =
|
||
{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
|
||
|
||
SCM_PROC(s_bit_count, "bit-count", 2, 0, 0, scm_bit_count);
|
||
|
||
SCM
|
||
scm_bit_count (item, seq)
|
||
SCM item;
|
||
SCM seq;
|
||
{
|
||
long i;
|
||
register unsigned long cnt = 0, w;
|
||
SCM_ASSERT (SCM_NIMP (seq), seq, SCM_ARG2, s_bit_count);
|
||
switch SCM_TYP7
|
||
(seq)
|
||
{
|
||
default:
|
||
scm_wta (seq, (char *) SCM_ARG2, s_bit_count);
|
||
case scm_tc7_bvect:
|
||
if (0 == SCM_LENGTH (seq))
|
||
return SCM_INUM0;
|
||
i = (SCM_LENGTH (seq) - 1) / SCM_LONG_BIT;
|
||
w = SCM_VELTS (seq)[i];
|
||
if (SCM_FALSEP (item))
|
||
w = ~w;
|
||
w <<= SCM_LONG_BIT - 1 - ((SCM_LENGTH (seq) - 1) % SCM_LONG_BIT);
|
||
while (!0)
|
||
{
|
||
for (; w; w >>= 4)
|
||
cnt += cnt_tab[w & 0x0f];
|
||
if (0 == i--)
|
||
return SCM_MAKINUM (cnt);
|
||
w = SCM_VELTS (seq)[i];
|
||
if (SCM_FALSEP (item))
|
||
w = ~w;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
SCM_PROC(s_bit_position, "bit-position", 3, 0, 0, scm_bit_position);
|
||
|
||
SCM
|
||
scm_bit_position (item, v, k)
|
||
SCM item;
|
||
SCM v;
|
||
SCM k;
|
||
{
|
||
long i, lenw, xbits, pos = SCM_INUM (k);
|
||
register unsigned long w;
|
||
SCM_ASSERT (SCM_NIMP (v), v, SCM_ARG2, s_bit_position);
|
||
SCM_ASSERT (SCM_INUMP (k), k, SCM_ARG3, s_bit_position);
|
||
SCM_ASSERT ((pos <= SCM_LENGTH (v)) && (pos >= 0),
|
||
k, SCM_OUTOFRANGE, s_bit_position);
|
||
if (pos == SCM_LENGTH (v))
|
||
return SCM_BOOL_F;
|
||
switch SCM_TYP7
|
||
(v)
|
||
{
|
||
default:
|
||
scm_wta (v, (char *) SCM_ARG2, s_bit_position);
|
||
case scm_tc7_bvect:
|
||
if (0 == SCM_LENGTH (v))
|
||
return SCM_MAKINUM (-1L);
|
||
lenw = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT; /* watch for part words */
|
||
i = pos / SCM_LONG_BIT;
|
||
w = SCM_VELTS (v)[i];
|
||
if (SCM_FALSEP (item))
|
||
w = ~w;
|
||
xbits = (pos % SCM_LONG_BIT);
|
||
pos -= xbits;
|
||
w = ((w >> xbits) << xbits);
|
||
xbits = SCM_LONG_BIT - 1 - (SCM_LENGTH (v) - 1) % SCM_LONG_BIT;
|
||
while (!0)
|
||
{
|
||
if (w && (i == lenw))
|
||
w = ((w << xbits) >> xbits);
|
||
if (w)
|
||
while (w)
|
||
switch (w & 0x0f)
|
||
{
|
||
default:
|
||
return SCM_MAKINUM (pos);
|
||
case 2:
|
||
case 6:
|
||
case 10:
|
||
case 14:
|
||
return SCM_MAKINUM (pos + 1);
|
||
case 4:
|
||
case 12:
|
||
return SCM_MAKINUM (pos + 2);
|
||
case 8:
|
||
return SCM_MAKINUM (pos + 3);
|
||
case 0:
|
||
pos += 4;
|
||
w >>= 4;
|
||
}
|
||
if (++i > lenw)
|
||
break;
|
||
pos += SCM_LONG_BIT;
|
||
w = SCM_VELTS (v)[i];
|
||
if (SCM_FALSEP (item))
|
||
w = ~w;
|
||
}
|
||
return SCM_BOOL_F;
|
||
}
|
||
}
|
||
|
||
|
||
SCM_PROC(s_bit_set_star_x, "bit-set*!", 3, 0, 0, scm_bit_set_star_x);
|
||
|
||
SCM
|
||
scm_bit_set_star_x (v, kv, obj)
|
||
SCM v;
|
||
SCM kv;
|
||
SCM obj;
|
||
{
|
||
register long i, k, vlen;
|
||
SCM_ASRTGO (SCM_NIMP (v), badarg1);
|
||
SCM_ASRTGO (SCM_NIMP (kv), badarg2);
|
||
switch SCM_TYP7
|
||
(kv)
|
||
{
|
||
default:
|
||
badarg2:scm_wta (kv, (char *) SCM_ARG2, s_bit_set_star_x);
|
||
case scm_tc7_uvect:
|
||
switch SCM_TYP7
|
||
(v)
|
||
{
|
||
default:
|
||
badarg1:scm_wta (v, (char *) SCM_ARG1, s_bit_set_star_x);
|
||
case scm_tc7_bvect:
|
||
vlen = SCM_LENGTH (v);
|
||
if (SCM_BOOL_F == obj)
|
||
for (i = SCM_LENGTH (kv); i;)
|
||
{
|
||
k = SCM_VELTS (kv)[--i];
|
||
SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, s_bit_set_star_x);
|
||
SCM_VELTS (v)[k / SCM_LONG_BIT] &= ~(1L << (k % SCM_LONG_BIT));
|
||
}
|
||
else if (SCM_BOOL_T == obj)
|
||
for (i = SCM_LENGTH (kv); i;)
|
||
{
|
||
k = SCM_VELTS (kv)[--i];
|
||
SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, s_bit_set_star_x);
|
||
SCM_VELTS (v)[k / SCM_LONG_BIT] |= (1L << (k % SCM_LONG_BIT));
|
||
}
|
||
else
|
||
badarg3:scm_wta (obj, (char *) SCM_ARG3, s_bit_set_star_x);
|
||
}
|
||
break;
|
||
case scm_tc7_bvect:
|
||
SCM_ASRTGO (SCM_TYP7 (v) == scm_tc7_bvect && SCM_LENGTH (v) == SCM_LENGTH (kv), badarg1);
|
||
if (SCM_BOOL_F == obj)
|
||
for (k = (SCM_LENGTH (v) + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k--;)
|
||
SCM_VELTS (v)[k] &= ~(SCM_VELTS (kv)[k]);
|
||
else if (SCM_BOOL_T == obj)
|
||
for (k = (SCM_LENGTH (v) + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k--;)
|
||
SCM_VELTS (v)[k] |= SCM_VELTS (kv)[k];
|
||
else
|
||
goto badarg3;
|
||
break;
|
||
}
|
||
return SCM_UNSPECIFIED;
|
||
}
|
||
|
||
|
||
SCM_PROC(s_bit_count_star, "bit-count*", 3, 0, 0, scm_bit_count_star);
|
||
|
||
SCM
|
||
scm_bit_count_star (v, kv, obj)
|
||
SCM v;
|
||
SCM kv;
|
||
SCM obj;
|
||
{
|
||
register long i, vlen, count = 0;
|
||
register unsigned long k;
|
||
SCM_ASRTGO (SCM_NIMP (v), badarg1);
|
||
SCM_ASRTGO (SCM_NIMP (kv), badarg2);
|
||
switch SCM_TYP7
|
||
(kv)
|
||
{
|
||
default:
|
||
badarg2:scm_wta (kv, (char *) SCM_ARG2, s_bit_count_star);
|
||
case scm_tc7_uvect:
|
||
switch SCM_TYP7
|
||
(v)
|
||
{
|
||
default:
|
||
badarg1:scm_wta (v, (char *) SCM_ARG1, s_bit_count_star);
|
||
case scm_tc7_bvect:
|
||
vlen = SCM_LENGTH (v);
|
||
if (SCM_BOOL_F == obj)
|
||
for (i = SCM_LENGTH (kv); i;)
|
||
{
|
||
k = SCM_VELTS (kv)[--i];
|
||
SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, s_bit_count_star);
|
||
if (!(SCM_VELTS (v)[k / SCM_LONG_BIT] & (1L << (k % SCM_LONG_BIT))))
|
||
count++;
|
||
}
|
||
else if (SCM_BOOL_T == obj)
|
||
for (i = SCM_LENGTH (kv); i;)
|
||
{
|
||
k = SCM_VELTS (kv)[--i];
|
||
SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, s_bit_count_star);
|
||
if (SCM_VELTS (v)[k / SCM_LONG_BIT] & (1L << (k % SCM_LONG_BIT)))
|
||
count++;
|
||
}
|
||
else
|
||
badarg3:scm_wta (obj, (char *) SCM_ARG3, s_bit_count_star);
|
||
}
|
||
break;
|
||
case scm_tc7_bvect:
|
||
SCM_ASRTGO (SCM_TYP7 (v) == scm_tc7_bvect && SCM_LENGTH (v) == SCM_LENGTH (kv), badarg1);
|
||
if (0 == SCM_LENGTH (v))
|
||
return SCM_INUM0;
|
||
SCM_ASRTGO (SCM_BOOL_T == obj || SCM_BOOL_F == obj, badarg3);
|
||
obj = (SCM_BOOL_T == obj);
|
||
i = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT;
|
||
k = SCM_VELTS (kv)[i] & (obj ? SCM_VELTS (v)[i] : ~SCM_VELTS (v)[i]);
|
||
k <<= SCM_LONG_BIT - 1 - ((SCM_LENGTH (v) - 1) % SCM_LONG_BIT);
|
||
while (!0)
|
||
{
|
||
for (; k; k >>= 4)
|
||
count += cnt_tab[k & 0x0f];
|
||
if (0 == i--)
|
||
return SCM_MAKINUM (count);
|
||
k = SCM_VELTS (kv)[i] & (obj ? SCM_VELTS (v)[i] : ~SCM_VELTS (v)[i]);
|
||
}
|
||
}
|
||
return SCM_MAKINUM (count);
|
||
}
|
||
|
||
|
||
SCM_PROC(s_bit_invert_x, "bit-invert!", 1, 0, 0, scm_bit_invert_x);
|
||
|
||
SCM
|
||
scm_bit_invert_x (v)
|
||
SCM v;
|
||
{
|
||
register long k;
|
||
SCM_ASRTGO (SCM_NIMP (v), badarg1);
|
||
k = SCM_LENGTH (v);
|
||
switch SCM_TYP7
|
||
(v)
|
||
{
|
||
case scm_tc7_bvect:
|
||
for (k = (k + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k--;)
|
||
SCM_VELTS (v)[k] = ~SCM_VELTS (v)[k];
|
||
break;
|
||
default:
|
||
badarg1:scm_wta (v, (char *) SCM_ARG1, s_bit_invert_x);
|
||
}
|
||
return SCM_UNSPECIFIED;
|
||
}
|
||
|
||
|
||
SCM
|
||
scm_istr2bve (str, len)
|
||
char *str;
|
||
long len;
|
||
{
|
||
SCM v = scm_make_uve (len, SCM_BOOL_T);
|
||
long *data = (long *) SCM_VELTS (v);
|
||
register unsigned long mask;
|
||
register long k;
|
||
register long j;
|
||
for (k = 0; k < (len + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k++)
|
||
{
|
||
data[k] = 0L;
|
||
j = len - k * SCM_LONG_BIT;
|
||
if (j > SCM_LONG_BIT)
|
||
j = SCM_LONG_BIT;
|
||
for (mask = 1L; j--; mask <<= 1)
|
||
switch (*str++)
|
||
{
|
||
case '0':
|
||
break;
|
||
case '1':
|
||
data[k] |= mask;
|
||
break;
|
||
default:
|
||
return SCM_BOOL_F;
|
||
}
|
||
}
|
||
return v;
|
||
}
|
||
|
||
|
||
|
||
static SCM ra2l SCM_P ((SCM ra, scm_sizet base, scm_sizet k));
|
||
|
||
static SCM
|
||
ra2l (ra, base, k)
|
||
SCM ra;
|
||
scm_sizet base;
|
||
scm_sizet k;
|
||
{
|
||
register SCM res = SCM_EOL;
|
||
register long inc = SCM_ARRAY_DIMS (ra)[k].inc;
|
||
register scm_sizet i;
|
||
if (SCM_ARRAY_DIMS (ra)[k].ubnd < SCM_ARRAY_DIMS (ra)[k].lbnd)
|
||
return SCM_EOL;
|
||
i = base + (1 + SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd) * inc;
|
||
if (k < SCM_ARRAY_NDIM (ra) - 1)
|
||
{
|
||
do
|
||
{
|
||
i -= inc;
|
||
res = scm_cons (ra2l (ra, i, k + 1), res);
|
||
}
|
||
while (i != base);
|
||
}
|
||
else
|
||
do
|
||
{
|
||
i -= inc;
|
||
res = scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra), SCM_MAKINUM (i)), res);
|
||
}
|
||
while (i != base);
|
||
return res;
|
||
}
|
||
|
||
|
||
SCM_PROC(s_array_to_list, "array->list", 1, 0, 0, scm_array_to_list);
|
||
|
||
SCM
|
||
scm_array_to_list (v)
|
||
SCM v;
|
||
{
|
||
SCM res = SCM_EOL;
|
||
register long k;
|
||
SCM_ASRTGO (SCM_NIMP (v), badarg1);
|
||
switch SCM_TYP7
|
||
(v)
|
||
{
|
||
default:
|
||
badarg1:scm_wta (v, (char *) SCM_ARG1, s_array_to_list);
|
||
case scm_tc7_smob:
|
||
SCM_ASRTGO (SCM_ARRAYP (v), badarg1);
|
||
return ra2l (v, SCM_ARRAY_BASE (v), 0);
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
return scm_vector_to_list (v);
|
||
case scm_tc7_string:
|
||
return scm_string_to_list (v);
|
||
case scm_tc7_bvect:
|
||
{
|
||
long *data = (long *) SCM_VELTS (v);
|
||
register unsigned long mask;
|
||
for (k = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT; k > 0; k--)
|
||
for (mask = 1UL << (SCM_LONG_BIT - 1); mask; mask >>= 1)
|
||
res = scm_cons (((long *) data)[k] & mask ? SCM_BOOL_T : SCM_BOOL_F, res);
|
||
for (mask = 1L << ((SCM_LENGTH (v) % SCM_LONG_BIT) - 1); mask; mask >>= 1)
|
||
res = scm_cons (((long *) data)[k] & mask ? SCM_BOOL_T : SCM_BOOL_F, res);
|
||
return res;
|
||
}
|
||
# ifdef SCM_INUMS_ONLY
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
{
|
||
long *data = (long *) SCM_VELTS (v);
|
||
for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
|
||
res = scm_cons (SCM_MAKINUM (data[k]), res);
|
||
return res;
|
||
}
|
||
# else
|
||
case scm_tc7_uvect: {
|
||
long *data = (long *)SCM_VELTS(v);
|
||
for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
|
||
res = scm_cons(scm_ulong2num(data[k]), res);
|
||
return res;
|
||
}
|
||
case scm_tc7_ivect: {
|
||
long *data = (long *)SCM_VELTS(v);
|
||
for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
|
||
res = scm_cons(scm_long2num(data[k]), res);
|
||
return res;
|
||
}
|
||
# endif
|
||
case scm_tc7_svect: {
|
||
short *data;
|
||
data = (short *)SCM_VELTS(v);
|
||
for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
|
||
res = scm_cons(SCM_MAKINUM (data[k]), res);
|
||
return res;
|
||
}
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect: {
|
||
long_long *data;
|
||
data = (long_long *)SCM_VELTS(v);
|
||
for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
|
||
res = scm_cons(scm_long_long2num(data[k]), res);
|
||
return res;
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
{
|
||
float *data = (float *) SCM_VELTS (v);
|
||
for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
|
||
res = scm_cons (scm_makflo (data[k]), res);
|
||
return res;
|
||
}
|
||
#endif /*SCM_SINGLES*/
|
||
case scm_tc7_dvect:
|
||
{
|
||
double *data = (double *) SCM_VELTS (v);
|
||
for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
|
||
res = scm_cons (scm_makdbl (data[k], 0.0), res);
|
||
return res;
|
||
}
|
||
case scm_tc7_cvect:
|
||
{
|
||
double (*data)[2] = (double (*)[2]) SCM_VELTS (v);
|
||
for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
|
||
res = scm_cons (scm_makdbl (data[k][0], data[k][1]), res);
|
||
return res;
|
||
}
|
||
#endif /*SCM_FLOATS*/
|
||
}
|
||
}
|
||
|
||
|
||
static char s_bad_ralst[] = "Bad scm_array contents list";
|
||
|
||
static int l2ra SCM_P ((SCM lst, SCM ra, scm_sizet base, scm_sizet k));
|
||
|
||
SCM_PROC(s_list_to_uniform_array, "list->uniform-array", 3, 0, 0, scm_list_to_uniform_array);
|
||
|
||
SCM
|
||
scm_list_to_uniform_array (ndim, prot, lst)
|
||
SCM ndim;
|
||
SCM prot;
|
||
SCM lst;
|
||
{
|
||
SCM shp = SCM_EOL;
|
||
SCM row = lst;
|
||
SCM ra;
|
||
scm_sizet k;
|
||
long n;
|
||
SCM_ASSERT (SCM_INUMP (ndim), ndim, SCM_ARG1, s_list_to_uniform_array);
|
||
k = SCM_INUM (ndim);
|
||
while (k--)
|
||
{
|
||
n = scm_ilength (row);
|
||
SCM_ASSERT (n >= 0, lst, SCM_ARG3, s_list_to_uniform_array);
|
||
shp = scm_cons (SCM_MAKINUM (n), shp);
|
||
if (SCM_NIMP (row))
|
||
row = SCM_CAR (row);
|
||
}
|
||
ra = scm_dimensions_to_uniform_array (scm_reverse (shp), prot, SCM_EOL);
|
||
if (SCM_NULLP (shp))
|
||
|
||
{
|
||
SCM_ASRTGO (1 == scm_ilength (lst), badlst);
|
||
scm_array_set_x (ra, SCM_CAR (lst), SCM_EOL);
|
||
return ra;
|
||
}
|
||
if (!SCM_ARRAYP (ra))
|
||
{
|
||
for (k = 0; k < SCM_LENGTH (ra); k++, lst = SCM_CDR (lst))
|
||
scm_array_set_x (ra, SCM_CAR (lst), SCM_MAKINUM (k));
|
||
return ra;
|
||
}
|
||
if (l2ra (lst, ra, SCM_ARRAY_BASE (ra), 0))
|
||
return ra;
|
||
else
|
||
badlst:scm_wta (lst, s_bad_ralst, s_list_to_uniform_array);
|
||
return SCM_BOOL_F;
|
||
}
|
||
|
||
static int
|
||
l2ra (lst, ra, base, k)
|
||
SCM lst;
|
||
SCM ra;
|
||
scm_sizet base;
|
||
scm_sizet k;
|
||
{
|
||
register long inc = SCM_ARRAY_DIMS (ra)[k].inc;
|
||
register long n = (1 + SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd);
|
||
int ok = 1;
|
||
if (n <= 0)
|
||
return (SCM_EOL == lst);
|
||
if (k < SCM_ARRAY_NDIM (ra) - 1)
|
||
{
|
||
while (n--)
|
||
{
|
||
if (SCM_IMP (lst) || SCM_NCONSP (lst))
|
||
return 0;
|
||
ok = ok && l2ra (SCM_CAR (lst), ra, base, k + 1);
|
||
base += inc;
|
||
lst = SCM_CDR (lst);
|
||
}
|
||
if (SCM_NNULLP (lst))
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
while (n--)
|
||
{
|
||
if (SCM_IMP (lst) || SCM_NCONSP (lst))
|
||
return 0;
|
||
ok = ok && scm_array_set_x (SCM_ARRAY_V (ra), SCM_CAR (lst), SCM_MAKINUM (base));
|
||
base += inc;
|
||
lst = SCM_CDR (lst);
|
||
}
|
||
if (SCM_NNULLP (lst))
|
||
return 0;
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
|
||
static void rapr1 SCM_P ((SCM ra, scm_sizet j, scm_sizet k, SCM port, scm_print_state *pstate));
|
||
|
||
static void
|
||
rapr1 (ra, j, k, port, pstate)
|
||
SCM ra;
|
||
scm_sizet j;
|
||
scm_sizet k;
|
||
SCM port;
|
||
scm_print_state *pstate;
|
||
{
|
||
long inc = 1;
|
||
long n = SCM_LENGTH (ra);
|
||
int enclosed = 0;
|
||
tail:
|
||
switch SCM_TYP7
|
||
(ra)
|
||
{
|
||
case scm_tc7_smob:
|
||
if (enclosed++)
|
||
{
|
||
SCM_ARRAY_BASE (ra) = j;
|
||
if (n-- > 0)
|
||
scm_iprin1 (ra, port, pstate);
|
||
for (j += inc; n-- > 0; j += inc)
|
||
{
|
||
scm_putc (' ', port);
|
||
SCM_ARRAY_BASE (ra) = j;
|
||
scm_iprin1 (ra, port, pstate);
|
||
}
|
||
break;
|
||
}
|
||
if (k + 1 < SCM_ARRAY_NDIM (ra))
|
||
{
|
||
long i;
|
||
inc = SCM_ARRAY_DIMS (ra)[k].inc;
|
||
for (i = SCM_ARRAY_DIMS (ra)[k].lbnd; i < SCM_ARRAY_DIMS (ra)[k].ubnd; i++)
|
||
{
|
||
scm_putc ('(', port);
|
||
rapr1 (ra, j, k + 1, port, pstate);
|
||
scm_puts (") ", port);
|
||
j += inc;
|
||
}
|
||
if (i == SCM_ARRAY_DIMS (ra)[k].ubnd)
|
||
{ /* could be zero size. */
|
||
scm_putc ('(', port);
|
||
rapr1 (ra, j, k + 1, port, pstate);
|
||
scm_putc (')', port);
|
||
}
|
||
break;
|
||
}
|
||
if SCM_ARRAY_NDIM
|
||
(ra)
|
||
{ /* Could be zero-dimensional */
|
||
inc = SCM_ARRAY_DIMS (ra)[k].inc;
|
||
n = (SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1);
|
||
}
|
||
else
|
||
n = 1;
|
||
ra = SCM_ARRAY_V (ra);
|
||
goto tail;
|
||
default:
|
||
if (n-- > 0)
|
||
scm_iprin1 (scm_uniform_vector_ref (ra, SCM_MAKINUM (j)), port, pstate);
|
||
for (j += inc; n-- > 0; j += inc)
|
||
{
|
||
scm_putc (' ', port);
|
||
scm_iprin1 (scm_cvref (ra, j, SCM_UNDEFINED), port, pstate);
|
||
}
|
||
break;
|
||
case scm_tc7_string:
|
||
if (n-- > 0)
|
||
scm_iprin1 (SCM_MAKICHR (SCM_CHARS (ra)[j]), port, pstate);
|
||
if (SCM_WRITINGP (pstate))
|
||
for (j += inc; n-- > 0; j += inc)
|
||
{
|
||
scm_putc (' ', port);
|
||
scm_iprin1 (SCM_MAKICHR (SCM_CHARS (ra)[j]), port, pstate);
|
||
}
|
||
else
|
||
for (j += inc; n-- > 0; j += inc)
|
||
scm_putc (SCM_CHARS (ra)[j], port);
|
||
break;
|
||
case scm_tc7_byvect:
|
||
if (n-- > 0)
|
||
scm_intprint (((char *)SCM_CDR (ra))[j], 10, port);
|
||
for (j += inc; n-- > 0; j += inc)
|
||
{
|
||
scm_putc (' ', port);
|
||
scm_intprint (((char *)SCM_CDR (ra))[j], 10, port);
|
||
}
|
||
break;
|
||
|
||
case scm_tc7_uvect:
|
||
case scm_tc7_ivect:
|
||
if (n-- > 0)
|
||
scm_intprint (SCM_VELTS (ra)[j], 10, port);
|
||
for (j += inc; n-- > 0; j += inc)
|
||
{
|
||
scm_putc (' ', port);
|
||
scm_intprint (SCM_VELTS (ra)[j], 10, port);
|
||
}
|
||
break;
|
||
|
||
case scm_tc7_svect:
|
||
if (n-- > 0)
|
||
scm_intprint (((short *)SCM_CDR (ra))[j], 10, port);
|
||
for (j += inc; n-- > 0; j += inc)
|
||
{
|
||
scm_putc (' ', port);
|
||
scm_intprint (((short *)SCM_CDR (ra))[j], 10, port);
|
||
}
|
||
break;
|
||
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
if (n-- > 0)
|
||
{
|
||
SCM z = scm_makflo (1.0);
|
||
SCM_FLO (z) = ((float *) SCM_VELTS (ra))[j];
|
||
scm_floprint (z, port, pstate);
|
||
for (j += inc; n-- > 0; j += inc)
|
||
{
|
||
scm_putc (' ', port);
|
||
SCM_FLO (z) = ((float *) SCM_VELTS (ra))[j];
|
||
scm_floprint (z, port, pstate);
|
||
}
|
||
}
|
||
break;
|
||
#endif /*SCM_SINGLES*/
|
||
case scm_tc7_dvect:
|
||
if (n-- > 0)
|
||
{
|
||
SCM z = scm_makdbl (1.0 / 3.0, 0.0);
|
||
SCM_REAL (z) = ((double *) SCM_VELTS (ra))[j];
|
||
scm_floprint (z, port, pstate);
|
||
for (j += inc; n-- > 0; j += inc)
|
||
{
|
||
scm_putc (' ', port);
|
||
SCM_REAL (z) = ((double *) SCM_VELTS (ra))[j];
|
||
scm_floprint (z, port, pstate);
|
||
}
|
||
}
|
||
break;
|
||
case scm_tc7_cvect:
|
||
if (n-- > 0)
|
||
{
|
||
SCM cz = scm_makdbl (0.0, 1.0), z = scm_makdbl (1.0 / 3.0, 0.0);
|
||
SCM_REAL (z) = SCM_REAL (cz) = (((double *) SCM_VELTS (ra))[2 * j]);
|
||
SCM_IMAG (cz) = ((double *) SCM_VELTS (ra))[2 * j + 1];
|
||
scm_floprint ((0.0 == SCM_IMAG (cz) ? z : cz), port, pstate);
|
||
for (j += inc; n-- > 0; j += inc)
|
||
{
|
||
scm_putc (' ', port);
|
||
SCM_REAL (z) = SCM_REAL (cz) = ((double *) SCM_VELTS (ra))[2 * j];
|
||
SCM_IMAG (cz) = ((double *) SCM_VELTS (ra))[2 * j + 1];
|
||
scm_floprint ((0.0 == SCM_IMAG (cz) ? z : cz), port, pstate);
|
||
}
|
||
}
|
||
break;
|
||
#endif /*SCM_FLOATS*/
|
||
}
|
||
}
|
||
|
||
|
||
|
||
int
|
||
scm_raprin1 (exp, port, pstate)
|
||
SCM exp;
|
||
SCM port;
|
||
scm_print_state *pstate;
|
||
{
|
||
SCM v = exp;
|
||
scm_sizet base = 0;
|
||
scm_putc ('#', port);
|
||
tail:
|
||
switch SCM_TYP7
|
||
(v)
|
||
{
|
||
case scm_tc7_smob:
|
||
{
|
||
long ndim = SCM_ARRAY_NDIM (v);
|
||
base = SCM_ARRAY_BASE (v);
|
||
v = SCM_ARRAY_V (v);
|
||
if (SCM_ARRAYP (v))
|
||
|
||
{
|
||
scm_puts ("<enclosed-array ", port);
|
||
rapr1 (exp, base, 0, port, pstate);
|
||
scm_putc ('>', port);
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
scm_intprint (ndim, 10, port);
|
||
goto tail;
|
||
}
|
||
}
|
||
case scm_tc7_bvect:
|
||
if (exp == v)
|
||
{ /* a uve, not an scm_array */
|
||
register long i, j, w;
|
||
scm_putc ('*', port);
|
||
for (i = 0; i < (SCM_LENGTH (exp)) / SCM_LONG_BIT; i++)
|
||
{
|
||
w = SCM_VELTS (exp)[i];
|
||
for (j = SCM_LONG_BIT; j; j--)
|
||
{
|
||
scm_putc (w & 1 ? '1' : '0', port);
|
||
w >>= 1;
|
||
}
|
||
}
|
||
j = SCM_LENGTH (exp) % SCM_LONG_BIT;
|
||
if (j)
|
||
{
|
||
w = SCM_VELTS (exp)[SCM_LENGTH (exp) / SCM_LONG_BIT];
|
||
for (; j; j--)
|
||
{
|
||
scm_putc (w & 1 ? '1' : '0', port);
|
||
w >>= 1;
|
||
}
|
||
}
|
||
return 1;
|
||
}
|
||
else
|
||
scm_putc ('b', port);
|
||
break;
|
||
case scm_tc7_string:
|
||
scm_putc ('a', port);
|
||
break;
|
||
case scm_tc7_byvect:
|
||
scm_puts ("bytes", port);
|
||
break;
|
||
case scm_tc7_uvect:
|
||
scm_putc ('u', port);
|
||
break;
|
||
case scm_tc7_ivect:
|
||
scm_putc ('e', port);
|
||
break;
|
||
case scm_tc7_svect:
|
||
scm_puts ("short", port);
|
||
break;
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
scm_puts ("long_long", port);
|
||
break;
|
||
#endif
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
scm_putc ('s', port);
|
||
break;
|
||
#endif /*SCM_SINGLES*/
|
||
case scm_tc7_dvect:
|
||
scm_putc ('i', port);
|
||
break;
|
||
case scm_tc7_cvect:
|
||
scm_putc ('c', port);
|
||
break;
|
||
#endif /*SCM_FLOATS*/
|
||
}
|
||
scm_putc ('(', port);
|
||
rapr1 (exp, base, 0, port, pstate);
|
||
scm_putc (')', port);
|
||
return 1;
|
||
}
|
||
|
||
SCM_PROC(s_array_prototype, "array-prototype", 1, 0, 0, scm_array_prototype);
|
||
|
||
SCM
|
||
scm_array_prototype (ra)
|
||
SCM ra;
|
||
{
|
||
int enclosed = 0;
|
||
SCM_ASRTGO (SCM_NIMP (ra), badarg);
|
||
loop:
|
||
switch SCM_TYP7
|
||
(ra)
|
||
{
|
||
default:
|
||
badarg:scm_wta (ra, (char *) SCM_ARG1, s_array_prototype);
|
||
case scm_tc7_smob:
|
||
SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
|
||
if (enclosed++)
|
||
return SCM_UNSPECIFIED;
|
||
ra = SCM_ARRAY_V (ra);
|
||
goto loop;
|
||
case scm_tc7_vector:
|
||
case scm_tc7_wvect:
|
||
return SCM_EOL;
|
||
case scm_tc7_bvect:
|
||
return SCM_BOOL_T;
|
||
case scm_tc7_string:
|
||
return SCM_MAKICHR ('a');
|
||
case scm_tc7_byvect:
|
||
return SCM_MAKICHR ('\0');
|
||
case scm_tc7_uvect:
|
||
return SCM_MAKINUM (1L);
|
||
case scm_tc7_ivect:
|
||
return SCM_MAKINUM (-1L);
|
||
case scm_tc7_svect:
|
||
return SCM_CDR (scm_intern ("s", 1));
|
||
#ifdef LONGLONGS
|
||
case scm_tc7_llvect:
|
||
return SCM_CDR (scm_intern ("l", 1));
|
||
#endif
|
||
#ifdef SCM_FLOATS
|
||
#ifdef SCM_SINGLES
|
||
case scm_tc7_fvect:
|
||
return scm_makflo (1.0);
|
||
#endif
|
||
case scm_tc7_dvect:
|
||
return scm_makdbl (1.0 / 3.0, 0.0);
|
||
case scm_tc7_cvect:
|
||
return scm_makdbl (0.0, 1.0);
|
||
#endif
|
||
}
|
||
}
|
||
|
||
|
||
static SCM markra SCM_P ((SCM ptr));
|
||
|
||
static SCM
|
||
markra (ptr)
|
||
SCM ptr;
|
||
{
|
||
if SCM_GC8MARKP
|
||
(ptr) return SCM_BOOL_F;
|
||
SCM_SETGC8MARK (ptr);
|
||
return SCM_ARRAY_V (ptr);
|
||
}
|
||
|
||
|
||
static scm_sizet freera SCM_P ((SCM ptr));
|
||
|
||
static scm_sizet
|
||
freera (ptr)
|
||
SCM ptr;
|
||
{
|
||
scm_must_free (SCM_CHARS (ptr));
|
||
return sizeof (scm_array) + SCM_ARRAY_NDIM (ptr) * sizeof (scm_array_dim);
|
||
}
|
||
|
||
static scm_smobfuns rasmob =
|
||
{markra, freera, scm_raprin1, scm_array_equal_p};
|
||
|
||
|
||
/* This must be done after scm_init_scl() */
|
||
|
||
void
|
||
scm_init_unif ()
|
||
{
|
||
#include "unif.x"
|
||
scm_tc16_array = scm_newsmob (&rasmob);
|
||
scm_add_feature ("array");
|
||
}
|
||
|
||
#else /* ARRAYS */
|
||
|
||
|
||
int
|
||
scm_raprin1 (exp, port, pstate)
|
||
SCM exp;
|
||
SCM port;
|
||
scm_print_state *pstate;
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
|
||
SCM
|
||
scm_istr2bve (str, len)
|
||
char *str;
|
||
long len;
|
||
{
|
||
return SCM_BOOL_F;
|
||
}
|
||
|
||
void
|
||
scm_init_unif ()
|
||
{
|
||
#include "unif.x"
|
||
scm_make_subr (s_resizuve, scm_tc7_subr_2, scm_vector_set_length_x);
|
||
}
|
||
|
||
#endif /* ARRAYS */
|