mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-03 21:30:29 +02:00
newline. A bit faster, and definitely hairier. (scm_read_line): Count newlines here instead. * strings.c (scm_take_str): New function. (scm_take0str): Reimplement in terms of scm_take_str. * strings.h (scm_take_str): New declaration. * ioext.c (scm_read_line): Use scm_take_str, to avoid copying the string. Add some simple-minded support for line buffered ports. * ports.h (SCM_BUFLINE): New flag for ports. * init.c (scm_init_standard_ports): Request line-buffering on the standard output port. * * ports.c (scm_mode_bits): Recognize 'l' as a request for line buffering. (scm_putc, scm_puts, scm_lfwrite): If the port is line-buffered, and there's a newline to be written, flush the port. * ports.c: (scm_lseek): clear buffers even if just reading current position. * fports.c (local_fclose): call local_fflush unconditionally. (various): don't use the scm_must... memory procs. * ports.h (scm_port): make read_pos a pointer to const. strports.c: take care of rw_active and rw_randow. fports.c: scm_fport_drain_input: removed. do it all in ports.c. strports.c (scm_mkstrport): check that pos is reasonable. ioext.c (scm_ftell, scm_fseek): use lseek. (SCM_CLEAR_BUFFERS): macro deleted. ioext.c (redirect_port: use ptob fflush, read_flush. ports.h (scm_ptobfuns): add ftruncate. ports.c (scm_newptob): set ftruncate. adjust ptob tables. * ports.c (scm_ftruncate): new procedure. fports.c (local_ftrunate), strports.c (str_ftruncate): new procs. strports.c (st_seek, st_grow_port): new procs. fports.h (scm_port): change size types from int to off_t. ports.c (scm_init_ports): initialise the seek symbols here instead of in ioext.c. strports.c (scm_call_with_output_string): start with an empty string, so seek and ftruncate can be used. * ports.h (scm_ptobfuns): add a read_flush procedure which is the equivalent to fflush for the read buffer. * ports.c (scm_newptob): set read_flush. ports.c (void_port_ptob): set read_flush. fports.c (local_read_flush): new proc. add to ptob. strport.c (st_read_flush): likewise. vport.c (sf_read_flush): likewise. fports.h (struct scm_fport): remove random member. there's nothing left but fdes. leaving it as a struct to allow for future changes. fports.c: replace usage of scm_fport::random with scm_port::rw_random. ports.c: (scm_putc, scm_puts, scm_lfwrite): call the read_flush ptob proc if the read buffer is filled. * ports.h (scm_port): add a rw_random member and replace reading and writing members with rw_active member. SCM_PORT_READ/SCM_PORT_WRITE: new values. * ports.h (struct scm_port_table): add writing and reading members to replace write_needs_seek: it isn't good enough for non-fports. ports.c, ioext.c, fports.c: corresponding changes. (struct scm_port_table): give it a typedef and rename to scm_port. ports.c, fports.c, strports.c, vports.c, ioext.c, ports.h: corresponding changes. * ports.c (scm_newptob): bugfix: set seek member. * * (scm_lseek): new procedure, using code from ioext.c:scm_fseek and generalised to all port types. * scmsigs.c (scm_init_scmsigs): set the SA_RESTART flag for all signals (it was only being done for handlers installed from Scheme). Otherwise (for example) SIGSTOP followed by SIGCONT on an interpreter waiting for input caused an EINTR error from read. * ports.h (struct scm_port_table): make all the char members unsigned, so they convert to int without becoming negative if large. * fports.c (scm_fdes_wait_for_input): forgot to check compilation with threads enabled. rename this procedure to fport_wait_for_input and take a port instead of a fdes. use scm_fport_input_waiting_p instead of scm_fdes_waiting_p. * readline.c (scm_readline): Applied a patch from Greg Harvey to get readline support working again: use fdopen to get FILE objects. * gc.c (scm_init_storage): install an atexit proc to flush the ports. (cleanup): the new proc. it sets a global variable which can be checked by the ptob flush procs to avoid trying to throw exceptions during exit. not very pleasant but it seems more reliable. * fports.c (local_fflush): check terminating variable and if set don't throw exception. * CHECKME: that the atexit proc is installed if unexec used. * throw.c (scm_handle_by_message): don't flush all ports here. it still causes bus errors. * fports.h (SCM_FPORT_CLEAR_BUFFERS): rename to SCM_CLEAR_BUFFERS and move to ioext.c. * fports.c (scm_fdes_waiting_p): merged into fport_input_waiting_p. * ports.c (scm_char_ready_p): check the port buffer and call the ptob entry if needed. * ports.h (scm_ptobfuns): input_waiting_p added. change all the ptob initialisers. use it in char-ready * ioext.c (scm_do_read_line): moved from ports.c. make it static. * vports.c (sfflush): modified to write a char (since softports currently use shortbuf.) * fports.c (scm_standard_stream_to_port): moved to init.c and made static. * init.c (scm_init_standard_ports): make stdout and stderr unbuffered if connected to a terminal. with stdio they were line-buffered by default. * ports.h (scm_ptobfuns): change fflush return to void. change flush proc definitions. * strports.c (scm_call_with_output_string): get size from buffer instead of port stream. (scm_strprint_obj): likewise. (st_flush): new proc. * ports.h (struct scm_port_table): added write_end member, as an optimisation. set it where write_buf_size is set. * ports.h (struct scm_port_table): change stream from void * back to SCM. SCM presumably must be large enough to hold a pointer (and probably vice versa but who knows.) (SCM_SSTREAM): deleted. change users back to SCM_STREAM. (scm_puts): rewritten * fports.c (local_ffwrite, local_fputs): removed. * strports.c (stputc, stputs, stwrite): dyked out (FIXME) * vports.c (sfputc, sfputs, sfwrite) likewise. * ports.c (write_void_port, puts_void_port): removed. (putc_void_port, getc_void_port, fgets_void_port): likewise. * ports.c (scm_lfwrite): rewritten using fport.c version. * fports.c (local_fputc): deleted. * ports.c (scm_add_to_port_table): initialise write_needs_seek. * ports.h (scm_ptobfuns): add seek function pointer. * fports.c: set it to local_seek, new procedure. * fports.h (SCM_MAYBE_DRAIN_INPUT): moved to ports.c. use ptob for seek. take ptob instead of fport arg. * ports.h (struct scm_port_table): new member write_needs_seek, replaces reading member in fport struct. * vports.c (sfgetc): store the getted char into the buffer. rename to sf_fill_buffer and install it for fill-buffer in ptob. the Scheme interface is still a procedure that gets a char. (scm_make_soft_port): set up the port buffer (shortbuf). * fports.c (local_fgetc, local_fgets): deleted. * strports.c (stgetc): likewise. * ports.c: scm_generic_fgets: likewise. * ports.h (scm_ptobfuns): add fill_buffer. * ports.c (scm_newptob): assign it. * strports.c (scm_mkstrport): set up the buffer. put just the string into the stream, not cons (pos stream). (stfill_buffer): new proc. * ports.h: fport buffer moved into port table: to be used for all port types. * throw.c (scm_handle_by_message): flush ports at exit. * socket.c (scm_sock_fd_to_port): use scm_fdes_to_port. (scm_getsockopt, scm_setsockopt, scm_shutdown, scm_connect, scm_bind, scm_listen, scm_accept, scm_getsockname, scm_getpeername, scm_recv, scm_send, scm_recvfrom, scm_sendto, use SCM_FPORT_FDES. use SCM_OPFPORTP not SCM_FPORTP. * posix.c (scm_getgroups): use SCM_ALLOW/DEFER_INTS. (scm_ttyname): use SCM_FPORT_FDES. (scm_tcgetpgrp, scm_tcsetpgrp): likewise. * ioext.c (scm_isatty_p): use SCM_FPORT_FDES. (scm_fdes_to_ports): modified. (scm_fdopen): use scm_fdes_to_port. * ports.c (scm_init_ports): don't try to flush ports using atexit(). it's too late, errors will cause SEGV. * fports.c (scm_fport_buffer_add): new procedure. * fports.h (SCM_FDES_RANDOM_P): new macro. use it in scm_fdes_to_port and scm_redirect_port. * ioext.c (scm_redirect_port): use setvbuf to set buffers in the new port. reset fp->random. * fports.c (scm_fdes_to_port), ports.c (scm_void_port), filesys.c (scm_opendir): restore defer interrupts while the port is constructed. * (scm_setvbuf): if mode is _IOFBF and size is not supplied, derive buffer size from fdes or use a default. (scm_fdes_to_port): use setvbuf instead of creating the buffers directly. vports.c (various places): use SCM_SSTREAM. strports.c: likewise. * gdbint.c: likewise. * ports.h (SCM_SSTREAM): new macro. * fports.c (scm_input_waiting_p): use scm_return_first, since port may be removed from the stack by the tail call to scm_fdes_waiting_p. * fports.h (SCM_CLEAR_BUFFERS): new macro. * ports.c (scm_force_output): call scm_fflush. * print.c (scm_newline): don't check errno for EPIPE (it wouldn't * reach this point.) don't flush port (if scm_cur_outp). * fports.h (SCM_FPORT_FDES): new macro. * vports.c (sfflush): don't need to set errno. * ports.c: install scm_flush_all_ports to be run on exit. ports.c fports.c ioext.c posix.c socket.c net_db.c filesys.c: removed all uses of SCM_DEFER/ALLOW ints for now. they were mainly just protecting errno. some may need to be put back. * scmsigs.c (take_signal): save and restore errno while this proc runs. *fports.c (print_pipe_port, local_pclose, scm_pipob): deleted. * open-pipe, close-pipe are emulated in (ice-9 popen) ports.c (scm_ports_prehistory): don't init scm_pipob. ports.h (scm_tc16_pipe): deleted. posix.c (scm_open_pipe, scm_close_pipe): deleted. * ioext.c (scm_primitive_move_to_fdes): use fport. * fport.c (scm_fport_fill_buffer): flush write buffer if needed. change arg type from scm_fport to SCM port. fport.h (SCM_SETFDES): removed. (SCM_MAYBE_DRAIN_INPUT): new macro. * ioext.c (scm_dup_to_fdes): use SCM_FSTREAM. (scm_ftell): always use lseek and account for the buffer. (scm_fileno): use fport buffer. (scm_fseek): clear fport buffers. always use lseek. * posix.c (scm_pipe): use fport buffer. * unif.c: include fports.h instead of genio.h. * fports.c (scm_fdes_wait_for_input, scm_fport_fill_buffer): new procedures. (local_fgetc): use them. (local_ffwrite): use buffer. (local_fgets): use buffer. (scm_setbuf0): deleted. (scm_setvbuf): set the buffer. (scm_setfileno): deleted. (scm_evict_ports): set fdes directly. * (scm_freopen): deleted. doesn't seem useful in Guile. (scm_stdio_to_port): deleted. fports.h (struct scm_fport): add shortbuf member to avoid separate code for unbuffered ports. (SCM_FPORTP, SCM_OPFPORTP, SCM_OPINFPORTP, SCM_OPOUTFPORTP): moved from ports.h. * genio.c, genio.h: move contents into ports.c, ports.h. The division wasn't useful. * fports.c, fports.h (scm_fport_drain_input): new procedure. * ports.c (scm_drain_input): call scm_fport_drain_input. * scm_fdes_waiting_p: new procedure. * fports.c (scm_fdes_to_port): allocate read and/or write buffers. (scm_input_waiting_p): check the buffer. (local_fgetc, local_fflush, local_fputc): likewise. * fports.h (scm_fport): read/write_buf,_pos,_buf_end,,_buf_size: new members. * init.c (scm_init_standard_ports): pass fdes instead of FILE *. * * ports.c (scm_drain_input): new procedure. ports.h: prototype. * fports.c (FPORT_READ_SAFE, FPORT_WRITE_SAFE, FPORT_ALL_OKAY, pre_read, pre_write): removed. (local_fputc, local_fputs, local_ffwrite): use write, not stdio. (scm_standard_stream_to_port): change first arg from FILE * to int fdes. (local_fflush): flush fdes, not FILE *. * fports.h (SCM_NOFTELL): removed. * genio.c, ports.c: don't include filesys.h. * genio.c (scm_getc): don't use scm_internal_select if FPORT. do it in fports.c:local_fgetc. * genio.c: don't use SCM_SYSCALL when calling ptob procedures. do it where it's needed in the port smobs. * filesys.c (scm_input_waiting_p): moved to fports.c, stdio buffer support removed. take SCM arg, not FILE *. * filesys.h: prototype moved too. * fports.c (scm_fdes_to_port): new procedure. (local_fgetc): use read not fgetc. (local_fclose): use close, not fclose. (local_fgets): use read, not fgets * fports.h: prototype for scm_fdes_to_port. * fports.h (scm_fport): new struct. * fports.c (scm_open_file): use open, not fopen. #include fcntl.h * ports.h (struct scm_port_table): change stream from SCM to void *. * ports.c (scm_add_to_port_table): check for memory allocation error. (scm_prinport): remove MSDOS hair. (scm_void_port): set stream to 0 instead of SCM_BOOL_F. (scm_close_port): don't throw errors: do it in fports.c.
2587 lines
63 KiB
C
2587 lines
63 KiB
C
/* Copyright (C) 1995,1996,1997,1998 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 "fports.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 long ivect
|
||
* unsigned long 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);
|
||
}
|
||
}
|
||
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); /* 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;
|
||
const 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;
|
||
const 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_UCHARS (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_UCHARS (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 = 0;
|
||
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_UCHARS (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] = scm_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:
|
||
((float *) SCM_CDR (v))[pos] = (float)scm_num2dbl(obj, s_array_set_x); break;
|
||
break;
|
||
#endif
|
||
case scm_tc7_dvect:
|
||
((double *) SCM_CDR (v))[pos] = scm_num2dbl(obj, s_array_set_x); break;
|
||
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 (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;
|
||
|
||
port_or_fd = SCM_COERCE_OUTPORT (port_or_fd);
|
||
|
||
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_UCHARS (ra)[j]), port, pstate);
|
||
if (SCM_WRITINGP (pstate))
|
||
for (j += inc; n-- > 0; j += inc)
|
||
{
|
||
scm_putc (' ', port);
|
||
scm_iprin1 (SCM_MAKICHR (SCM_UCHARS (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_putc ('y', 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_putc ('h', 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;
|
||
{
|
||
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 */
|