sisc-1.16.6.orig/0000755000175000017500000000000011445752462012143 5ustar amoeamoesisc-1.16.6.orig/doc/0000755000175000017500000000000011445752462012710 5ustar amoeamoesisc-1.16.6.orig/doc/sss/0000755000175000017500000000000011445752462013520 5ustar amoeamoesisc-1.16.6.orig/doc/sss/io.xml0000644000175000017500000046407611445752462014672 0ustar amoeamoe I/O &SISC;'s I/O routines are implemented in a flexible manner, allowing extensions to create new I/O sources that will behave as standard Scheme port objects. The ports can then be operated on with all &R5RS; port operations, as well as some &SISC; specific port functions. Ports URLs In &SISC; all procedures that create ports for accessing files, e.g. open-input-file, open-output-file accept URLs in addition to ordinary file names. Here are some examples of valid URLs: http://foo.com/bar/bar1.scm file:/tmp/foo.scm file:c:\bar\baz.scm file:foo.scm jar:http://foo.com/bar.jar!/bar/bar1.scm The last is a URL referring to a file stored in a JAR on a remote web server. For further details on the format of URLs please consult this specification. The format of JAR URLs is defined in the JDK API documentation. What types of URLs are supported by a particular installation of Java depends on the configured protocol handlers. See the JDK API documentation for details. Handling of JAR files in URLS may be dependent on the &SISC; host language, as well as some uncommon protocols. FILE, HTTP and FTP should be expected to work with any host language. Relative file names or URLs are resolved in relation to the following parameter:
current-url ¶meter; url current-url url
Retrieves or sets the URL which forms the basis for resolving relative filenames and URLs. It is initialized on start up with the path to the current directory. All parameters and the returned value are strings.
The algorithm for resolving relative URLs is defined in this specification. For compatibility with other Schemes, &SISC; also supports the current-directory procedure, which is a simple wrapper around current-url.
A convenience procedure exists for executing a procedure while the current-url is temporarily set to a different value:
with-current-url &procedure; value with-current-url url thunk
Sets the current URL to the URL obtained by normalizing url in relation to the current URL, then executes thunk, and then sets the current URL back to the previous value.
URLs can be normalized using
normalize-url &procedure; url normalize-url url1 url2
When called with one string argument, normalize-url returns the normalized version of the given URL. Normalization involves, amongst other things, the replacement of relative path references such as . and ... When called with two string arguments, the procedure returns the normalized version of the second URL when interpreted as a being relative to the first URL.
Buffered I/O Buffered ports are provided in &SISC; to layer over any existing port, and read or write in larger, more efficient chunks. Buffered ports are created with the following constructors, which accept the underlying port and an optional size, indicating the number of bytes or characters to buffer before making an underlying read or write.
open-buffered-binary-input-port &procedure; binary-input-port open-buffered-binary-input-port binary-input-port
Creates a binary-input-port which is buffered, and reads its bytes from the provided port.
open-buffered-binary-output-port &procedure; binary-output-port open-buffered-binary-output-port binary-output-port
Creates a binary-output-port which is buffered, and writes its bytes to the provided port.
open-buffered-character-input-port &procedure; character-input-port open-buffered-character-input-port character-input-port
Creates a character-input-port which is buffered, and reads its characters from the provided port.
open-buffered-character-output-port &procedure; character-output-port open-buffered-character-output-port character-output-port
Creates a character-output-port which is buffered, and writes its characters to the provided port.
With buffered output ports, individual writes may not actually reach the eventual output source, so the programmer must explicitly flush the port when it the output data must reach its destination.
flush-output-port &procedure; undefined flush-output-port output-port
Causes the specified output-port's buffered data to be written immediately. This operation is allowed on any output port, but may have no affect on some. output-port defaults to current-output-port.
Character Ports The &R5RS; I/O primitives implemented by &SISC; create character ports. Character ports read characters from input sources and treat the data as characters in a given character set. Correspondingly, character ports output bytes from characters according to a given character set's encoding rules. By default character ports use the value of the string parameter character-set as the character encoding name. A list of many possible encoding names can be found in the Java Platform Documentation One may temporarily change the default character set using the with-character-set function.
with-character-set &procedure; value with-character-set encoding thunk
Changes the value of the character-set parameter, and the default character set to the named encoding while executing the body of thunk.
Port Creation
open-input-file &procedure; input-port open-input-file url encoding
Creates an input port from the specified url. If the optional encoding parameter, a string, is supplied input will be decoded from the specified encoding rather than the default.
open-output-file &procedure; output-port open-output-file url encoding auto-flush
Creates an output port to the specified url. If the optional encoding parameter, a string, is supplied output will be encoded in the specified encoding rather than the default. If the optional auto-flush argument is provided and is non-false, the port will automatically flush after each write call. If the specified file exists, it will be overwritten silently when the port is opened.
open-character-input-port &procedure; input-port open-character-input-port binary-input-port character-set
Creates an input port which reads from the provided binary input port. One may specify the desired character set as a string, otherwise the character set is retrieved from the character-set dynamic parameter.
open-character-output-port &procedure; output-port open-character-output-port binary-output-port character-set auto-flush
Creates an output port which writes to the provided binary output port. One may specify the desired character set as a string, otherwise the character set is retrieved from the character-set dynamic parameter. If the optional auto-flush argument is provided and is non-false, the port will automatically flush after each write call.
Bulk Character I/O In addition to the &R5RS; I/O primitives, &SISC; provides two functions for reading and writing blocks of characters from a character port.
read-string &procedure; integer read-string buffer offset count character-input-port
Reads up to count characters from the implicit or specified character port into the string buffer starting from the position specified by the integer offset. The number of characters successfully read (which may be fewer than count) is returned, or the end-of-file value if the end-of-file was reached before any characters were encountered.
write-string &procedure; undefined write-string buffer offset count character-output-port
Writes exactly count characters from the given string buffer starting from the integer position offset to the implicit or specified character output port.
Port Creation Wrappers The next set of procedures assists in creating a port, followed by calling a given procedure with that port. When the procedure returns, the port is closed. Invoking escaping continuations from inside the procedure does not close the port, and invoking a continuation captured inside the procedure does not open the port.
call-with-input-file &procedure; value call-with-input-file url encoding procedure
Calls procedure with a new input port attached to url. The result of the thunk is returned. If the optional encoding parameter is provided, the character port created will use the specified encoding rather than the default.
call-with-output-file &procedure; value call-with-output-file url encoding procedure
Calls procedure with a new character output port attached to url. The result of the thunk is returned. If the optional encoding parameter is provided, the character port created will use the specified encoding rather than the default.
Replacing Standard Ports The following procedures wrap a thunk, redirecting the input and output of the thunk while it is evaluating to an input or output port other than the current-input-port and current-output-port. Invoking escaping continuations from inside the procedure restores the original port, and invoking a continuation captured inside the procedure restores the redirection.
with-input-from-port &procedure; value with-input-from-port input-port thunk
Evaluates thunk with input-port as the current-input-port for the duration of the evaluation.
with-output-to-port &procedure; value with-output-to-port output-port thunk
Evaluates thunk with output-port as the current-output-port for the duration of the evaluation.
with-input-from-file &procedure; value with-input-from-file url encoding thunk
Evaluates thunk with an input port attached to a file opened for reading from url as the current-input-port for the duration of the evaluation. The port is closed when thunk returns normally. If the optional encoding parameter is provided, the character port created will use the specified encoding rather than the default.
with-output-to-file &procedure; value with-output-to-file url encoding thunk
Evaluates thunk with an input port attached to a file opened for writing to url as the current-output-port for the duration of the evaluation. The port is closed when thunk returns normally. If the optional encoding parameter is provided, the character port created will use the specified encoding rather than the default.
Port Predicates
input-port? &procedure; #t/#f input-port? value
Returns #t if value is an input port, #f otherwise.
output-port? &procedure; #t/#f output-port? value
Returns #t if value is an output port, #f otherwise.
String Ports &requires; (import string-io) String ports are input or output ports that read or write to a string rather than a file or other stream. String ports can be used to parse or emit formatted strings using the standard Scheme port operations. A String Input port will read from a given string until the end of string is reached, at which point #!eof is returned. String ports deal with characters as the atomic unit, and as such preserve full unicode width characters at all times.
open-input-string &procedure; string-input-port open-input-string string
Creates a string input port whose characters are read from the provided string. Characters will be returned from any read operation on the port until the end of the string is reached. Read calls after reaching the end of the string will return #!eof.
&procedure; string-output-port open-output-string
Creates a string output port, which behaves as an ordinary output port, except that writes are used to create a string as output. The results of all the write operations are retrieved using get-output-string.
get-output-string &procedure; string get-output-string string-output-port
Returns the string that was created by zero or more writes to a string output port. If no writes were performed on the string output port, an empty string ("") is returned. After this call, the provided string output port is reset to its initial, empty state.
call-with-input-string &procedure; value call-with-input-string string procedure
Calls procedure with a new string input port created from string. The result of the thunk is returned.
call-with-output-string &procedure; string call-with-output-string procedure
Calls procedure with a new string output port. The contents of the string-output-port are returned when the procedure returns.
with-input-from-string &procedure; value with-input-from-string string thunk
Evaluates thunk with a string-input-port created from string as the current-input-port for the duration of the evaluation.
with-output-to-string &procedure; string with-output-to-string thunk
Evaluates thunk with a string-output-port created as the current-output-port for the duration of the evaluation. When the thunk returns, the contents of the string-output-port are returned.
string-input-port? &procedure; #t/#f string-input-port? value
Returns #t if value is a string input port, #f otherwise.
string-output-port? &procedure; #t/#f string-output-port? value
Returns #t if value is a string output port, #f otherwise.
This interface complies with SRFI-6 (Basic String Ports).
Binary Ports and Block IO &requires; (import binary-io) In addition to the &R5RS; I/O functions, &SISC; provides a symmetric set of functions for reading and writing binary data to and from ports with no character set translation. These ports are operated on using the binary I/O functions described below. Using character-oriented operations (such as the traditional &R5RS; functions read, read-char, display, etc.) is an error. Binary ports also provide block input/output functions, that allow a Scheme program to read blocks of more than one byte of data at a time from binary ports. &SISC; stores data that is read or is to be written in block fashion in a binary buffer (see ).
open-binary-input-file &procedure; binary-input-port open-binary-input-file url
Creates an input port in the same manner as &R5RS; open-input-file, producing an input port that does no character-set decoding on the bytes read as input.
open-binary-output-file &procedure; binary-output-port open-binary-output-file url auto-flush
Creates an output port in the same manner as open-output-file, producing an output port that does no character-set encoding.
call-with-binary-input-file &procedure; value call-with-binary-input-file url procedure
Calls procedure with a new binary input port attached to url. The result of the thunk is returned.
call-with-binary-output-file &procedure; value call-with-binary-output-file url procedure
Calls procedure with a new binary output port attached to url. The result of the thunk is returned.
with-binary-input-from-file &procedure; value with-binary-input-from-file url thunk
Evaluates thunk with a binary input port attached to a file opened for reading from url as the current-input-port for the duration of the evaluation. The port is closed when thunk returns normally.
with-binary-output-to-file &procedure; value with-binary-output-to-file url thunk
Evaluates thunk with a binary output port attached to a file opened for writing to url as the current-output-port for the duration of the evaluation. The port is closed when thunk returns normally.
There are several operations specifically available for use on binary ports. peek-byte &procedure; integer peek-byte binary-input-port
Similar to peek-char, reads ahead one byte in the stream, returning the next byte available but not advancing the stream. The byte is returned as an integer. The current input port is used unless specified.
read-byte &procedure; integer read-byte binary-input-port
Reads a single byte from the stream, advancing the stream and returning the byte as an integer. The current input port is used unless specified.
read-block &procedure; integer read-block buffer offset count binary-input-port
Reads up to count bytes of data from the current input port or the binary-input-port parameter if provided, into the binary buffer buffer starting at position offset. Note that less than count bytes may be read. The number of bytes actually read is returned. If the end-of-file is encountered before any bytes could be read, #!eof will be returned.
write-byte &procedure; undefined write-byte integer binary-output-port
Writes a single byte specified as an integer to the given binary-output-port if provided, current output port otherwise.
write-block &procedure; undefined write-block buffer offset count binary-output-port
Writes count bytes of data from the provided buffer at starting point offset to the given binary-output-port or to the current output port if unspecified. Exactly count bytes will be written.
binary-input-port? &procedure; #t/#f binary-input-port? value
Returns #t if value is a binary input port, #f otherwise.
binary-output-port? &procedure; #t/#f binary-output-port? value
Returns #t if value is a binary output port, #f otherwise.
Buffer I/O &requires; (import buffer-io) A module is also provided for input and output to and from binary buffers using buffer ports, similar to character I/O to and from strings using string ports.
open-input-buffer &procedure; buffer-input-port open-input-buffer buffer
Creates a buffer input port whose bytes are read from the provided buffer. Bytes will be returned from any read operation on the port until the end of the buffer is reached. Read calls after reaching the end of the buffer will return #!eof.
&procedure; buffer-output-port open-output-buffer
Creates a buffer output port, which behaves as an ordinary output port, except that writes are used to create a buffer as output. The results of all the write operations are retrieved using get-output-buffer.
get-output-buffer &procedure; buffer get-output-buffer buffer-output-port
Returns the buffer that was created by zero or more writes to a buffer output port. If no writes were performed on the buffer output port, an empty buffer is returned. After this call, the provided buffer output port is reset to its initial, empty state.
call-with-input-buffer &procedure; value call-with-input-buffer buffer procedure
Calls procedure with a new buffer input port created from buffer. The result of the thunk is returned.
call-with-output-buffer &procedure; buffer call-with-output-buffer procedure
Calls procedure with a new buffer output port. The contents of the buffer-output-port are returned when the procedure returns.
with-input-from-buffer &procedure; value with-input-from-buffer buffer thunk
Evaluates thunk with a buffer-input-port created from buffer as the current-input-port for the duration of the evaluation.
with-output-to-buffer &procedure; buffer with-output-to-buffer thunk
Evaluates thunk with a buffer-output-port created as the current-output-port for the duration of the evaluation. When the thunk returns, the contents of the buffer-output-port are returned.
Java Ports &requires; (import java-io) This module provides procedures to convert between Scheme and Java I/O types. In general, binary Scheme ports map to plain Java streams, while character Scheme ports map to Java readers and writers. The following example is somewhat contrived, but illustrates a common usage pattern: |java.lang.System|)) (define-generic-java-field-accessors (:jout out)) (let ((stdout (open-character-output-port (->binary-output-port (:jout (java-null )) #t) #t))) (display "Hello, world!" stdout)) ]]>
->binary-input-port &procedure; binary-input-port ->binary-input-port jinput-stream
Returns a binary input port associated to the java.io.InputStream object passed as the jinput-stream parameter.
->binary-output-port &procedure; binary-output-port ->binary-output-port joutput-stream aflush?
Returns a binary input port associated to the java.io.OutputStream object passed as the joutput-stream parameter. If the optional boolean aflush? parameter is not provided, the port will not autoflush by default.
->character-input-port &procedure; character-input-port ->character-input-port jreader
Returns a character input port associated to the java.io.Reader object passed as the jreader parameter.
->character-output-port &procedure; character-output-port ->character-output-port jwriter aflush?
Returns a binary input port associated to the java.io.Writer object passed as the joutput-stream parameter. If the optional boolean aflush? parameter is not provided, the port will not autoflush by default.
->jinput-stream &procedure; jinput-stream ->jinput-stream input-port
Returns a java.io.InputStream object associated to the given Scheme input-port. The function produces an error if a character port is passed.
->joutput-stream &procedure; joutput-stream ->joutput-stream output-port
Returns a java.io.OutputStream object associated to the given Scheme output-port. The function produces an error if a character port is passed.
->jreader &procedure; jreader ->jreader character-input-port
Returns a java.io.Reader object associated to the given Scheme character-input-port.
->jwriter &procedure; jwriter ->jwriter character-output-port
Returns a java.io.Writer object associated to the given Scheme character-output-port.
Scheme ports can also be used from Java. See for information.
Serialization &requires; (import serial-io) With read and write, Scheme values are read and written in a standardized, textual external representation. However, this external representation only fully describes a limited subset of Scheme types. For instance it is impossible to read/write a procedure, or closure, or continuation. &SISC; provides a special composed port type and procedures for reading and writing any Scheme value using a binary representation. The (de)serialization preserves the referential structure of the object graph comprising the serialized values. Serial ports are composed onto and thus are binary ports, i.e. all operations applicable to binary ports also apply to serial ports. Port Creation and Identification
open-serial-input-port &procedure; serial-input-port open-serial-input-port binary-input-port
Creates a serial input port which reads external representations of Scheme values from the given binary input port.
open-serial-output-port &procedure; serial-output-port open-serial-output-port binary-output-port auto-flush
Creates a serial output port which can be used to write external representations of Scheme values to the provided binary output port.
serial-input-port? &procedure; #t/#f serial-input-port? value
Returns #t if value is a serial input port, #f otherwise.
serial-output-port? &procedure; #t/#f serial-output-port? value
Returns #t if value is a serial output port, #f otherwise.
Serial Port Wrappers
call-with-serial-input-port &procedure; value call-with-serial-input-port binary-input-port procedure
Calls procedure with a new serial input port attached to binary-input-port. The result of the thunk is returned.
call-with-serial-output-port &procedure; value call-with-serial-output-port binary-output-port procedure
Calls procedure with a new serial output port attached to binary-output-port. The result of the thunk is returned.
with-serial-input-from-port &procedure; value with-serial-input-from-port binary-input-port thunk
Evaluates thunk with a serial input port attached to the specified binary-input-port as the current-input-port for the duration of the evaluation. The port is not closed when thunk returns.
with-serial-output-to-port &procedure; value with-serial-output-to-port binary-output-port thunk
Evaluates thunk with a serial input port attached to the specified binary-output-port as the current-output-port for the duration of the evaluation. The port is not closed when thunk returns.
call-with-serial-input-file &procedure; value call-with-serial-input-file url procedure
Calls procedure with a new serial input port attached to url. The result of the thunk is returned.
call-with-serial-output-file &procedure; value call-with-serial-output-file url procedure
Calls procedure with a new serial output port attached to url. The result of the thunk is returned.
with-serial-input-from-file &procedure; value with-serial-input-from-file url thunk
Evaluates thunk with a serial input port attached to a file opened for reading from url as the current-input-port for the duration of the evaluation. The port is closed when thunk returns normally.
with-serial-output-to-file &procedure; value with-serial-output-to-file url thunk
Evaluates thunk with a serial input port attached to a file opened for writing to url as the current-output-port for the duration of the evaluation. The port is closed when thunk returns normally.
Serialization Procedures
deserialize &procedure; value deserialize serial-input-port
Reads a Scheme value from an external representation retrieved from serial-input-port. If serial-input-port is absent the data is read from the current input port.
serialize &procedure; undefined serialize value serial-output-port
Writes an external representation of value to serial-output-port. If serial-output-port is absent the data is written to the current output port.
Networking &requires; (import networking) The &SISC; Networking library provides a mechanism for creating and manipulating IP network protocols as standard Scheme ports. &SISC; supports TCP, UDP, and Multicast UDP. Each is described in the sections that follow. Each protocol provides one or more socket constructors. These functions produce a Socket handle, which is represented in &SISC; as #<socket>. A socket handle is then used to obtain Scheme ports. IP addresses and network hostnames are represented as strings in &SISC;. Unless otherwise noted, the network library functions that require an address may take a network address as a string which may be any of: A hostname, to be resolved through the domain name system. An IPv4 network address in the standard dotted quad format. (RFC-791) An IPv6 network address in colon separated hexadecimal form, and zero-shortened form. (RFC-2373) IPv6 addresses must be supported by the underlying operating system. An error may be raised if the address is not supported. All IP port values must be exact integers in the proper range. IP Addressing Several utility functions are provided for manipulating IP addresses. These are described below.
get-host-ip-by-name &procedure; string get-host-ip-by-name hostname
Attempts to resolve a hostname provided as a string into an IP address in dotted-quad form. If the host cannot be found, &f; is returned.
get-host-name-by-ip &procedure; string get-host-name-by-ip ip-address
Attempts a reverse lookup of the given dotted-quad address to determine a registered domain name. If unsuccessful, &f; is returned.
get-local-host &procedure; string get-local-host
Attempts to determine the Internet visible IP address of the local machine. If successful, this address is returned in dotted-quad notation. &f; is returned otherwise.
Socket Operations Once obtained using a protocol specific constructor, a Socket Handle allows manipulation of common socket options, the creation of Scheme input/output ports, and closing of the socket.
socket? &procedure; #t/#f socket? value
Returns true if and only if the provided value is a socket.
open-socket-input-port &procedure; input-port open-socket-input-port socket encoding
Opens a character input port to the socket. If the optional encoding parameter is provided, the character port created will use the specified encoding rather than the default.
open-socket-output-port &procedure; output-port open-socket-output-port socket encoding auto-flush
Opens a character output port to the socket. If provided, the boolean argument specifies whether the given port should be set to auto-flush mode. If unspecified, the port does not auto-flush. If the optional encoding parameter is provided, the character port created will use the specified encoding rather than the default.
open-binary-socket-input-port &procedure; binary-input-port open-binary-socket-input-port socket
Opens a binary input port to the socket.
open-binary-socket-output-port &procedure; binary-output-port open-binary-socket-output-port socket auto-flush
Opens a character output port to the socket. If provided, the boolean argument specifies whether the given port should be set to auto-flush mode. If unspecified, the port does not auto-flush.
close-socket &procedure; unspecified close-socket socket
Closes an IP socket.
The port-obtaining functions above work on most sockets. An exception applies for TCP server sockets, which are used only to obtain connected TCP sockets.
TCP The most commonly used Internet protocol maps most favorably to Scheme's input/output model. Writing to an output port retrieved from a TCP socket writes the data to that socket. Reading from an input port reads from the connected socket. One important note is that one can control the amount of data that fills a TCP packet by using an output port that does not auto-flush. Data is written to the port until one considers the packet complete, and then uses (flush-output-port port) to complete the packet. Note also that this does not guarantee that one gets the desired packet size, but does allow one to construct reasonably sized packets. TCP sockets are obtained one of two ways. Either one creates an outgoing connection to another listening host and then subsequently obtains a socket handle, or one creates a listening socket and then obtains a socket by waiting for an incoming connection on the specified port. In either case, the result is a socket handle with an available input and output port that can be obtained using a function in the previous section.
open-tcp-socket &procedure; socket open-tcp-socket host port
Attempts to connect to the host at the given hostname or IP address encoded as a string, at the given TCP port specified as an integer. An error is raised if the host cannot be found or the connection fails. If successful, a socket is returned.
open-tcp-listener &procedure; server-socket open-tcp-listener port interface-address
Creates a TCP server socket, which may only be used with accept-tcp-socket, or closed. The server socket will listen on the integer port specified. If provided, the interface-address, a string specifies the address of a local interface to bind to. If not provided, the port is bound on all available interfaces. An error is raised if the socket cannot be bound and set listening.
server-socket? &procedure; #t/#f server-socket? value
Returns true if and only if the provided value is a server socket.
accept-tcp-socket &procedure; socket accept-tcp-socket server-socket
Accepts an incoming connection on the provided server-socket, and returns a TCP socket handle. This function will block until an incoming connection is made, or, if set, the socket timeout is exceeded. If the latter happens, an error will be raised.
set-so-timeout! &procedure; undefined set-so-timeout! socket timeout
Sets the socket timeout on a socket. The socket can be either a server socket or connected socket. In the former case, this value specifies the number of milliseconds that an accept-tcp-socket can wait before timing out. In the latter, the value specifies the number of milliseconds that can elapse during a read call before timing out.
TLS and SSL Sockets which are encrypted using the Secure Sockets Layer (SSL) or Transport Security Layer (TLS) can be created an accepted as well. This functionality can heavily depend on the underlying support in the JVM, including security settings, restrictions, installed certificates, etc. For information on the Java Secure Socket Extension (JSSE) and its setup, refer to the JSSE documentation page at Sun. The SSL functionality is built atop the sockets and server sockets functionality as in TCP networking above. A separate constructor for sockets (open-ssl-socket) and listening sockets (open-ssl-listener) exist, and produce sockets which are used identically to TCP sockets as previously described.
open-ssl-socket &procedure; socket open-ssl-socket host port auto-close
Attempts to connect to the host at the given hostname or IP address encoded as a string, at the given TCP port specified as an integer, and establish an SSL connection using the default cipher suites and protocols available. An error is raised if the host cannot be found or the connection fails. If successful, a socket is returned.
open-ssl-listener &procedure; server-socket open-ssl-listener port interface-address
Creates an SSL TCP server socket, which may only be used with accept-tcp-socket, or closed. The server socket will listen on the integer port specified. If provided, the interface-address, a string specifies the address of a local interface to bind to. If not provided, the port is bound on all available interfaces. An error is raised if the socket cannot be bound and set listening. The cipher suites, protocols, and modes which this server socket will accept are set with the following functions.
get-enabled-cipher-suites &procedure; list get-enabled-cipher-suites ssl-server-socket
Returns a list of strings naming the cipher suites which are enabled for this server socket.
set-enabled-cipher-suites! &procedure; list set-enabled-cipher-suites! ssl-server-socket suite-list
Accepts an ssl server socket and a list of strings naming the cipher suites which should be available for negotiation with the remote end. The previous list is returned.
get-enabled-protocols &procedure; list get-enabled-protocols ssl-server-socket
Returns a list of strings naming the security protocols which are enabled for this server socket.
set-enabled-protocols! &procedure; list set-enabled-protocols! ssl-server-socket protocol-list
Accepts an ssl server socket and a list of strings naming the protocols which should be available for negotiation with the remote end. The previous list is returned.
session-creation-permitted &procedure; boolean session-creation-permitted? ssl-server-socket
Returns true if new SSL/TLS sessions can be created by the sockets obtained from this server socket.
set-session-creation-permitted! &procedure; boolean set-session-creation-permitted! ssl-server-socket boolean
Sets whether new SSL/TLS sessions can be created by the sockets obtained from this server socket. The previous value is returned.
is-client-mode? &procedure; boolean is-client-mode? ssl-server-socket
Returns true if the SSL server socket will be in the rare client mode after accepting the connection, rather than the more common server mode.
set-client-mode! &procedure; boolean set-client-mode! ssl-server-socket boolean
Sets whether the SSL server socket will be in client mode when accepting new connections. The previousvalue is returned.
get-client-auth &procedure; symbol or #f get-client-auth ssl-server-socket
Returns the necessity of the remote client to authenticate to this server socket. The returned values are either needed, indicating the remote must authenticate, wanted, indicating the remote will be requiested to authenticate but is not required to, or #f, indicating the remote will not be requested to authenticate.
set-client-auth! &procedure; symbol or #f set-client-auth! ssl-server-socket client-auth-mode
Sets the client authentication requirements, as described in get-client-auth above. One of the above values must be specified. The previous value is returned.
UDP UDP sockets can be obtained for both receive only and send/receive sessions. The behavior of the char-ready? function is somewhat more difficult to predict on a UDP input port. The function will return #t only when a previous datagram contained more bytes than were requested by the read operation that received it.
open-udp-listen-socket &procedure; udp socket open-udp-listen-socket listen-port interface-address datagram-size
Opens a UDP socket that listens on listen-port (optionally bound to only the interface on interface-address). If provided, datagram-size specifies the buffer size (in bytes) for receiving UDP datagrams. Datagrams larger than datagram-size are truncated to that size. If unspecified, the default datagram size is 1500 bytes.
open-udp-socket &procedure; udp socket open-udp-socket remote-host remote-port
Opens a UDP socket for sending datagrams to the Internet host specified by remote-host, on port remote-port.
After obtaining a UDP socket, input and output ports can be obtained in the usual manner. It is an error to attempt to obtain an output-port from a listening UDP socket, or an input port from a sending UDP socket. UDP input ports behave as ordinary input ports. When a datagram arrives as a result of any read operation on the port, their entire contents are stored in a buffer of length datagram-size bytes. Successive read operations return data from that buffer until it is exhausted, at which point a read operation will cause the UDP socket to listen for another datagram. UDP output ports should be treated with some care, however. If a UDP output port was obtained in auto-flush mode, each write operation to the output port will cause a new datagram to be sent. Control over the size of the datagram must be maintained by using a port that does not auto-flush, writing the desired data, and flushing once the amount of data that the user wants to occupy a single UDP datagram is reached. The behavior of constructing very large UDP packets is undefined. The packet may be silently dropped or (more likely) fragmented at the IP layer.
Multicast UDP &SISC; provides support for IP multicast UDP datagrams as well. This allows a program to both send and receive to an IP multicast group. Multicast UDPs are an extension of ordinary UDP. Thus all I/O operations on a Multicast UDP socket are subject to the same semantics as an ordinary UDP socket. The Multicast UDP library requires that the underlying operating system's IP networking stack support Multicast. The functions described here may produce an error if the operating system does not. A program wishing to use multicast UDP sockets must first obtain a multicast socket for either listening to a multicast group, or for both listening and sending to such a group.
open-multicast-socket &procedure; multicast udp socket open-multicast-socket listen-port interface-address datagram-size
Opens a multicast UDP socket that listens on listen-port (optionally bound only to the interface addressed by interface-address. If provided, datagram-size specifies the buffer size (in bytes) for receiving UDP datagrams. Datagrams larger than datagram-size are truncated to that size. If unspecified, the default datagram size is 1500 bytes.
&procedure; multicast udp socket open-multicast-socket group port interface-address datagram-size
Opens a multicast UDP socket for sending datagrams to the specified multicast group, on the specified port. The returned socket will also be capable of listening to that group on the same port (and optionally bound only to the interface addressed by interface-address), though the socket will not initially be a member of the group. If provided, datagram-size specifies the buffer size (in bytes) for receiving UDP datagrams. Datagrams larger than datagram-size are truncated to that size. If unspecified, the default datagram size is 1500 bytes.
Once a sending socket has been obtained (the second form), an output-port can be obtained in the usual manner, and datagrams can be immediately sent to the multicast group. To receive datagrams, sockets returned from both forms must join a multicast group. A multicast group is specified by a class D IP address and by a standard UDP port number. Class D IP addresses are in the range 224.0.0.0 to 239.255.255.255, inclusive. The address 224.0.0.0 is reserved and should not be used. Groups are joined and left using the following functions:
join-multicast-group &procedure; undefined join-multicast-group multicast-socket group
Causes the given multicast socket to join the group specified by the Internet address in group. Once joined, read operations on an obtained input-port will be able to receive datagrams destined to that group.
leave-multicast-group &procedure; undefined leave-multicast-group multicast-socket group
Causes the given multicast socket to leave the group specified by the Internet address in group. Read operations on any input ports obtained from this socket will no longer receive datagrams from that group.
A single multicast socket can simultaneously listen to more than one multicast group. A socket can only send to one group, however: the group it was constructed with. Multicast packets are limited in extent by their time-to-live. Each time a multicast packet crosses a router, its ttl is decremented. In this manner, one can send datagrams only to local networks or subnetworks, as well as more grand scopes. The TTL of a socket is set using set-multicast-ttl!
set-multicast-ttl! &procedure; undefined set-multicast-ttl! multicast-socket ttl
Sets the multicast TTL of the given socket to ttl, an integer. All datagrams sent after this call will have their TTL set to the new value.
Valid multicast TTLs are in the range 0 (restricted to the same host) to 255 (unlimited in scope).
User Defined Ports &requires; (import custom-io) &SISC; provides the ability to create new I/O port types from within Scheme. To add a new port type, one invokes a custom port constructors described below, passing procedures (Scheme or otherwise) which implement the operations required by that port. Each custom port constructor returns a Scheme port which may be used with any of the &SISC; or &R5RS; I/O functions. Port implementors may also use an associated port-local value to coordinate state for some specialized ports.
set-port-local! &procedure; value set-port-local! custom-port value
Sets the port-local value of the given custom port.
port-local &procedure; value port-local wrapper-stream
Gets the port-local value of the given custom port.
make-custom-character-input-port &procedure; character-input-port make-custom-character-input-port read read-string ready? close
Creates a character-input-port whose functionality is implemented by the four provided fundamental procedures. The fundamental procedures required are as follows: integer read port
Return a character as an integer value, or -1 if the end of stream has been reached. port is a reference to the custom Scheme port which contains the procedure.
integer read-string port mutable-string offset count
Reads up to count characters into the given mutable string at position offset. The number of actual characters read are returned as an integer value, or -1 if the end of stream has been reached. port is a reference to the custom Scheme port which contains the procedure.
boolean ready? port
Returns a non-false value if one or more characters are available for reading, false otherwise.
undefined close port
Closes the port.
make-custom-binary-input-port &procedure; binary-input-port make-custom-binary-input-port read read-block available close
Creates a binary-input-port whose functionality is implemented by the four provided fundamental procedures. The fundamental procedures required are as follows: integer read port
Return a byte as an integer value, or -1 if the end of stream has been reached. port is a reference to the custom Scheme port which contains the procedure.
integer read-block port buffer offset count
Reads up to count bytes into the given binary buffer at position offset. The number of actual bytes read are returned as an integer value, or -1 if the end of stream has been reached. port is a reference to the custom Scheme port which contains the procedure.
integer available port
Returns a count of the number of bytes which are available for reading. This number need not be accurate.
undefined close port
Closes the port.
make-custom-character-output-port &procedure; character-output-port make-custom-character-output-port write write-string flush close
Creates a character-output-port whose functionality is implemented by the four provided fundamental procedures. The fundamental procedures required are as follows: undefined write port byte
Writes a character represented as an integer value. port is a reference to the custom Scheme port which contains the procedure.
void write-string port string offset count
Writes count characters from the given string at position offset. port is a reference to the custom Scheme port which contains the procedure.
undefined flush port
Flushes any unwritten characters to the stream.
undefined close port
Closes the port.
make-custom-binary-output-port &procedure; binary-output-port make-custom-binary-output-port write write-block flush close
Creates a binary-output-port whose functionality is implemented by the four provided fundamental procedures. The fundamental procedures required are as follows: The fundamental procedures required are as follows: undefined write port byte
Writes a byte represented as an integer value. port is a reference to the custom Scheme port which contains the procedure.
void write-block port buffer offset count
Writes count bytes from the given binary buffer at position offset. port is a reference to the custom Scheme port which contains the procedure.
undefined flush port
Flushes any unwritten characters to the stream.
undefined close port
Closes the port.
Finally, the underlying procedures which implement a custom port can be retrieved with the following function:
custom-port-procedures &procedure; list custom-port-procedures custom-port
Returns the procedures which implement a custom port as a list.
As an example, here are String Ports, implemented as user defined ports: User defined string ports (import custom-io) ;; String Input Ports (define (sio/read port) (let ([local (port-local port)]) (let ([ptr (vector-ref local 1)]) (if (= (vector-ref local 2) ptr) -1 (let ([c (char->integer (string-ref (vector-ref local 0) ptr))]) (vector-set! local 1 (+ ptr 1)) c))))) (define (sio/read-string local buffer offset length) (let ([local (port-local port)]) (let ([str (vector-ref local 0)] [strlen (vector-ref local 2)]) (do ([i offset (+ i 1)] [j (vector-ref local 1) (+ j 1)] [c 0 (+ c 1)]) ((or (= i (+ offset length)) (= j strlen)) (vector-set! local 1 (+ ptr 1)) c) (string-set! buffer i (string-ref str j)))))) (define null (lambda args (void))) (define (open-input-string str) (unless (string? str) (error 'open-input-string "expected string, got '~a'.~%" str)) (let ([port (make-custom-character-input-port sio/read sio/read-string null null)]) ; Use the port local value to store the string and a pointer ; for the current position (set-port-local! port (vector str 0 (string-length str))) port)) ;; String Output Ports (define (sio/write port char) (set-port-local! port (cons char (port-local port)))) (define (sio/write-string port string offset length) (set-port-local! port (append (reverse (string->list (substring string offset (+ length offset)))) (port-local port)))) (define (open-output-string) (let ([port (make-custom-character-output-port sio/write sio/write-string null null)]) (set-port-local! port '()) port)) (define (get-output-string port) (flush-output-port port) (let ([str (apply string (reverse (port-local port)))]) (set-port-local! port '()) str))
Miscellaneous Pretty-Printing &SISC; includes a pretty-printer, a function that behaves like write, but introduces whitespace in order to make the output of data more readable to humans.
pretty-print &procedure; unspecified pretty-print value output-port
Pretty-prints the specified value, either to the specified output-port, or to the console if no output-port is specified.
Source Loading The load procedure accepts URLs as well as ordinary file names. See for details on what kinds of URLs are supported. The file name passed to load is resolved relative to the current-url parameter. During the execution of load, current-url is set to the loaded file, so that any invocations of load from the loaded file resolve the given file name relative to the file currently being loaded. For example, lets assume we have a web site that serves the following files: ;;;contents of http://foo.com/bar/bar1.scm ;;; (load "bar2.scm") ;;;contents of http://foo.com/bar/bar2.scm ;;; (load "/baz/baz1.scm") ;;;contents of http://foo.com/baz/baz1.scm ;;; (load "../baz/baz2.scm") ;;;contents of http://foo.com/baz/baz2.scm ;;; (display "Hello") Invoking (load "http://foo.com/bar/bar1.scm") results in each file being loaded; with the last file in the chain, baz2.scm, displaying Hello. The load function supports many types of files which contain executable code. load will attempt to determine (primarily by the file's extension) which type of file is being loaded to load that file in the correct manner. The file types currently supported are those described in . When a pure source file is loaded, each s-expression is evaluated in sequence, exactly as if entered into the REPL one s-expression at a time. Location Tracking &SISC; allows the location of input, i.e. the file name, line number, and column number, to be tracked when reading from an input port.
open-source-input-file &procedure; input-port open-source-input-file url
This procedure behaves the same as open-input-file, except that it also tracks the location of the input.
input-port-location &procedure; list input-port-location input-port
Returns the current location information associated with input-port. The return value is an association list containing the following keys: source-file, line-number, column-number. If no location information is available, #f is returned.
Locating Resources &SISC; provides a mechanism for locating and subsequently loading named resources, such as Scheme source files, Scheme data files, property files. The resources are located using the mechanism described in . This allows Scheme programs to load resources in a portable, J2EE-compliant manner.
find-resource &procedure; url find-resource string
Locates the resource named by string on the Java class path. The resource location is returned as a URL suitable for &SISC; I/O operations. If the resource cannot be found, #f is returned.
find-resources &procedure; url-list find-resources string
Locates the resource named by string on the Java class path. The resource locations are returned as a list of URLs suitable for &SISC; I/O operations. If the resource cannot be found, an empty list is returned.
File Manipulation &requires; (import file-manipulation) The file-manipulation library provides access to a number of functions for reading and manipulating files and their attributes. The file-manipulation library acts on filenames in the same manner as other Scheme file related functions, e.g. it accepts file and directory names as strings, which are resolved relative to the current URL. The following functions act on both files and directories. With the exception of file-exists? and get-parent-url, the behavior when applying these to non-existant files or directories is undefined.
file-delete! &procedure; #t/#f file-delete! filename
Attempts to remove the given file or directory. If successful, #t is returned.
file-hidden? &procedure; #t/#f file-exists? filename
Returns true if the given file or directory exists.
file-is-directory? &procedure; #t/#f file-is-directory? filename
Returns true if the given string names an existing directory.
file-is-file? &procedure; #t/#f file-is-file? filename
Returns true if the given string names an existing file.
file-last-modified &procedure; integer file-last-modified filename
Returns the number of milliseconds since the Unix epoch (Jan 1, 1970) of the date the file or directory was last modified.
file-rename! &procedure; #t/#f file-rename! source-filename dest-filename
Renames the given source file or directory to the destination. This can be used both to rename a file or directory or to move a file/directory in the same filesystem. If successful, #t is returned.
file-set-last-modified! &procedure; #t/#f file-set-last-modified! filename unixtime
Sets the last modified date of the given filename to the given integer (in number of milliseconds since the epoch). Returns #t if successful.
get-parent-url &procedure; string get-parent-url filename
Given any URL, returns the URL of its parent. For filenames, as an example, the parent directory is returned.
The following functions operate only on files. Their behavior when applied to directories or non-existant files is undefined.
file-is-readable? &procedure; #t/#f file-is-readable? filename
Returns #t if the file can be opened for reading.
file-is-writeable? &procedure; #t/#f file-is-writeable? filename
Returns #t if the file can be opened for writing.
file-length &procedure; integer file-length filename
Returns the length, in bytes, of the given file.
file-set-read-only! &procedure; #t/#f file-set-read-only! filename
Sets the given file read-only. Returns #t if successful.
Finally, the following functions are specific to directories. Their behavior on files is undefined. The behavior of directory-list is undefined on non-existant directories.
directory-list &procedure; list of strings directory-list directory
Retrieves the children of the given directory, as a list of strings. Each string names one child, and is a filename relative to the given directory.
make-directory! &procedure; #t/#f make-directory! directoryname
Attempts to creates the given directory. Returns #t if successful.
make-directories! &procedure; #t/#f make-directories! directoryname
Attempts to creates the given directory and all non-existing parent directories. Returns #t if successful.
Class Loading Some &SISC; features require classes and other resources to be loaded. By default, &SISC; will use the current thread's class loader, or, if none is present, the system class loader. &SISC; maintains a list of class path extensions onto which class and resource loading falls back. This list can be inspected and extended using the following functions:
class-path-extension ¶meter; string-list class-path-extension
Retrieves the current class path extension. The class path extension is a list of strings representing URLs, typically pointing to jar files or directories. It is used a fall back during class and resource loading.
class-path-extension-append! ¶meter; undefined class-path-extension-append! class-path
Appends a list of URLs to the current class path extension. The elements of the class-path list are normalized using the current-url (see ), thus permitting the usage of relative URLs.
Note that the class path extension is part of the dynamic environment,, so each thread has its own setting, initially inherited from the parent thread. See for more details on &SISC;'s threading semantics.
sisc-1.16.6.orig/doc/sss/version.xml0000644000175000017500000000073411445752462015733 0ustar amoeamoe This document describes functionality present in &SISC; version 1.16.4. Some of the document may apply to previous and future versions. When in doubt, the source of this document can be found in the &SISC; CVS repository, or in the packaged source distribution that should be available wherever the binary distribution was obtained. sisc-1.16.6.orig/doc/sss/index.xml0000644000175000017500000000030311445752462015345 0ustar amoeamoe Index of Functions, Parameters, and Syntax sisc-1.16.6.orig/doc/sss/sss.xml0000644000175000017500000004430011445752462015053 0ustar amoeamoeSISC"> 5RS"> syntax: "> returns: "> procedure: "> parameter: "> Requires: "> ]> &SISC; <emphasis>for Seasoned Schemers</emphasis> Scott G. Miller Matthias Radestock Februrary 2007 2002-2007 Scott G. Miller, Matthias Radestock This documentation 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 of the License, or (at your option) any later version. The source code refers to the DocBook XML source files. The object code refers to the generated HTML, PostScript, PDF, and other forms. This documentation 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 (in ) along with this documentation; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA &intro-chapter; &inst-chapter; &scheme-chapter; &debugging-chapter; &io-chapter; &threads-chapter; &oo-chapter; &java-chapter; &library-chapter; &modules-chapter; &extensibility-chapter; Errata This appendix describes where this manual and the implementation of SISC depart. This section should ideally remain small or empty, as it is the goal of the system to conform to this document, not for this document to describe the idiosyncrasies of the system. &R5RS; Liberties and Violations This section lists all ways in which &SISC; interprets the &R5RS; specification, where the standard is not particular clear. Such interpretations may allow non-portable code to be written and executed on &SISC;. Additionally, all known &R5RS; violations are listed. Actual violations are considered &SISC; bugs, and have a high priority for being fixed. Violations of the standard are written in bold text. 2.3 - &SISC; allows identifiers to start with '+', '-', or '.' if they cannot be read as numbers. 2.3 - &SISC; uses the reserved characters '[' and ']' as synonyms for '(' and ')' respectively. 2.3 - &SISC; does not raise any warning or error when encountering the reserved characters "[]{}|", and allows "{}|" to appear in identifiers. 4.1.3 - &SISC; does not distinguish between () and the quoted empty list '(). 6.2.3 - The standard desires that that operations such as sqrt try to provide exact results when given exact arguments. While &SISC; meets the requirement for sqrt, it is not clear what other mathematical functions should have this behavior. &SISC; takes no heroic efforts to meet this requirement. 6.2.6 - &SISC; allows radixes other than those specified in the contract for number->string and string->number. In particular, any radix up to 36 is allowed, and any unsupported value causes &SISC; to revert to base 10. 6.5 - &SISC; currently returns an environment from the scheme-report-environment which contains four bindings not specified in &R5RS;, bindings which are needed by &R5RS; syntactic keywords. 6.6.2 - &SISC; currently only warns when end-of-file is reached in read, rather than signaling an error. The unterminated datum is discarded. All of the liberties described above are implemented for the convenience of the programmer. If desired, strict &R5RS; syntax and semantics may be enabled with the strictR5RSCompliance configuration parameter (see ), causing &SISC; to raise errors in all &R5RS; situations that result in "an error", as well as respect the lexical syntax's reserved characters. When in strict compliance mode, the above mentioned deviations no longer apply and &SISC; is entirely &R5RS; compliant. Troubleshooting This appendix covers issues with running &SISC; in certain environments. Kaffe There is a known limitation with Kaffe, whose default stack size is too small for &SISC; to parse s-expressions. To fix this, either edit the &SISC; startup scripts to pass -Xss32m, or set the JAVAOPT environment variable to the same. Backend Details This appendix is under development This appendix describes details of &SISC; on particular backends. This is not intended to guide programming. The programmer should code according to the main body of this document. However, this section still describes useful performance tips and limitations of &SISC;'s operation. Limits This appendix lays out the various limits in &SISC; running on a JVM backend. These limits are not specifications for an expected set of limits on all platforms, but serve as a real-world guide. Datastructure Limits &SISC; Limits Description Limit Fixed-point Exact Integers -231 < n < +231-1 AP Exact Integers -2(232-1) < x < +2(232-1)-1. Inexacts (32Float) See IEEE 754-1985 Floating Point Standard Inexacts (64Float) See IEEE 754-1985 Floating Point Standard Inexact Mantissa (APFloat) same as AP Exact Integers Inexact Exponent (APFloat) same as fixed-point exact integer Max vector elements Same as max fixed-point integer Max string elements Same as max fixed-point integer (?) Representable characters see Maximum formal parameters Same as max fixed-point integer Maximum lexical depth Same as max fixed-point integer Maximum symbolic-environment bindings Same as max fixed-point integer (?) Addressable file size min of 264-1 and operating system limit
Arbitrary precision integers aren't quite arbitrary precision. &SISC; has a hard limit to the number of bits in an exact integer and thus to the range of representable numbers. Exact integers are stored as two's complement signed integers, with a bit limit (including the sign bit) of 232. This limits the range of representable exact integers to the numbers quoted above. Likewise, arbitrary precision inexact numbers (when present) have a similar hard limit. The arbitrary precision inexact is constructed with an arbitrary precision exact number with the limits described above as the number's mantissa, and an exponent whose range is equivalent to that of a fixed-point exact integer. The inexact is then then mantissa*10exponent.
Symbol Uniqueness In order to support compilation in multiple threads, on multiple machines, or in multiple times, generated symbols for module bindings, lexical variables, etc. must be 4d-unique, that is they must be unique across space and time. &SISC; attempts to balance this requirement with the space inefficiency of generating symbols with very long names. &SISC;'s unique symbols are generated by creating a number of the form current-time + (random-16-bit-natural*311040000000) + (counter*155520000000). The current time variable is only updated when the value of counter reaches 65536. In this manner, two entities that generate the same symbol will only generate a colliding symbol if they generate the symbol on the same system millisecond, with the same counter value, and the same random number, or, if one entity happens to generate the symbol with the same millisecond and does so (counter-1)*50 years, (counter-2)*100 years... in the future, and with the same random or (random-1)*100 years, (random-2)*200 years, etc in the future. Only if all of these factors align will a colliding symbol be generated. This is not as unlikely as say a Microsoft GUID or Java VMID number, but it should be sufficiently unlikely. The advantage over other GUID algorithms is that the value produced by &SISC;'s is significantly smaller (and thus does not bloat expanded code).
Performance and Efficiency considerations Math The &SISC; numeric library is most efficient when operating on fixed bitlength numbers. Exact numbers are in their fixed bitlength mode if they are in the representable range for fixed exact integers, as described in . Fixed bitlength inexact numbers are only available in the 64Float and 32Float libraries. For &SISC; on Java on the x86 32-bit architecture, the 64Float library is generally more efficient than the 32Float library, while both are more efficient than the APFloat library. Fixed bitlength exact integers are only used for whole numbers. Rational numbers use arbitrary precision components and thus are less efficient than whole fixed integers. Arbitrary precision inexact numbers are progressively slower as the bitlength of the mantissa and the scale of the exponent increase. Using the precision constraints can prevent an unbounded increase in the scale of arbitrary precision inexacts which will very rapidly slow calculations. Strings At the time of this writing, the Scheme string type can be represented either as a character array, a native string, or simultaneously as both. The character array representation allows efficient, constant time modification of a mutable string (using string-set! for example). The native string representation allows efficient output to ports, string comparison, and substring operations. By default, &SISC; allows the Scheme string to contain both representations simultaneously, ensuring that there is not a costly representation conversion necessary to perform certain operations. However, in this default mode, strings may occupy twice the memory as a string in a single representation. If a program uses many strings or several very large strings, the programmer may wish to create strings that may only be in one representation at any given time. &SISC; provides a parameter to control this behavior.
compact-string-rep ¶meter; #t/#f compact-string-rep boolean
This parameter, if set #t, will force strings to be represented either as a character array, or as a native string, but never both. If false, simultaneous representations are possible.
Interrupts Interrupts allow running Scheme code to be forcibly broken from another thread, causing the Scheme code to raise an error. The interrupt signal handling code does add an appreciable overhead (usually between 1-5% depending on the JVM) to execution. It can disabled using the sisc.permitInterrupts system property.
&gpl; &index;
sisc-1.16.6.orig/doc/sss/threads.xml0000644000175000017500000011723111445752462015701 0ustar amoeamoe Threads and Concurrency &requires; (import threading) &SISC; provides a comprehensive library for executing Scheme code in parallel in multiple concurrent threads. This allows code for simple code for handling blocking I/O sources (such as network servers) or for the ability to do parallel computation across multiple processors. In addition, functions are provided to ensure mutually exclusive access to data (mutexes), to assign priorities to Scheme threads, and for inter-thread signaling and synchronization. Scheme Thread Semantics Care has been taken to ensure that Scheme code executing concurrently in two or more threads does not result in unpredictable behavior. Assuming the executing threads do not share data, executing code in multiple threads should behave just as executing the code in a single thread. All threads executing in the system share some resources. The top-level and symbolic environments are shared by all threads. If a thread makes a change to these environments, the change will be visible in all other threads. Unless changed by the thread, all threads share the same console input and output ports. As threads originate from a thunk created in the primordial thread or a child thread, the lexical environment captured by the thunk may include some lexical variables from the parent thread. These variables will be visible by both the parent and child threads. The lexical environments created in an executing thread are visible by that thread only (unless that thread spawns a child thread whose thunk binds its parent's lexicals). Some resources can be shared but may also be distinct from thread to thread. These resources are inherited from the parent thread, but may be changed by the child or parent without affecting the other. The dynamic environment (including the console input and output port, parameters, etc.) are inherited from the parent, as is the dynamic-wind stack. When a thread begins, it is considered to be isolated from its parent in terms of the dynamic-wind stack. If a parent spawns a thread in the during section of a dynamic-wind call, the spawned thread escapes the restrictions of the dynamic-wind call. This is logical, as the parent thread may then exit from the dynamic extent even as the child thread executes, or may remain there waiting for the child thread to finish, in which case the parent has not left the dynamic extent of the call. In short, the dynamic-wind is protecting only the parent thread. It is possible for more than one thread to access the same memory location (be it a lexical variable or a named variable in the top-level or another symbolic environment), it is also possible that interactions on shared variables can have unpredictable results. As in any multi-threaded language, unprotected access to shared variables can result in race conditions and other concurrency mishaps. If the programmer anticipates concurrent access to a shared variable and if any thread is to write to the variable, sections of code that access the variable should use a protection mechanism from . A thread can complete in one of two ways. If the thunk that contains the thread's code exits, the thread will terminate and the thread handle will contain the return value of the thunk. This completion condition is called a clean exit. If during the execution of the thunk's body an error is raised and is not subsequently caught, the thread will terminate and the thread handle will trap the error. The error will be raised to any caller that attempts to retrieve the return value of the thread. It is perfectly legal for a thunk to both capture and invoke continuations, even continuations created by other threads. When applying a continuation captured outside of the thread, the resources of the executing thread are used, though the thread may be accessing lexical environments created by other threads. Once created, a thread can be in one of four states: ready, running, finished, or finished-with-error. The first two states indicate a newly created thread and a running thread, repectively. The last two represent the end stages of a thread, finished indicating a thread that has exited cleanly, and finished-with-error indicating exit with an error. There are no guarantees that a Scheme thread will ever exit. It is perfectly valid for a thread to execute indefinitely. Furthermore, the &SISC; environment will not exit until all threads have completed, either cleanly or with a failure, unless all remaining threads are so-called daemon threads. Daemon threads are threads that may run indefinitely but will be forcibly terminated if no non-daemon threads (of which the primordial thread is one) are still running. Termination of a daemon thread when no non-daemon threads exist is the only instance where a thread can be forcibly terminated. There is no guaranteed thread stop or destroy operation. Basic Thread Operations This section describes the basic, low-level operations on threads, including how to create a thread, how to start it, how to wait for it to terminate, and how to retrieve its result. A thread is managed in Scheme by its thread handle, an opaque value that is used to identify the thread. A thread handle is present as an argument to most of the thread library functions. Threads are created with thread/new. This function takes as its sole argument a thunk. The body of the thunk is the code that the thread will execute when started.
thread? &procedure; #t/#f thread? value
Returns true if and only if the provided value is a thread handle.
thread/new &procedure; thread-handle thread/new thunk
Creates a new thread handle whose code is defined in the provided thunk.
Once a thread-handle is created, the thread is in the ready state, and can be started at any time by calling thread/start. At this point one can also set various thread parameters, such as thread priority and daemon status.
thread/start &procedure; undefined thread/start thread-handle
Starts the thread identified by thread-handle. The thread must be in the ready state. It is an error to start a thread in any other state.
thread/daemon! &procedure; undefined thread/daemon! thread-handle boolean
Sets the daemon status of a thread. It is an error to change the status of a thread that is not in the 'ready state.
thread/daemon? &procedure; #t/#f thread/daemon? thread-handle
Returns #t if the given thread is a daemon thread.
It is common pattern to create a thread and immediately start it. The convenience method thread/spawn encapsulates this operation.
thread/spawn &procedure; thread-handle thread/spawn thunk
Creates a new thread handle whose code is defined in the provided thunk, and starts the thread.
Once started, the thread will be in the running state. The body of the thunk is now being evaluated in parallel to the parent thread. The thread will remain in the running state until it completes and enters one of the two finished states. The state can be read using thread/state.
thread/state &procedure; symbol thread/state thread-handle
Returns the state of the thread identified by thread-handle. The state is one of 'ready, 'running, 'finished, or 'finished-with-error.
The parent thread may continue executing its own code, or may attempt to join the child thread. To join another thread is to wait until the other thread has completed. The parent thread can join a child using thread/join. The parent can wait indefinitely or may specify a timeout, after which the thread/join command will return with #f.
thread/join &procedure; boolean thread/join thread-handle timeout
Attempts to join with the indicated thread. If the thread terminates, thread/join will return a non-false value. If a timeout is specified thread/join will only wait timeout milliseconds for the thread to complete. If the thread does not terminate before the timeout, #f will be returned.
It is possible to join on an already completed thread. In such a case the join will immediately return #t. The behavior of a join on a thread in the ready state is unspecified, and may cause an error. Finally, it is possible that a join may return #f, even if no timeout is specified. Though unlikely, programmers who wish to wait indefinitely for a thread to complete should check the return value of thread/join and repeat the join until #t is returned. If enabled (using the permitInterrupts configuration parameter, see ), running threads may be interrupted at both the host language level and when executing Scheme code with the thread/interrupt function. If disabled (the default), only a host-language interrupt signal can be sent.
thread/interrupt &procedure; undefined thread/interrupt thread-handle
Sends an interrupt signal to the given thread. This will cause an error to be raised from Scheme code, and a thread interrupt in the host language.
When invoked, a signal is sent to the running thread which will cause an error to be raised from some point in its execution. If not caught, the thread will terminate in the finished-with-error state, and the raised error will be rethrown if thread/result is called. The error-continuation of the error thrown inside the thread, when invoked with no arguments, will restart the computation exactly where it left off. A thread may not properly resume if its code calls back into Scheme using any of the mechanisms described in . Final Continuation of a Thread If a thread is interrupted and later its computation is resumed by calling the error-continuation, the thread that hosts the resumed computation will exit when the computation terminates. As a consequence, if a computation that ran in a separate thread is resumed in the primordial thread (that usually hosts the REPL), the primordial thread will terminate as soon as the computation completes. This will circumvent the REPL entirely and cause &SISC; to exit if no non-daemon threads remain. In general, interrupted threads should be resumed in a newly created thread to avoid this scenario. It is important to note that thread/interrupt does not guarantee the termination of a thread. A thread may still capture the error at the scheme level with a with/fc, or catch the interrupt signal if executing in the host language. In either case, the running code is not required to rethrow the error. Once a thread has completed, the parent thread may wish to retrieve the result of the thread's thunk, be it an error or a valid result. This can be done with the thread/result function.
thread/result &procedure; value thread/result thread-handle
Returns the return value from a completed thread. If the thread completed with error, that error is raised from this call.
An error will be raised if an attempt is made to retrieve the result of a thread before that thread has completed.
High-level Functions In addition to the basic thread operations, some high level syntax is provided to simplify some general case thread use.
parallel &procedure; multiple values parallel thunk1 thunk2 thunks
Executes each thunk in its own thread in parallel. The call to parallel blocks until all the threads have finished. If all threads completed without error, the results of each thunk are returned as multiple values. If any thread raised an error, that error is raised from the call to parallel. The error is raised only after all other thunks have also completed. If more than one thunk raises an error, it is undefined which error will be raised to the caller.
Thread Scheduling All Scheme threads created in &SISC; are preemptive and managed by a scheduler. It is possible for a program to manage the priorities of threads in order to give execution preference to higher priority threads. It is also possible for threads to give up their execution time to other blocked threads. The priority of a thread is represented by an integer. The range of priorities and the default priority of a thread is unspecified and may be platform specific. Larger integers represent higher priorities then smaller integers. If a higher or lower priority thread is desired, the recommended procedure is to get the current priority of a thread and increment or decrement it. Though unspecified, it is possible that an error will be raised if a priority level outside the platform specific range is selected. Though not guaranteed, the behavior of the scheduler when two threads, one with higher priority than another are both runnable but only one processor is available to run a thread, is that the higher priority thread will be selected. If only equal priority threads are available to be run, the scheduler can choose any thread to run. No guarantees are made about latency or fairness. Thread priorities can be set by the parent thread or the thread itself. The behavior of a child thread attempting to set the parent's priority, or a sibling's priority is undefined.
thread/priority &procedure; integer thread/priority thread-handle
Retrieves the current priority of the given thread.
thread/priority! &procedure; undefined thread/priority! thread-handle new-priority
Attempts to set the given thread's priority to the integer new-priority.
In addition to setting priority levels, a program may wish to yield its execution time temporarily to other threads. Performing a yield allows the scheduler to select a thread to run on the processor of the thread that just yielded control. It is possible that the yielding thread may be selected again, or another thread may be chosen.
thread/yield &procedure; undefined thread/yield
Causes the currently executing thread to yield to other threads.
Finally, a thread (including the main thread) may sleep for a specified amount of time, allowing other threads to execute in the mean time. If no other threads are running, sleeping effectively pauses the program for the given time period.
sleep &procedure; undefined sleep milliseconds
Causes the currently executing thread to sleep for the given number of milliseconds, specified as an exact integer.
Synchronization Primitives &SISC; provides an implementation of mutexes and condition variables designed to support a wide range of synchronization models, including the monitor paradigm previously found in &SISC;. The implementation provides both a mutex and condition-variable first-class value for concurrency protection and inter-thread communication. Mutexes provide mutual exclusion locking, while condition variables faciliate synchronization of threads with the change in state of monitored data. &SISC;'s mutexes are reentrant, that is, if a thread locks a mutex and then attempts to lock it again, the lock is granted immediately- it does not block. Correspondingly, the mutex is not unlocked until the same number of unlock operations as previous lock operations are performed by the owning thread. &SISC;'s synchronization primitives map very closely to SRFI-18, which is supported by &SISC;. In fact, it is recommended that programmers write to SRFI-18 if at all possible, as they will gain maximum portability with little or no loss in efficiency on &SISC;. Throughout the following sections, a thread is often said to block because of some circumstance. While a thread is blocked on some resource, other threads are allowed to execute freely, at the discretion of the scheduler. Several functions exist for performing low level operations such as creating mutexes and condition variables. All require the mutex or condition variable as the first parameter. Mutexes are represented in Scheme as opaque values displayed as #<mutex> while condition variables are represented as #<condition-variable>. It is important to understand that all the synchronization operations depend on the same mutex and/or condition variable being shared between any threads using the functionality. Mutex Operations In order to protect a segment of Scheme code from concurrent access, one can create a mutex that is shared by all threads that may access the segment. When entering the contested region of code (the critical section), a thread would call mutex/lock. Upon exiting the region, mutex/unlock is called.
mutex? &procedure; #t/#f mutex? value
Returns true if and only if the provided value is a mutex.
mutex/new &procedure; mutex mutex/new
Creates and returns a new mutex object.
mutex-of &procedure; mutex mutex-of value
Returns a mutex that is uniquely associated to the given value. Subsequent (or concurrent) calls to this function are guaranteed to return the same mutex if given the same value.
mutex/lock! &procedure; undefined mutex/lock! mutex
Attempts to acquire the lock on the given mutex. Returns only when the lock has been successfully acquired.
mutex/unlock! &procedure; undefined mutex/unlock! mutex
Releases the lock on the given mutex. The behavior when unlocking a mutex when the running thread does not have the lock is undefined, and may raise an error.
The semantics of mutex/lock! ensure that only one thread can execute beyond the lock call at any one time. The first thread that reaches the call acquires the lock on the mutex. Any later threads will block at the call to mutex/lock! until the thread that owns the lock releases the lock with mutex/unlock!.
Condition Variable Operations A condition variable allows one thread to sleep until another wakes it. A common situation is for one thread to check the status of a variable, and sleep if the condition is not met. While the thread sleeps, one or more separate threads may execute and satisfy the condition (by changing the state of the variable) and then notify the sleeping thread via the condition variable. The thread then awakes, checks the state variable, and proceeds if the condition is met. If not, it sleeps again. This construct allows for cooperation between multiple threads on a computation. To wait on a condition variable, the mutex/unlock! function is again used with a condition variable as an additional argument. applied to a monitor. This will cause the thread to unlock the given mutex, then block until notified by another thread. When it is notified, or the provided timeout expires, the lock is not reacquired.
condvar? &procedure; #t/#f condvar? value
Returns true if the provided value is a condition variable.
condvar/new &procedure; condition variable condvar/new
Creates a new condition variable.
mutex/unlock! &procedure; #t/#f mutex/unlock! mutex condvar timeout
Causes the thread to sleep until notified on the provided condition variable by another thread. This call will not return until notified, unless the optional timeout is specified and timeout milliseconds have elapsed without a notification. Before blocking, the lock on mutex is released. If the timeout is reached before notification, #f is returned, otherwise #t is returned.
Another thread may wake a single waiting thread with the condvar/notify operation. When called, one thread waiting on the condition variable is woken. If no threads are waiting this call has no effect. If more than one thread is waiting, exactly one will be woken. Which is woken is unspecified. If a thread wishes to wake all threads waiting on a given monitor, it may use the condvar/notify-all function.
condvar/notify &procedure; undefined condvar/notify condvar
Wakes exactly one thread waiting on the condition variable, if any such threads exist. If the notifying thread holds the lock on condvar, the waiting thread will not proceed until the notifying thread releases the lock.
condvar/notify-all &procedure; undefined condvar/notify-all condvar
Wakes all threads waiting on the condition variable, if any waiting threads exist. If the notifying thread holds the lock on condvar, the waiting thread will not procede until the notifying thread releases the lock.
High-level Concurrency In addition to the low-level operations on mutexes and condition variables, two library functions are provided to greatly ease the construction and readability of thread-safe code.
mutex/synchronize &procedure; value mutex/synchronize mutex thunk
Protects execution of thunk as a critical section by holding the mutex's lock during evaluation of the thunk. The result of the thunk's evaluation becomes the result of the mutex/synchronize expression.
mutex/synchronize-unsafe &procedure; value mutex/synchronize-unsafe mutex thunk
Behaves exactly as mutex/synchronize without automatic unlocking when an error is raised or a continuation escapes when executing thunk.
mutex/synchronize locks the mutex while the thunk provided is being executed. The lock is automatically released when the expression has completed. Also, if an error is raised or a continuation is invoked that escapes the call to mutex/synchronize, the lock is automatically released. The added safety provided by mutex/synchronize may slow the execution of code that repeatedly calls a critical section. If the programmer is absolutely sure that no error can be raised and that no continuations will be applied to escape the call, mutex/synchronize-unsafe may be used. It provides no safety guarantees in those situations. If an error is raised or an escaping continuation invoked, the mutex will remain locked which could cause a deadlock if another thread attempts to acquire the lock.
sisc-1.16.6.orig/doc/sss/library.xml0000644000175000017500000023471111445752462015716 0ustar amoeamoe Additional Libraries Optional &SISC; Libraries The optional &SISC; libraries are modules whose definition is included in the full &SISC; distribution, but not the lite distribution. Definitions &requires; (import misc) In addition to the standard &R5RS; definition syntaxes, &SISC; provides an additional value definition and syntax definition form. First, define-values, which allows more than one binding to be created at once, given the multiple-value return of its body.
define-values &syntax; undefined define-values (binding binding ) expression
Evaluates the expression in the body, which must return the same number of values as there are binding names. Each value is then bound (in an undefined order) to each binding name.
define-values behaves like define in terms of which environment the bindings are created. If the define-values statement is at the top-level then bindings are created in the top-level environment. If the statement is in a lexical environment, then it behaves just as an internal define. Second, define-simple-syntax provides a shorthand for syntax definition when the syntactic form's appearance is similar to a function.
define-simple-syntax &syntax; undefined define-simple-syntax (name vars ) body
Creates a syntactic form with the given name, and any number of listed syntactic variables, which expands to the given body (with instances of the syntactic variables hygienically expanded).
Here is an example usage of define-simple-syntax to define the when macro: (define-simple-syntax (when condition body ...) (if condition (begin body ...)))
Bitwise Logical Operations &requires; (import logicops) In addition to the &R5RS; set of procedures that deal with numbers, &SISC; provides operators for performing bitwise logic operations on exact integers.
logand &procedure; integer logand integer integer
Performs the logical AND of all the provided arguments.
logor &procedure; integer logor integer integer
Performs the logical OR of all the provided arguments.
logxor &procedure; integer logxor integer integer
Performs the logical exclusive-OR of all the provided arguments.
lognot &procedure; integer lognot integer
Performs the logical NOT of the provided integer.
logcount &procedure; integer logcount integer
Returns the count of the number of 1 bits in the representation of a given positive integer, or 0 bits in a negative integer.
In addition, two operators are provided to perform arithmetic shifts on any integer (these operators do not have the range limitation the previous logical functions do). The shift operators return a newly generated number formed by shifting the provided number left or right by the given number of bits.
ashl &procedure; integer ashl integer bits
Arithmetically shifts integer left by bits bits.
ashr &procedure; integer ashr integer bits
Arithmetically shifts integer right by bits bits.
Mathematically, if r is the number, and s is the number of bits, ashl calculates: r x 2s while ashr calculates r / 2s in the integer domain. Both ashl and ashr operate on exact integers and produce only exact integers.
Records &requires; (import record) &SISC; provides a native implementation of record types as defined in SRFI-9. See for details. In addition to the define-record-type syntax provided by SRFI-9, a more compact (but less flexible) define-struct syntax is offered. define-struct &syntax; define-struct name (field ...)
Defines a SRFI-9 record type as follows: (define-record-type (make-name field ...) name? (field name-field set-name-field!) ...) i.e. naming conventions are used to determine the names of the record type constructor, predicate, field access and field modifier procedures.
Records are eq? and eqv? if and only if they are identical. Records are equal? if and only if they are instances of the same record type and all their fields are equal?. It is also possible to define non-generative record types, using define-nongenerative-record-type and define-nongenerative-struct. Non-generative record types are associated with a user-specified guid. If an attempt is made to define a record type with a guid that is already bound to an existing record type then the existing record type is modified, instead of a new record type being created. Non-generative record types are serialised specially such that deserialising them also performs this check. By contract, deserialisation of ordinary, generative record types and their instances results in duplicate types being created, which is usually not desirable. define-nongenerative-record-type &syntax; define-nongenerative-record-type name guid (constructor-name field ...) (predicate ...) (field-spec ...)
This is the same as define-record-type, except that the resulting record type is non-generative with guid, a symbol, as the unique identifier.
define-nongenerative-struct &syntax; define-nongenerative-struct name guid (field ...)
This is the same as define-struct, except that the resulting struct is non-generative with guid, a symbol, as the unique identifier.
Hash Tables &requires; (import hashtable) Hash tables store mappings of keys to values. Hence they are similar to association lists, except that hash tables allow retrieval, addition and modification in constant time whereas association lists typically perform these operations in linear time based on the number of elements. Creation and Introspection Hash tables are a distinct data type. They can be created empty or filled with the contents of an association list. The converse, creating an association list from a hash table, is also supported.
make-hashtable &procedure; hashtable make-hashtable equivalence-predicate hash-function thread-safe? weak?
Creates a hash table. The first optional argument supplies the equivalence test procedure that the hashtable should use for comparison of keys. This must be a function accepting two arguments and returning a boolean. It defaults to equal?. The second optional argument supplies the hash function, which must accept one argument and return a numeric value. For the equivalence predicates eq?, eqv?, equal?, string=?, string-ci=? it defaults to hash-by-eq, hash-by-eqv, hash-by-equal, hash-by-string=, hash-by-string-ci=? respectively, and hash-by-equal otherwise. The third optional argument determines whether operations on the hash table should be made thread-safe. The default is #t. Thread synchronization (see ) is required if there are potentially several threads operating concurrently on the hash table and one of these threads performs a structural modification (i.e. adds or removes an entry; merely changing the value of an entry is not a structural modification). Failure to enforce proper thread synchronization has unpredicatable results. The fourth optional argument determines whether the keys in the hash table are held with weak references, allowing them to be garbage collected, and automatically removed from the hashtable when they are not referenced from elsewhere. The default is #t. For reasons of disambiguation, the hash function argument can only be supplied if the preceeding equivalence predicate was also supplied, and the weakness argument can only be supplied if the preceeding thread-safety argument was also supplied. The equivalence and hash function must produce stable results for the keys in a hash table. The effects of invoking an escaping continuation inside the equivalence predicate or hash function, or invoking a continuation captured inside the equivalence predicate or hash function after that function has returned, are unspecified.
alist->hashtable &procedure; hashtable alist->hashtable alist equivalence-predicate hash-function thread-safe? weak?
Creates a hashtable and initializes it with the keys and values found in alist. alist must be a list of pairs, with the car of each pair representing a key and the cdr representing its associated value. The optional arguments are the same as for make-hashtable. If there are multiple pairs which contain the same key (with respect to chosen equivalence test) then the resulting hash table will associate the key with the value of the last such pair.
hashtable? &procedure; #t/#f hashtable? value
Returns #t if value is a hash table, #f otherwise.
hashtable/equivalence-function &procedure; procedure hashtable/equivalence-function hashtable
Returns the equivalence predicate of hashtable.
hashtable/hash-function &procedure; procedure hashtable/hash-function hashtable
Returns the hash function of hashtable.
hashtable/thread-safe? &procedure; #t/#f hashtable/thread-safe? hashtable
Returns #t if hashtable is thread safe, #f otherwise.
hashtable/weak? &procedure; #t/#f hashtable/weak? hashtable
Returns #t if the keys in hashtable are held by weak references, #f otherwise.
hashtable/size &procedure; number hashtable/size hashtable
Returns the number of key/value pairs stored in hashtable.
hashtable->alist &procedure; alist hashtable->alist hashtable
Returns an association list comprising the elements of hashtable. The list contains pairs whose cars are they keys found in hashtable and whose cdrs contain the associated values.
Hash Functions Several hash functions that return results consistent with common equivalence predicates are predefined.
hash-by-eq &procedure; number hash-by-eq value hash-by-eqv &procedure; number hash-by-eqv value hash-by-equal &procedure; number hash-by-equal value hash-by-string= &procedure; number hash-by-string= string hash-by-string-ci= &procedure; number hash-by-string-ci= string These procedures return a hash code of their argument that is consistent with eq?, eqv?, equal?, string=?, string-ci=?, respectively.
Access and Modification All hash table access operations follow a similar pattern. They return the value that was associated with the the given key at the time the operation was invoked. If no binding for the key existed, an optionally supplied value is returned that defaults to #f. This allows the programmer to associate keys with #f values and distinguish this case from not having any association for a key.
hashtable/put! &procedure; value hashtable/put! hashtable key val nobinding
Associates key with val in hashtable. Returns the previous association of key or nobinding, which defaults to #f, if key has no previous association.
hashtable/get &procedure; value hashtable/get hashtable key nobinding
Returns the value associated with key in hashtable, or nobinding, which defaults to #f, if key has no association.
hashtable/get! &procedure; value hashtable/get! hashtable key thunk unsafe?
Returns the value associated with key in hashtable. If key has no association then thunk is called and the result is associated with key in hashtable and also returned. The unsafe?, which defaults to #t, indicates whether thunk may invoke escaping continuations or raise errors. Setting unsafe? to #f results in more efficient execution but may cause deadlocks if thunk is unsafe. See also mutex/synchronize-unsafe in . When hashtable is thread-safe this operation is atomic.
hashtable/contains? &procedure; #t/#f hashtable/contains? hashtable key
Returns the #t if hashtable contains an entry for key, #f otherwise.
hashtable/remove! &procedure; value hashtable/remove! hashtable key nobinding
Removes the association of key in hashtable. Returns the associated value of key or nobinding, which defaults to #f, if key has no association.
Bulk Operations Bulk operations are operations that apply to all elements of a hash table.
hashtable/clear! &procedure; hashtable/clear! hashtable
Removes all elements from hashtable.
hashtable/keys &procedure; list hashtable/keys hashtable
Returns the keys contained in hashtable.
hashtable/for-each &procedure; hashtable/for-each proc hashtable
Applies proc to each element of hashtable. proc is called with two parameters - the key and the value of the element.
hashtable/map &procedure; list hashtable/map proc hashtable
Applies proc to each element of hashtable. proc is called with two parameters - the key and the value of the element. The results of calling proc are returned as a list.
Binary Buffers &requires; (import buffers) Binary buffers provide an opaque container for a fixed amount of binary data. The binary buffer library provides a number of functions for creating and accessing those buffers. The buffer is very similar to a vector, in that it is a randomly accessable, zero-based structure. But as a tradeoff for space efficiency, binary buffers are only capable of storing bytes. The bytes are stored as 8-bit, unsigned fixed integers (of the range 0-255).
buffer? &procedure; #t/#f buffer? value
Returns true if and only if the provided argument is a binary buffer.
make-buffer &procedure; buffer make-buffer size fill-value
Creates a new buffer capable of storing size bytes. size must be a fixed non-negative integer. If provided, the value of all bytes in the buffer is initialized to fill-value. If not provided, the contents of the buffer is unspecified.
buffer &procedure; buffer buffer value
Creates a new buffer whose size is equal to the number of arguments given and whose contents are the bytes given as arguments.
buffer-length &procedure; fixed integer buffer-length buffer
Returns the capacity of the given buffer.
buffer-ref &procedure; fixed integer buffer-ref buffer index
Returns the byte at offset index in the specified buffer. It is an error if index is out of range.
buffer-set! &procedure; undefined buffer-set! buffer index new-value
Sets the byte at offset index of the specified buffer to the given fixed integer new-value. It is an error if index is out of range.
buffer-copy! &procedure; undefined buffer-copy! source-buffer source-offset dest-buffer dest-offset count
Copies count bytes starting from index source-offset in the source buffer to successive bytes starting at index dest-offset in the destination buffer. If count is unspecified, it is assumed to be the length of the source buffer. It is an error to copy more bytes from the source buffer than are available, or to copy more bytes into the destination buffer than its capacity allows.
Buffers are serializable (can exist in loadable libraries or a &SISC; heap), but are not representable in an s-expression. For this reason, they bear the printed representation of #<buffer>.
Procedure Properties &requires; (import procedure-properties) &SISC; allows key/value bindings to be associated with procedures. This has a number of applications. For instance, generic procedures store their methods in a procedure property. Keys must be symbols. Values are any valid Scheme value. All operations are thread-safe.
procedure-property &procedure; value procedure-property proc symbol nobinding
Returns the value associated with the property symbol of procedure proc, or nobinding, which defaults to #f, if the property is not set.
set-procedure-property! &procedure; value set-procedure-property! proc symbol val nobinding
Sets the property symbol of procedure proc to the value val. Returns the previous value of the property or nobinding, which defaults to #f, if the property was unset.
procedure-property! &procedure; value procedure-property! proc symbol thunk unsafe?
Returns the value associated with the property symbol of procedure proc. If the property is unset then thunk is called and the property is set to the result, which is also returned. The unsafe?, which defaults to #t, indicates whether thunk may invoke escaping continuations or raise errors. Setting unsafe? to #f results in more efficient execution but may cause deadlocks if thunk is unsafe. See also mutex/synchronize-unsafe in .
Loadable Scheme Libraries &requires; (import libraries) This module gets imported by default. Scheme code can be packaged into libraries that can have dependencies on other libraries and can be loaded as required. Libraries are identified by a name that follows Java package file naming conventions, i.e. using path-style names typically containing domain, organisation name, project name and library name. For instance, if company Foo produces a library Baz for project Bar and that library contains three files, the file structure might look as follows: com/foo/bar/baz.scm com/foo/bar/baz/baz1.scm com/foo/bar/baz/baz2.scm com/foo/bar/baz/baz3.scm This library can be made accessible from &SISC; by adding the base directory or a jar file containing these files to the Java class path. Libraries are loaded by the following procedure.
require-library &procedure; undefined require-library name
Checks whether the library identified by name (a string), has already been loaded and, if not, loads it. An error is raised if the library cannot be found. Libraries are loaded using the load procedure from a resource located by the find-resource procedure. The name of the resource is derived from the name of the library by appending ".scc", ".sce" and, if that does not succeed, ".scm".
Note that require-library only loads a single file. The definition of dependencies on other libraries and the loading of other files therefore needs to happen within that file. For instance, the file com/foo/bar/baz.scm from the above example might contain the following: (require-library 'com/foo/bar/boo) (load "baz/baz1.scm") (load "baz/baz2.scm") (load "baz/baz3.scm") It is possible to programmatically check whether a particular library exists and whether it has been loaded:
library-exists? &procedure; #t/#f library-exists? name
Returns #t if the library identified by name (a string) exists, #f otherwise.
library-loaded? &procedure; #t/#f library-loaded? name
Returns #t if the library identified by name (a string) has been loaded, #f otherwise.
Operating System Interface &requires; (import os) The operating system interface currently contains functions for spawning external processes on the host operating system, obtaining input/output ports to the resulting process, and monitoring their status. Two procedures exist for spawning processes:
spawn-process &procedure; process spawn-process program/commandline arglist
Spawns a process, returning a process handle. If the optional argument list is provided, then the first argument is the binary to run with those arguments. If omitted, the first argument is tokenized as a commandline and used to spawn the process.
spawn-process-with-environment &procedure; process spawn-process-with-environment program arglist environment working-directory spawn-process/env &procedure; process spawn-process/env program arglist environment working-directory
Spawns a process named by program with the arguments given in arglist, in the given environment. The environment is an association list of strings to strings. The key in the association list is an environment variable name, and the corresponding value is the value to assign to that environment variable. If the environment parameter is #f, the environment variables of the current &SISC; instance are used. The optional parameter working-directory specifies the directory which will be set as the current directory when the process is spawned. If ommited, the value of the current-directory parameter (i.e. the current directory of the running Scheme program) is used instead.
process? &procedure; #t/#f process? value
Returns #t if the given value is a process handle.
Once started, a process will run in parallel to the current Scheme program according to the usual scheduling of the host platform. The process handle obtained can be used to obtain the input, output, and error streams of the process using the following functions:
get-process-stdout &procedure; binary-input-port get-process-stdout process
Returns a binary input port which will read bytes which the given process has written to its standard output stream.
get-process-stderr &procedure; binary-input-port get-process-stderr process
Returns a binary input port which will read bytes which the given process has written to its standard error stream.
get-process-stdin &procedure; binary-output-port get-process-stdin process
Returns a binary output port which when written to will send bytes to the given process' standard input stream.
Finally, functions are provided to check the status of a spawned process, and to wait for a process to complete:
process-terminated? &procedure; integer or #f process-terminated? process
Checks to see if the given process has terminated, and returns the process' return code if so. If the process is still running, #f is returned.
wait-for-process &procedure; integer or #f wait-for-process process
Waits for the given process to terminate, and returns the process' return code if so. The wait operation may be interrupted by other code, in which #f is returned.
Third-Party Libraries &SISC; provides hooks for accessing a number of third-party Scheme libraries. This functionality has not undergone much testing. SRFIs The Scheme Requests For Implementation (SRFI) process aims to coordinate libraries and other additions to the Scheme language between different Scheme implementations. For details see which describes the process and contains a list of all available SRFIs. SRFI Modules In &SISC; each SRFI is encapsulated in a module. See for details of &SISC;'s module system. The definitions for SRFI modules are not included in the standard &SISC; heap build and hence must be loaded separately from various compiled library files in the sisc-lib.jar jar file in the root directory of the &SISC; binary distribution. As long as this jar file is on the classpath, which is the case by default, any SRFI's module definition may be loaded with the expression (require-library 'sisc/libs/srfi/srfi-n), where n is the SRFI's number. For example: (require-library 'sisc/libs/srfi/srfi-9) All SRFI's may be loaded at once by requiring sisc/libs/srfi. Using SRFIs &SISC; currently supports SRFIs 0, 1, 2, 5, 6, 7, 8, 9, 11, 13, 14, 16, 18, 19, 22, 23, 25, 26, 27, 28, 29, 30, 31, 34, 35, 37, 38, 39, 40, 42, 43, 45, 48, 51, 54, 55, 59, 60, 61, 62, 66, 67, 69 and 78. Once the SRFI module definitions have been loaded as described above, a SRFI n can be imported using (import srfi-n) e.g. (import srfi-1) (xcons 1 2) ;=> (2 . 1) SRFI modules, like all modules in &SISC;, can be imported/used by other modules. Doing so does not pollute the top-level environment with the definitions exported by the module, i.e. any code outside the importing module remains unaffected. If, however, an SRFI is to be imported into the top-level, one can use the require-extension mechanism (see ). SRFI Extensions Some SRFIs have built-in extension points that Scheme implementations can use to augment a SRFI's functionality. It is also the case that some SRFIs would benefit from slightly extended APIs. This section documents the SRFI extensions implemented by &SISC;. SRFI 69 (Basic hash tables) The make-hash-table function takes two additional optional arguments: thread-safe? and weak?. See make-hashtable in for details. The basic hash table API is extended in a separate module:
&requires; (import srfi-69-ext) hash-table-thread-safe? &procedure; #t/#f hash-table-thread-safe? hashtable
Returns #t if hashtable is thread safe, #f otherwise.
hash-table-weak? &procedure; #t/#f hash-table-weak? hashtable
Returns #t if the keys in hashtable are held by weak references, #f otherwise.
hash-table-ref! &procedure; value hash-table-ref! hashtable key thunk
Returns the value associated with key in hashtable. If key has no association then thunk is called and the result is associated with key in hashtable and also returned. When hashtable is thread-safe this operation is atomic.
hash-table-ref!/default &procedure; value hash-table-ref! hashtable key default
Returns the value associated with key in hashtable. If key has no association then default is associated with key in hashtable and also returned. When hashtable is thread-safe this operation is atomic.
SLIB The SLIB portable scheme library provides compatibility and utility functions for standard Scheme implementations. It is supported by many Schemes, including &SISC;. Downloading and Installation The latest version of SLIB is available from as both a zip file and RPM. The site also hosts an online version of the SLIB manual. Download SLIB and install it in a convenient location. The RPM will by default be installed in /usr/share/slib/. Do not worry when you see some errors about missing programs such as mzscheme and scheme48 when installing the RPM - these happen because SLIB tries to auto-configure itself for various Schemes that you may not have installed on your system. Environment Using SLIB in &SISC; requires two Java system properties to be set: <envar>sisc.home</envar> This should (but does not actually have to) point to the location where you have installed &SISC;. If you are using one of the scripts from the binary &SISC; distribution in order to run &SISC; then this property will automatically be set to the value of the SISC_HOME environment variable. <envar>sisc.slib</envar> This must point to the location where you installed SLIB. Other Schemes supporting SLIB tend to use an environment variable SCHEME_LIBRARY_PATH, so it is advisable to define that (if it is not already defined) and run Java with a -Dsisc.slib=... option based on the environment variable. If you are using the scripts from the binary $SISC; distribution in order to run &SISC; then you can set the property by adding the -Dsisc.slib=... to the JAVAOPT environment variable. Note that the value of this property should be a fully qualified url, e.g. file:///usr/share/slib You need to ensure that all potential users of SLIB have read permissions to files in the directories referred to by the above system properties. Building the Catalog Make sure that the above system properties are set and that you have write permissions to the sisc.home directory; often this means you need to be logged in as a privileged user. Start &SISC; as you normally would. At the prompt type (require-library 'sisc/libs/slib) (require 'new-catalog) (exit) The above should create a file slibcat in the sisc.home directory. It is a good idea to check that this has indeed happened. Using <application>SLIB</application> Make sure the above system properties are set. Start &SISC; as you normally would. At the prompt load the &SISC; SLIB as described above, i.e. (require-library 'sisc/libs/slib) You can now load SLIB modules using require, e.g. (require 'tsort) (tsort '((shirt tie belt) (tie jacket) (belt jacket) (watch) (pants shoes belt) (undershorts pants shoes) (socks shoes)) eq?) loads the topological sorting module and invokes one of the procedures defined by it. Please refer to the SLIB manual for further details of what modules are available. Note however that, as with most other Schemes supported by SLIB, there will be some modules that are not available or do not work in &SISC;.
Creating Libraries &requires; (import libraries) &SISC; allows the creation of compiled libraries which contain compiled scheme code. These libraries can then be executed into a running &SISC; session in order to extend the functionality without processing or possessing the original source. Such libraries can be loaded using load as would any ordinary Scheme source file. Compiled code files (.scc) are created using the compile-file function, which takes a Scheme source file and a target output file, and processes the Scheme source through the various expansion and compilation phases, and then serializes the resulting &SISC; microexpressions to the given target file. The resulting file may then be loaded with load as any ordinary Scheme file would, or can be placed in the library path and resolved using require-library.
compile-file &procedure; undefined compile-file source-file target-file
Compiles the Scheme source present in source-file, writing the resulting micro-expressions into target-file, suitable for loading. As a side effect, the micro-expressions are also evaluated, i.e. in effect compile-file compiles and evaluates the source-file. The latter is necessary because the compilation of an expression may depend on the results of evaluating a previous expression, e.g. as is typically the case for libraries that depend on other libraries.
<literal>.sll</literal> Deprecation Scheme Loadable Libraries (.sll files) were deprecated in version 1.9. This was due to unresolvable incompatibilities in the engine's closure representation and the .sll functionality.
sisc-1.16.6.orig/doc/sss/dbefsyn.dsl0000644000175000017500000004205111445752462015660 0ustar amoeamoe;; This file is part of the Modular DocBook Stylesheet distribution. ;; See ../README or http://www.berkshire.net/~norm/dsssl/ ;; ;; ============================ CLASS SYNOPSIS ============================= (define %indent-classsynopsisinfo-lines% #f) (define %number-classsynopsisinfo-lines% #f) (define %default-classsynopsis-language% "java") (element classsynopsis (let ((language (if (attribute-string (normalize "language")) (attribute-string (normalize "language")) %default-classsynopsis-language%))) (case language (("scheme") (with-mode cs-scheme-mode (process-node-list (current-node)))) (("java") (with-mode cs-java-mode (process-node-list (current-node)))) (("perl") (with-mode cs-perl-mode (process-node-list (current-node)))) (("idl") (with-mode cs-idl-mode (process-node-list (current-node)))) (("python") (with-mode cs-python-mode (process-node-list (current-node)))) (else (with-mode cs-java-mode (process-node-list (current-node))))))) (element methodsynopsis (let ((language (if (attribute-string (normalize "language")) (attribute-string (normalize "language")) %default-classsynopsis-language%))) (case language (("scheme") (with-mode cs-scheme-mode (scheme-method-synopsis))) (("java") (with-mode cs-java-mode (java-method-synopsis))) ; (("perl") (with-mode cs-perl-mode ; (process-node-list (current-node)))) ; (("idl") (with-mode cs-idl-mode ; (process-node-list (current-node)))) ; (("python") (with-mode cs-python-mode ; (process-node-list (current-node)))) ; (else (with-mode cs-java-mode ; (process-node-list (current-node)))) ))) ;; ===== Java ======================================================== (mode cs-java-mode (element classsynopsis (let* ((classes (select-elements (children (current-node)) (normalize "ooclass"))) (classname (node-list-first classes)) (superclasses (node-list-rest classes))) (make display-group use: verbatim-style (make paragraph (process-node-list classname) (process-node-list superclasses) (literal "{")) (process-node-list (node-list-filter-by-gi (children (current-node)) (list (normalize "constructorsynopsis") (normalize "destructorsynopsis") (normalize "fieldsynopsis") (normalize "methodsynopsis") (normalize "classsynopsisinfo")))) (make paragraph (literal "}"))))) (element classsynopsisinfo ($verbatim-display$ %indent-classsynopsisinfo-lines% %number-classsynopsisinfo-lines%)) (element ooclass (make sequence (if (first-sibling?) (literal " ") (literal ", ")) (process-children))) (element oointerface (make sequence (if (first-sibling?) (literal " ") (literal ", ")) (process-children))) (element ooexception (make sequence (if (first-sibling?) (literal " ") (literal ", ")) (process-children))) (element modifier (make sequence (process-children) (literal " "))) (element classname (if (first-sibling?) (make sequence (literal "class ") (process-children) (literal " ") (if (last-sibling?) (empty-sosofo) (literal "extends "))) (make sequence (process-children) (if (last-sibling?) (literal " ") (literal ", "))))) (element fieldsynopsis (make paragraph (literal " ") (process-children) (literal ";"))) (element type (make sequence (process-children) (literal " "))) (element varname (make sequence (process-children))) (element initializer (make sequence (literal " = ") (process-children))) (element constructorsynopsis (java-method-synopsis)) (element destructorsynopsis (java-method-synopsis)) (element methodsynopsis (java-method-synopsis)) (element void (literal "void ")) (element methodname (make sequence font-weight: 'bold (process-children) (empty-sosofo))) (element methodparam (make sequence (if (first-sibling?) (empty-sosofo) (literal ", ")) (process-children))) (element parameter (process-children)) (element exceptionname (make sequence (if (first-sibling?) (literal " throws ") (literal ", ")) (process-children))) ) (define (java-method-synopsis #!optional (nd (current-node))) (let* ((modifiers (select-elements (children nd) (normalize "modifier"))) (notmod (node-list-filter-by-not-gi (children nd) (list (normalize "modifier")))) (type (if (equal? (gi (node-list-first notmod)) (normalize "methodname")) (empty-node-list) (node-list-first notmod))) (methodname (select-elements (children nd) (normalize "methodname"))) (param (node-list-filter-by-gi (node-list-rest notmod) (list (normalize "methodparam")))) (excep (select-elements (children nd) (normalize "exceptionname")))) (make sequence (literal " ") (process-node-list modifiers) (process-node-list type) (process-node-list methodname) (literal "(") (process-node-list param) (literal ")") (process-node-list excep) (literal ";")))) ;; ===== Scheme ====================================================== (mode cs-scheme-mode (element classsynopsis (let* ((classes (select-elements (children (current-node)) (normalize "ooclass"))) (classname (node-list-first classes)) (superclasses (node-list-rest classes))) (make display-group use: verbatim-style (make paragraph (process-node-list classname) (process-node-list superclasses) (literal "{")) (process-node-list (node-list-filter-by-gi (children (current-node)) (list (normalize "constructorsynopsis") (normalize "destructorsynopsis") (normalize "fieldsynopsis") (normalize "methodsynopsis") (normalize "classsynopsisinfo")))) (make paragraph (literal "}"))))) (element classsynopsisinfo ($verbatim-display$ %indent-classsynopsisinfo-lines% %number-classsynopsisinfo-lines%)) (element ooclass (make sequence (if (first-sibling?) (literal " ") (literal ", ")) (process-children))) (element oointerface (make sequence (if (first-sibling?) (literal " ") (literal ", ")) (process-children))) (element ooexception (make sequence (if (first-sibling?) (literal " ") (literal ", ")) (process-children))) (element modifier (make sequence (process-children) (literal " "))) (element classname (if (first-sibling?) (make sequence (literal "class ") (process-children) (literal " ") (if (last-sibling?) (empty-sosofo) (literal "extends "))) (make sequence (process-children) (if (last-sibling?) (literal " ") (literal ", "))))) (element fieldsynopsis (make paragraph (literal " ") (process-children) (literal ";"))) (element type (make sequence (process-children) (literal " "))) (element varname (make sequence (process-children) (literal " "))) (element initializer (make sequence (literal " = ") (process-children))) (element constructorsynopsis (scheme-method-synopsis)) (element destructorsynopsis (scheme-method-synopsis)) (element methodsynopsis (scheme-method-synopsis)) (element void (literal "void ")) (element methodname ($mono-seq$ (make sequence font-weight: 'bold (process-children)))) (element methodparam (let ((choice (attribute-string (normalize "choice"))) (rep (attribute-string (normalize "rep")))) ($mono-seq$ (make sequence ; (if (first-sibling?) ; (empty-sosofo) (literal " ");) (if (equal? choice (normalize "opt")) (literal "[") (empty-sosofo)) (process-children) (if (equal? choice (normalize "opt")) (literal "]") (empty-sosofo)) (if (equal? rep (normalize "repeat")) (make sequence (literal " ") (literal "...")) (empty-sosofo)))))) (element parameter (process-children)) (element exceptionname (make sequence (if (first-sibling?) (literal " throws ") (literal ", ")) (process-children))) ) (define (scheme-method-synopsis #!optional (nd (current-node))) (let* ((modifiers (select-elements (children nd) (normalize "modifier"))) (notmod (node-list-filter-by-not-gi (children nd) (list (normalize "modifier")))) (type (if (equal? (gi (node-list-first notmod)) (normalize "methodname")) (empty-node-list) (node-list-first notmod))) (methodname (select-elements (children nd) (normalize "methodname"))) (param (node-list-filter-by-gi (node-list-rest notmod) (list (normalize "methodparam")))) (excep (select-elements (children nd) (normalize "exceptionname")))) (make sequence (literal " ") (literal "(") (process-node-list methodname) (process-node-list param) (literal ") ") (if (node-list-empty? type) (empty-sosofo) (literal " => ")) (process-node-list type) (process-node-list excep)))) ;; ===== Perl ======================================================== (mode cs-perl-mode (element classsynopsis (let* ((modifiers (select-elements (children (current-node)) (normalize "modifier"))) (classes (select-elements (children (current-node)) (normalize "classname"))) (classname (node-list-first classes)) (superclasses (node-list-rest classes))) (make display-group use: verbatim-style; (make paragraph (literal "package ") (process-node-list classname) (literal ";")) (if (node-list-empty? superclasses) (empty-sosofo) (make sequence (literal "@ISA = ("); (process-node-list superclasses) (literal ";"))) (process-node-list (node-list-filter-by-gi (children (current-node)) (list (normalize "constructorsynopsis") (normalize "destructorsynopsis") (normalize "fieldsynopsis") (normalize "methodsynopsis") (normalize "classsynopsisinfo"))))))) (element classsynopsisinfo ($verbatim-display$ %indent-classsynopsisinfo-lines% %number-classsynopsisinfo-lines%)) (element modifier (literal "Perl ClassSynopses don't use Modifiers")) (element classname (if (first-sibling?) (process-children) (make sequence (process-children) (if (last-sibling?) (empty-sosofo) (literal ", "))))) (element fieldsynopsis (make paragraph (literal " "); (process-children) (literal ";"))) (element type (make sequence (process-children) (literal " "))) (element varname (make sequence (process-children))) (element initializer (make sequence (literal " = ") (process-children))) (element constructorsynopsis (perl-method-synopsis)) (element destructorsynopsis (perl-method-synopsis)) (element methodsynopsis (perl-method-synopsis)) (element void (empty-sosofo)) (element methodname (process-children)) (element methodparam (make sequence (if (first-sibling?) (empty-sosofo) (literal ", ")) (process-children))) (element parameter (process-children)) (element exceptionname (literal "Perl ClassSynopses don't use Exceptions")) ) (define (perl-method-synopsis #!optional (nd (current-node))) (let* ((modifiers (select-elements (children nd) (normalize "modifier"))) (notmod (node-list-filter-by-not-gi (children nd) (list (normalize "modifier")))) (type (if (equal? (gi (node-list-first notmod)) (normalize "methodname")) (empty-node-list) (node-list-first notmod))) (methodname (select-elements (children nd) (normalize "methodname"))) (param (node-list-filter-by-gi (node-list-rest notmod) (list (normalize "type") (normalize "void")))) (excep (select-elements (children nd) (normalize "exceptionname")))) (make paragraph (literal "sub ") (process-node-list modifiers) (process-node-list type) (process-node-list methodname) (literal " { ... }")))) ;; ===== IDL ========================================================= (mode cs-idl-mode (element classsynopsis (let* ((modifiers (select-elements (children (current-node)) (normalize "modifier"))) (classes (select-elements (children (current-node)) (normalize "classname"))) (classname (node-list-first classes)) (superclasses (node-list-rest classes))) (make display-group use: verbatim-style; (make paragraph (literal "interface ") (process-node-list modifiers) (process-node-list classname) (if (node-list-empty? superclasses) (literal " ") (make sequence (literal " : ") (process-node-list superclasses))) (literal "{")) (process-node-list (node-list-filter-by-gi (children (current-node)) (list (normalize "constructorsynopsis") (normalize "destructorsynopsis") (normalize "fieldsynopsis") (normalize "methodsynopsis") (normalize "classsynopsisinfo")))) (make paragraph (literal "}"))))) (element classsynopsisinfo ($verbatim-display$ %indent-classsynopsisinfo-lines% %number-classsynopsisinfo-lines%)) (element modifier (make sequence (process-children) (literal " "))) (element classname (if (first-sibling?) (process-children) (make sequence (process-children) (if (last-sibling?) (empty-sosofo) (literal ", "))))) (element fieldsynopsis (make paragraph (literal " "); (process-children) (literal ";"))) (element type (make sequence (process-children) (literal " "))) (element varname (make sequence (process-children))) (element initializer (make sequence (literal " = ") (process-children))) (element constructorsynopsis (idl-method-synopsis)) (element destructorsynopsis (idl-method-synopsis)) (element methodsynopsis (idl-method-synopsis)) (element void (literal "void ")) (element methodname (process-children)) (element methodparam (make sequence (if (first-sibling?) (empty-sosofo) (literal ", ")) (process-children))) (element parameter (process-children)) (element exceptionname (make sequence (if (first-sibling?) (literal " raises(") (literal ", ")) (process-children) (if (last-sibling?) (literal ")") (empty-sosofo)))) ) (define (idl-method-synopsis #!optional (nd (current-node))) (let* ((modifiers (select-elements (children nd) (normalize "modifier"))) (notmod (node-list-filter-by-not-gi (children nd) (list (normalize "modifier")))) (type (if (equal? (gi (node-list-first notmod)) (normalize "methodname")) (empty-node-list) (node-list-first notmod))) (methodname (select-elements (children nd) (normalize "methodname"))) (param (node-list-filter-by-gi (node-list-rest notmod) (list (normalize "methodparam")))) (excep (select-elements (children nd) (normalize "exceptionname")))) (make paragraph (process-node-list modifiers) (process-node-list type) (process-node-list methodname) (literal "(") (process-node-list param) (literal ")") (process-node-list excep) (literal ";")))) ;; ===== Python ====================================================== ;; Contributed by Lane Stevens, lane@cycletime.com (mode cs-python-mode (element classsynopsis (let* ((classes (select-elements (children (current-node)) (normalize "ooclass"))) (classname (node-list-first classes)) (superclasses (node-list-rest classes))) (make display-group use: verbatim-style (make paragraph (literal "class ") (process-node-list classname) (literal "(") (process-node-list superclasses) (literal ") :")) (process-node-list (node-list-filter-by-gi (children (current-node)) (list (normalize "constructorsynopsis") (normalize "destructorsynopsis") (normalize "fieldsynopsis") (normalize "methodsynopsis") (normalize "classsynopsisinfo")))) ) ) ) (element ooclass (make sequence (process-children) (cond ((first-sibling?) (literal " ")) ((last-sibling?) (empty-sosofo)) (#t (literal ", ")) ) ) ) (element methodsynopsis (python-method-synopsis)) (element classname (process-children)) (element initializer (make sequence (literal " = ") (process-children))) (element methodname (process-children)) (element methodparam (make sequence (process-children) (if (last-sibling?) (empty-sosofo) (literal ", ")) ) ) (element parameter (process-children)) ) (define (python-method-synopsis #!optional (nd (current-node))) (let* ((the-method-name (select-elements (children nd) (normalize "methodname"))) (the-method-params (select-elements (children nd) (normalize "methodparam"))) ) (make paragraph (literal " def ") (process-node-list the-method-name) (literal "(") (process-node-list the-method-params) (literal ") :")) ) ) ;; EOF sisc-1.16.6.orig/doc/sss/sss.css0000644000175000017500000000011711445752462015041 0ustar amoeamoe.METHODNAME { font-weight: bold } .PARAMETER { font-style: italic } .TYPE { } sisc-1.16.6.orig/doc/sss/dbparam.dsl0000644000175000017500000015706311445752462015646 0ustar amoeamoe ;; This file is part of the Modular DocBook Stylesheet distribution. ;; See ../README or http://nwalsh.com/docbook/dsssl/ ;; ;; === Book intro, for dsl2man ========================================== DocBook Print Parameters ;; Part of the Modular DocBook Stylesheet distribution ;; NormanWalsh ;; ;; $Revision: 1.2 $ ;; 199719981999 ;; Norman Walsh ;; ;; ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ;; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ;; NONINFRINGEMENT. IN NO EVENT SHALL NORMAN WALSH OR ANY OTHER ;; CONTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ;; OTHER DEALINGS IN THE SOFTWARE. ;; ;; ;; ;; ;; Please direct all questions, bug reports, or suggestions for changes ;; to Norman Walsh, <ndw@nwalsh.com>. ;; ;; ;; See http://nwalsh.com/docbook/dsssl/ for more information. ;; ;; /DOCINFO ]]> ;; REFERENCE TOC/LOT Apparatus (define %generate-set-toc% ;; REFENTRY generate-set-toc ;; PURP Should a Table of Contents be produced for Sets? ;; DESC ;; If true, a Table of Contents will be generated for each 'Set'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %generate-book-toc% ;; REFENTRY generate-book-toc ;; PURP Should a Table of Contents be produced for Books? ;; DESC ;; If true, a Table of Contents will be generated for each 'Book'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define ($generate-book-lot-list$) ;; REFENTRY generate-book-lot-list ;; PURP Which Lists of Titles should be produced for Books? ;; DESC ;; This parameter should be a list (possibly empty) of the elements ;; for which Lists of Titles should be produced for each 'Book'. ;; ;; It is meaningless to put elements that do not have titles in this ;; list. If elements with optional titles are placed in this list, only ;; the instances of those elements that do have titles will appear in ;; the LOT. ;; ;; /DESC ;; AUTHOR N/A ;; /REFENTRY (list (normalize "table") (normalize "figure") (normalize "example") (normalize "equation"))) (define %generate-part-toc% ;; REFENTRY generate-part-toc ;; PURP Should a Table of Contents be produced for Parts? ;; DESC ;; If true, a Table of Contents will be generated for each 'Part'. ;; Note: '%generate-part-toc-on-titlepage%' controls whether the Part TOC ;; is placed on the bottom of the part titlepage or on page(s) of its own. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %generate-part-toc-on-titlepage% ;; REFENTRY generate-part-toc-on-titlepage ;; PURP Should the Part TOC appear on the Part title page? ;; DESC ;; If true, the Part TOC will be placed on the Part title page. If false, ;; the TOC will be placed on separate page(s) after the Part title page. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %generate-reference-toc% ;; REFENTRY generate-reference-toc ;; PURP Should a Table of Contents be produced for References? ;; DESC ;; If true, a Table of Contents will be generated for each 'Reference'. ;; Note: '%generate-reference-toc-on-titlepage%' controls whether the ;; Reference TOC ;; is placed on the bottom of the title page or on page(s) of its own. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %generate-reference-toc-on-titlepage% ;; REFENTRY generate-reference-toc-on-titlepage ;; PURP Should the Reference TOC appear on the Reference title page? ;; DESC ;; If true, the Reference TOC will be placed on the Reference title page. ;; If false, ;; the TOC will be placed on separate page(s) after the title page. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %generate-article-toc% ;; REFENTRY generate-article-toc ;; PURP Should a Table of Contents be produced for Articles? ;; DESC ;; If true, a Table of Contents will be generated for each 'Article'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %generate-article-toc-on-titlepage% ;; REFENTRY generate-article-toc-on-titlepage ;; PURP Should the Article TOC appear on the Article title page? ;; DESC ;; If true, the Article TOC will be placed on the Article title page. ;; If false, ;; the TOC will be placed on separate page(s) after the title page. ;; If false, %generate-article-titlepage-on-separate-page% should be ;; true. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) ;; REFERENCE Titlepages (define %generate-set-titlepage% ;; REFENTRY generate-set-titlepage ;; PURP Should a set title page be produced? ;; DESC ;; If true, a title page will be generated for each 'Set'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %generate-book-titlepage% ;; REFENTRY generate-book-titlepage ;; PURP Should a book title page be produced? ;; DESC ;; If true, a title page will be generated for each 'Book'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %generate-part-titlepage% ;; REFENTRY generate-part-titlepage ;; PURP Should a part title page be produced? ;; DESC ;; If true, a title page will be generated for each 'Part'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %generate-partintro-on-titlepage% ;; REFENTRY generate-partintro-on-titlepage ;; PURP Should the PartIntro appear on the Part/Reference title page? ;; DESC ;; If true, the PartIntro content will appear on the title page of ;; Parts and References. If false, ;; it will be placed on separate page(s) after the title page. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %generate-reference-titlepage% ;; REFENTRY generate-reference-titlepage ;; PURP Should a reference title page be produced? ;; DESC ;; If true, a title page will be generated for each 'Reference'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %generate-article-titlepage% ;; REFENTRY generate-article-titlepage ;; PURP Should an article title page be produced? ;; DESC ;; If true, a title page will be generated for each 'Article'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %generate-article-titlepage-on-separate-page% ;; REFENTRY generate-article-ttlpg-on-sep-page ;; PURP Should the article title page be on a separate page? ;; DESC ;; If true, the title page for each 'Article' will occur on its own page. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %titlepage-in-info-order% ;; REFENTRY titlepage-in-info-order ;; PURP Place elements on title page in document order? ;; DESC ;; If true, the elements on the title page will be set in the order that ;; they appear in the *info element. Otherwise, they will be set in ;; the order specified in the *-titlepage-*-elements list. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %author-othername-in-middle% ;; REFENTRY othername-in-middle ;; PURP Author OTHERNAME appears between FIRSTNAME and SURNAME? ;; DESC ;; If true, the OTHERNAME of an AUTHOR appears between the ;; FIRSTNAME and SURNAME. Otherwise, OTHERNAME is suppressed. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) ;; REFERENCE RefEntries and FuncSynopses (define %refentry-new-page% ;; REFENTRY refentry-new-page ;; PURP 'RefEntry' starts on new page? ;; DESC ;; If true, each 'RefEntry' begins on a new page. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %refentry-keep% ;; REFENTRY refentry-keep ;; PURP Keep RefEntrys together? ;; DESC ;; Refentry keep indicates how the stylesheet should ;; attempt to keep each RefEntry. Common values are '#t', for the ;; smallest possible area, 'page' for the same page, and '#f' to ignore ;; this characteristic. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %refentry-generate-name% ;; REFENTRY refentry-generate-name ;; PURP Output NAME header before 'RefName'(s)? ;; DESC ;; If true, a "NAME" section title is output before the list ;; of 'RefName's. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %refentry-xref-italic% ;; REFENTRY refentry-xref-italic ;; PURP Use italic text when cross-referencing RefEntrys? ;; DESC ;; If true, italics are used when cross-referencing RefEntrys, either ;; with XRef or CiteRefEntry. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %refentry-xref-manvolnum% ;; REFENTRY refentry-xref-manvolnum ;; PURP Output manvolnum as part of RefEntry cross-reference? ;; DESC ;; If true, the manvolnum is used when cross-referencing RefEntrys, either ;; with XRef or CiteRefEntry. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %funcsynopsis-style% ;; REFENTRY funcsynopsis-style ;; PURP What style of 'FuncSynopsis' should be generated? ;; DESC ;; If '%funcsynopsis-style%' is 'ansi', ;; ANSI-style function synopses are generated for a 'FuncSynopsis', ;; otherwise KR-style function synopses are generated. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'ansi) (define %kr-funcsynopsis-indent% ;; REFENTRY kr-funcsynopsis-indent ;; PURP Indent-depth in KR-style function synopses ;; DESC ;; If the '%funcsynopsis-style%' is 'kr', ;; '%kr-funcsynopsis-indent%' specifies the amount by which parameter ;; definitions should be indented under the function prototype. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 1pi) (define %funcsynopsis-decoration% ;; REFENTRY funcsynopsis-decoration ;; PURP Decorate elements of a FuncSynopsis? ;; DESC ;; If true, elements of the FuncSynopsis will be decorated (e.g. bold or ;; italic). The decoration is controlled by functions that can be redefined ;; in a customization layer. See 'edbsynop.dsl'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) ;; REFERENCE Fonts (define %refentry-name-font-family% ;; REFENTRY refentry-name-font-family ;; PURP The font family used in RefName ;; DESC ;; The name of the font family used in 'RefEntry' ;; 'RefName's. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY %mono-font-family%) (define %title-font-family% ;; REFENTRY title-font-family ;; PURP The font family used in titles ;; DESC ;; The name of the font family used in titles (Arial by default). ;; ;; The values used here are system dependent (you have ;; to have the fonts you select) and backend dependent (the backend has ;; to know how to use them). ;; ;; The values here work for the RTF backend under MS Windows. YMMV. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY "Arial") (define %body-font-family% ;; REFENTRY body-font-family ;; PURP The font family used in body text ;; DESC ;; The name of the font family used in body text ;; (Times New Roman by default). ;; ;; The values used here are system dependent (you have ;; to have the fonts you select) and backend dependent (the backend has ;; to know how to use them). ;; ;; The values here work for the RTF backend under MS Windows. YMMV. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY "Times New Roman") (define %mono-font-family% ;; REFENTRY mono-font-family ;; PURP The font family used in verbatim environments ;; DESC ;; The name of the font family used in verbatim environments (Courier New ;; by default). ;; ;; The values used here are system dependent (you have ;; to have the fonts you select) and backend dependent (the backend has ;; to know how to use them). ;; ;; The values here work for the RTF backend under MS Windows. YMMV. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY "Courier New") (define %admon-font-family% ;; REFENTRY admon-font-family ;; PURP The font family used in admonitions ;; DESC ;; The name of the font family used for body text in admonitions (Arial ;; by default). ;; ;; The values used here are system dependent (you have ;; to have the fonts you select) and backend dependent (the backend has ;; to know how to use them). ;; ;; The values here work for the RTF backend under MS Windows. YMMV. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY "Arial") (define %guilabel-font-family% ;; REFENTRY guilabel-font-family ;; PURP The font family used in GUI labels ;; DESC ;; The name of the font family used for text that represents text on a ;; GUI (e.g., text in 'GUILabel', 'GUIMenu', ;; etc.). (Arial by default). ;; ;; The values used here are system dependent (you have ;; to have the fonts you select) and backend dependent (the backend has ;; to know how to use them). ;; ;; The values here work for the RTF backend under MS Windows. YMMV. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY "Arial") (define %visual-acuity% ;; REFENTRY visual-acuity ;; PURP General measure of document text size ;; DESC ;; This parameter controls the general size of the text in the document. ;; Several other values (body font size and margins) have default values that ;; vary depending on the setting of '%visual-acuity%'. There ;; are three legal values: 'normal', ;; the normal, standard document size (10pt body text); ;; 'presbyopic', ;; a slightly more generous size (12pt body text); and ;; 'large-type', ;; quite large (24pt body text). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY ;; "presbyopic" ;; "large-type" "normal") (define %hsize-bump-factor% ;; REFENTRY hsize-bump-factor ;; PURP Font scaling factor ;; DESC ;; Internally, the stylesheet refers to font sizes in purely relative ;; terms. This is done by defining a scaled set of fonts ;; (sizes 1, 2, 3, etc.) ;; based at the default text font size (e.g. 10pt). The '%hsize-bump-factor%' ;; describes the ratio between scaled sizes. The default is 1.2. ;; ;; Each hsize is '%hsize-bump-factor%' times larger than ;; the previous hsize. For example, if the base size is 10pt, and ;; '%hsize-bump-factor%' ;; 1.2, hsize 1 is 12pt, hsize 2 is 14.4pt, hsize 3 is 17.28pt, etc. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 1.2) (define %smaller-size-factor% ;; REFENTRY smaller-size-factor ;; PURP Smaller font scaling factor ;; DESC ;; In environments that are usually set with a slightly smaller font size, ;; for example block quotations, the stylesheet calculates the smaller font ;; size by muliplying the current font size by '%smaller-size-factor%'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0.9) (define %ss-size-factor% ;; REFENTRY ss-size-factor ;; PURP Super/subscript scaling factor ;; DESC ;; When text is set as a subscript or superscript, the font size of the ;; text is multiplied by '%ss-size-factor%'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0.6) (define %ss-shift-factor% ;; REFENTRY ss-shift-factor ;; PURP Super/subscript shift factor ;; DESC ;; When text is set as a subscript or superscript, it is set above or below ;; the baseline by a factor of the current font size and '%ss-shift-factor%'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0.4) (define %verbatim-size-factor% ;; REFENTRY verbatim-size-factor ;; PURP Verbatim font scaling factor ;; DESC ;; When a monospace font is selected, the current font size is multiplied ;; by the '%verbatim-size-factor%'. If '%verbatim-size-factor%' ;; is '#f', no scaling is performed (Well, that's not precisely true. ;; In '$verbatim-display$' ;; environments, the font size is calculated with respect to the longest line ;; in the display, if '%verbatim-size-factor%' is '#f'). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0.9) (define %bf-size% ;; REFENTRY bf-size ;; PURP Defines the body font size ;; DESC ;; Sets the body font size. This parameter is usually controlled by the ;; '%visual-acuity%' parameter. ;; /DESC ;; /REFENTRY (case %visual-acuity% (("tiny") 8pt) (("normal") 10pt) (("presbyopic") 12pt) (("large-type") 24pt))) (define-unit em %bf-size%) (define %footnote-size-factor% ;; REFENTRY footnote-size-factor ;; PURP Footnote font scaling factor ;; DESC ;; When printing footnotes, the current font size is multiplied by the ;; '%footnote-size-factor%'. ;; /DESC ;; /REFENTRY 0.9) ;; REFERENCE Backends (define tex-backend ;; REFENTRY tex-backend ;; PURP Are we using the TeX backend? ;; DESC ;; This parameter exists so that '-V tex-backend' can be used on the ;; command line to explicitly select the TeX backend. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define mif-backend ;; REFENTRY mif-backend ;; PURP Are we using the MIF backend? ;; DESC ;; This parameter exists so that '-V mif-backend' can be used on the ;; command line to explicitly select the MIF backend. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define rtf-backend ;; REFENTRY rtf-backend ;; PURP Are we using the RTF backend? ;; DESC ;; This parameter exists so that '-V rtf-backend' can be used on the ;; command line to explicitly select the RTF backend. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define default-backend ;; REFENTRY default-backend ;; PURP What is the default backend? ;; DESC ;; This parameter sets the default backend. Selecting an explicit ;; backend enables features specific to that backend (if there are any). ;; The legal values are 'rtf', 'tex', 'mif', and '#f'. Using ;; '#f' implies that no special features are used. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define (print-backend) ;; REFENTRY print-backend ;; PURP Returns the backend that is being used to format the document ;; DESC ;; This parameter controls features in the stylesheet that are backend ;; specific. The legal values are 'rtf', 'tex', 'mif', and '#f'. Using ;; '#f' implies that no special features are used. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY (cond (tex-backend 'tex) (mif-backend 'mif) (rtf-backend 'rtf) (else default-backend))) ;; REFERENCE Verbatim Environments (define %verbatim-default-width% ;; REFENTRY verbatim-default-width ;; PURP Default width of verbatim environments ;; DESC ;; If no WIDTH attribute is specified on verbatim environments, ;; '%verbatim-default-width%' is the default. Note: this width only ;; comes into play if '%verbatim-size-factor%' is '#f'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 80) (define %number-synopsis-lines% ;; REFENTRY number-synopsis-lines ;; PURP Enumerate lines in a 'Synopsis'? ;; DESC ;; If true, lines in each 'Synopsis' will be enumerated. ;; See also '%linenumber-mod%', '%linenumber-length%', ;; '%linenumber-padchar%', and '($linenumber-space$)'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %number-funcsynopsisinfo-lines% ;; REFENTRY number-funcsynopsisinfo-lines ;; PURP Enumerate lines in a 'FuncSynopsisInfo'? ;; DESC ;; If true, lines in each 'FuncSynopsisInfo' will be enumerated. ;; See also '%linenumber-mod%', '%linenumber-length%', ;; '%linenumber-padchar%', and '($linenumber-space$)'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %number-literallayout-lines% ;; REFENTRY number-literallayout-lines ;; PURP Enumerate lines in a 'LiteralLayout'? ;; DESC ;; If true, lines in each 'LiteralLayout' will be enumerated. ;; See also '%linenumber-mod%', '%linenumber-length%', ;; '%linenumber-padchar%', and '($linenumber-space$)'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %number-address-lines% ;; REFENTRY number-address-lines ;; PURP Enumerate lines in a 'Address'? ;; DESC ;; If true, lines in each 'Address' will be enumerated. ;; See also '%linenumber-mod%', '%linenumber-length%', ;; '%linenumber-padchar%', and '($linenumber-space$)'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %number-programlisting-lines% ;; REFENTRY number-programlisting-lines ;; PURP Enumerate lines in a 'ProgramListing'? ;; DESC ;; If true, lines in each 'ProgramListing' will be enumerated. ;; See also '%linenumber-mod%', '%linenumber-length%', ;; '%linenumber-padchar%', and '($linenumber-space$)'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %number-screen-lines% ;; REFENTRY number-screen-lines ;; PURP Enumerate lines in a 'Screen'? ;; DESC ;; If true, lines in each 'Screen' will be enumerated. ;; See also '%linenumber-mod%', '%linenumber-length%', ;; '%linenumber-padchar%', and '($linenumber-space$)'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %linenumber-mod% ;; REFENTRY linenumber-mod ;; PURP Controls line-number frequency in enumerated environments. ;; DESC ;; Every '%linenumber-mod%' line will be enumerated. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 5) (define %linenumber-length% ;; REFENTRY linenumber-length ;; PURP Width of line numbers in enumerated environments ;; DESC ;; Line numbers will be padded to '%linenumber-length%' ;; characters. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 3) (define %linenumber-padchar% ;; REFENTRY linenumber-padchar ;; PURP Pad character in line numbers ;; DESC ;; Line numbers will be padded (on the left) with '%linenumber-padchar%'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY "\no-break-space;") (define ($linenumber-space$) ;; REFENTRY linenumber-space ;; PURP Returns the sosofo which separates line numbers from the text ;; DESC ;; The sosofo returned by '($linenumber-space$)' is placed ;; between the line number and the corresponding line in ;; enumerated environments. ;; ;; Note: '%linenumber-padchar%'s are separated from lines ;; that are not enumerated (because they don't match '%linenumber-mod%'). ;; In other words, '($linenumber-space$)' occurs ;; on every line. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY (literal "\no-break-space;")) (define %indent-synopsis-lines% ;; REFENTRY indent-synopsis-lines ;; PURP Indent lines in a 'Synopsis'? ;; DESC ;; If not '#f', each line in the display will be indented ;; with the content of this variable. Usually it is set to some number ;; of spaces, but you can indent with any string you wish. ;; /DESC ;; /REFENTRY #f) (define %indent-funcsynopsisinfo-lines% ;; REFENTRY indent-funcsynopsisinfo-lines ;; PURP Indent lines in a 'FuncSynopsisInfo'? ;; DESC ;; If not '#f', each line in the display will be indented ;; with the content of this variable. Usually it is set to some number ;; of spaces, but you can indent with any string you wish. ;; /DESC ;; /REFENTRY #f) (define %indent-literallayout-lines% ;; REFENTRY indent-literallayout-lines ;; PURP Indent lines in a 'LiteralLayout'? ;; DESC ;; If not '#f', each line in the display will be indented ;; with the content of this variable. Usually it is set to some number ;; of spaces, but you can indent with any string you wish. ;; /DESC ;; /REFENTRY #f) (define %indent-address-lines% ;; REFENTRY indent-address-lines ;; PURP Indent lines in a 'Address'? ;; DESC ;; If not '#f', each line in the display will be indented ;; with the content of this variable. Usually it is set to some number ;; of spaces, but you can indent with any string you wish. ;; /DESC ;; /REFENTRY #f) (define %indent-programlisting-lines% ;; REFENTRY indent-programlisting-lines ;; PURP Indent lines in a 'ProgramListing'? ;; DESC ;; If not '#f', each line in the display will be indented ;; with the content of this variable. Usually it is set to some number ;; of spaces, but you can indent with any string you wish. ;; /DESC ;; /REFENTRY #f) (define %indent-screen-lines% ;; REFENTRY indent-screen-lines ;; PURP Indent lines in a 'Screen'? ;; DESC ;; If not '#f', each line in the display will be indented ;; with the content of this variable. Usually it is set to some number ;; of spaces, but you can indent with any string you wish. ;; /DESC ;; /REFENTRY #f) (define %callout-fancy-bug% ;; REFENTRY callout-fancy-bug ;; PURP Use fancy callout bugs? ;; DESC ;; If true, fancy callout bugs will be used. Otherwise, simple ones are ;; used. Fancy callout bugs may require the RTF backend. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %callout-default-col% ;; REFENTRY callout-default-col ;; PURP Default column for callouts ;; DESC ;; If the coordinates of a callout include only a line number, the callout ;; bug will appear in column '%callout-default-col%'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 60) ;; REFERENCE Labelling (define %section-autolabel% ;; REFENTRY section-autolabel ;; PURP Are sections enumerated? ;; DESC ;; If true, unlabeled sections will be enumerated. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %chapter-autolabel% ;; REFENTRY chapter-autolabel ;; PURP Are chapters enumerated? ;; DESC ;; If true, chapters will be enumerated. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %label-preface-sections% ;; REFENTRY label-preface-sections ;; PURP Are sections in the Preface enumerated? ;; DESC ;; If true, unlabeled sections in the Preface will be enumerated ;; if '%section-autolabel%' is true. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %qanda-inherit-numeration% ;; REFENTRY qanda-inherit-numeration ;; PURP Should numbered questions inherit the surrounding numeration? ;; DESC ;; If true, question numbers are prefixed with the surrounding ;; component or section number. Has no effect unless ;; '%section-autolabel%' is also true. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) ;; REFERENCE Running Heads (define %chap-app-running-heads% ;; REFENTRY chap-app-running-heads ;; PURP Generate running headers and footers on chapter-level elements? ;; DESC ;; If true, running headers and footers are produced on chapter-level ;; elements. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %chap-app-running-head-autolabel% ;; REFENTRY chap-app-running-head-autolabel ;; PURP Put chapter labels in running heads? ;; DESC ;; If true, running heads on 'Chapter's and ;; 'Appendix'es will include an automatic label. ;; ;; In other words, if a 'Chapter' has no 'Label' attribute, ;; and '%chap-app-running-head-autolabel%' ;; is true, running heads will include the automatic label for the ;; 'Chapter'. If '%chap-app-running-head-autolabel%' ;; is false, only the 'Title' (or 'TitleAbbrev') ;; will appear in the running head. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) ;; REFERENCE Paper/Page Characteristics (define %paper-type% ;; REFENTRY paper-type ;; PURP Name of paper type ;; DESC ;; The paper type value identifies the sort of paper in use, for example, ;; 'A4' or 'USletter'. Setting the paper type is an ;; easy shortcut for setting the correct paper height and width. ;; ;; As distributed, only 'A4' and 'USletter' are supported. You can add ;; additional paper types by updating 'page-width' and 'page-height'. ;; If you do, please pass along your updates. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY ;; "A4" "USletter") (define %two-side% ;; REFENTRY two-side ;; PURP Is two-sided output being produced? ;; DESC ;; If '%two-side%' is true, headers and footers are alternated ;; so that the "outer" and "inner" headers will be correctly ;; placed in the bound document. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %writing-mode% ;; REFENTRY writing-mode ;; PURP The writing mode ;; DESC ;; The writing mode is either 'left-to-right', or ;; 'right-to-left'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'left-to-right) (define %page-n-columns% ;; REFENTRY page-n-columns ;; PURP Sets the number of columns on each page ;; DESC ;; Sets the number of columns on each page ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 1) (define %titlepage-n-columns% ;; REFENTRY titlepage-n-columns ;; PURP Sets the number of columns on the title page ;; DESC ;; Sets the number of columns on the title page ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 1) (define %page-column-sep% ;; REFENTRY page-column-sep ;; PURP Sets the width of the gutter between columns ;; DESC ;; Sets the width of the gutter between columns ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0.5in) (define %page-balance-columns?% ;; REFENTRY page-balance-columns ;; PURP Balance columns on pages? ;; DESC ;; If true, the columns on the final page of a multiple column layout ;; will be balanced. Otherwise, the columns will be completely filled in the ;; writing direction and the last column may be a different length ;; than the preceding columns. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %left-margin% ;; REFENTRY left-margin ;; PURP Width of left margin ;; DESC ;; The '%left-margin%' parameter specifies the width of the left margin ;; of the page. Note that this setting is relative to the physical page, ;; not the writing direction. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 6pi) (define %right-margin% ;; REFENTRY right-margin ;; PURP Width of the right margin ;; DESC ;; The '%right-margin%' parameter specifies the width of the right margin ;; of the page. Note that this setting is relative to the physical page, ;; not the writing direction. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 6pi) (define %page-width% ;; REFENTRY page-width ;; PURP Specifies the page width ;; DESC ;; Identifies the width of the page (length in the writing direction). ;; It is usually controlled by the '%paper-type%' parameter. ;; /DESC ;; /REFENTRY (case %paper-type% (("A4landscape") 297mm) (("USletter") 8.5in) (("USlandscape") 11in) (("4A0") 1682mm) (("2A0") 1189mm) (("A0") 841mm) (("A1") 594mm) (("A2") 420mm) (("A3") 297mm) (("A4") 210mm) (("A5") 148mm) (("A6") 105mm) (("A7") 74mm) (("A8") 52mm) (("A9") 37mm) (("A10") 26mm) (("B0") 1000mm) (("B1") 707mm) (("B2") 500mm) (("B3") 353mm) (("B4") 250mm) (("B5") 176mm) (("B6") 125mm) (("B7") 88mm) (("B8") 62mm) (("B9") 44mm) (("B10") 31mm) (("C0") 917mm) (("C1") 648mm) (("C2") 458mm) (("C3") 324mm) (("C4") 229mm) (("C5") 162mm) (("C6") 114mm) (("C7") 81mm) (("C8") 57mm) (("C9") 40mm) (("C10") 28mm))) (define %page-height% ;; REFENTRY page-height ;; PURP Specifies the page height ;; DESC ;; Identifies the height of the page (length perpendicular to the ;; writing direction). ;; It is usually controlled by the '%paper-type%' parameter. ;; /DESC ;; /REFENTRY (case %paper-type% (("A4landscape") 210mm) (("USletter") 11in) (("USlandscape") 8.5in) (("4A0") 2378mm) (("2A0") 1682mm) (("A0") 1189mm) (("A1") 841mm) (("A2") 594mm) (("A3") 420mm) (("A4") 297mm) (("A5") 210mm) (("A6") 148mm) (("A7") 105mm) (("A8") 74mm) (("A9") 52mm) (("A10") 37mm) (("B0") 1414mm) (("B1") 1000mm) (("B2") 707mm) (("B3") 500mm) (("B4") 353mm) (("B5") 250mm) (("B6") 176mm) (("B7") 125mm) (("B8") 88mm) (("B9") 62mm) (("B10") 44mm) (("C0") 1297mm) (("C1") 917mm) (("C2") 648mm) (("C3") 458mm) (("C4") 324mm) (("C5") 229mm) (("C6") 162mm) (("C7") 114mm) (("C8") 81mm) (("C9") 57mm) (("C10") 40mm))) (define %text-width% ;; REFENTRY text-width ;; PURP Specifies the width of the body column ;; DESC ;; Identifies the width of the page on which text may occur. ;; /DESC ;; /REFENTRY (- %page-width% (+ %left-margin% %right-margin%))) (define %body-width% ;; REFENTRY body-width ;; PURP Specifies the width of the text in the body column ;; DESC ;; Identifies the width of the page on which text will occur, after ;; the '%body-start-indent%' is removed. ;; /DESC ;; /REFENTRY (- %text-width% %body-start-indent%)) (define %top-margin% ;; REFENTRY top-margin ;; PURP Height of top margin ;; DESC ;; The '%top-margin%' parameter specifies the height of the ;; top margin ;; of the page. Note that this setting is relative to the physical page, ;; not the writing direction. ;; /DESC ;; /REFENTRY (if (equal? %visual-acuity% "large-type") 7.5pi 6pi)) (define %bottom-margin% ;; REFENTRY bottom-margin ;; PURP Height of bottom margin ;; DESC ;; The '%bottom-margin%' parameter specifies the ;; height of the bottom margin ;; of the page. Note that this setting is relative to the physical page, ;; not the writing direction. ;; /DESC ;; /REFENTRY (if (equal? %visual-acuity% "large-type") 9.5pi 8pi)) (define %header-margin% ;; REFENTRY header-margin ;; PURP Height of header margin ;; DESC ;; The '%header-margin%' parameter specifies the heigth ;; of the header margin ;; of the page. Note that this setting is relative to the physical page, ;; not the writing direction. ;; /DESC ;; /REFENTRY (if (equal? %visual-acuity% "large-type") 5.5pi 4pi)) (define %footer-margin% ;; REFENTRY footer-margin ;; PURP Height of footer margin ;; DESC ;; The '%footer-margin%' parameter specifies the height ;; of the footer margin ;; of the page. Note that this setting is relative to the physical page, ;; not the writing direction. ;; /DESC ;; /REFENTRY 4pi) (define %page-number-restart% ;; REFENTRY page-number-restart ;; PURP Restart page numbers in each component? ;; DESC ;; If true, page numbers are restarted at the beginning of each ;; component-level ;; element ('Chapter', 'Appendix', ;; 'Bibliography', etc.). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %article-page-number-restart% ;; REFENTRY article-page-number-restart ;; PURP Restart page numbers in each article? ;; DESC ;; If true, page numbers are restarted at the beginning of each ;; article. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %generate-heading-level% ;; REFENTRY generate-heading-level ;; PURP Output RTF heading level characteristics? ;; DESC ;; If true, component and section titles will have the heading-level ;; characteristic in the RTF. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) ;; REFERENCE Admonitions (define %admon-graphics% ;; REFENTRY admon-graphics ;; PURP Use graphics in admonitions? ;; DESC ;; If true, admonitions are presented in an alternate style that uses ;; a graphic. Default graphics are provided in the distribution. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %admon-graphics-path% ;; REFENTRY admon-graphics-path ;; PURP Path to admonition graphics ;; DESC ;; Sets the path, probably relative to the directory where the HTML ;; files are created, to the admonition graphics. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY "/usr/share/sgml/docbook/stylesheet/dsssl/modular/images/") (define admon-graphic-default-extension ;; REFENTRY admon-graphic-default-extension ;; PURP Admonition graphic file extension ;; DESC ;; Identifies the default extension for admonition graphics. This allows ;; backends to select different images (e.g., EPS for print, PNG for ;; PDF, etc.) ;; /DESC ;; AUTHOR N/A ;; /REFENTRY ".eps") (define ($admon-graphic$ #!optional (nd (current-node))) ;; REFENTRY admon-graphic ;; PURP Admonition graphic file ;; DESC ;; Given an admonition node, returns the name of the graphic that should ;; be used for that admonition. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY (cond ((equal? (gi nd) (normalize "tip")) (string-append %admon-graphics-path% (string-append "tip" admon-graphic-default-extension))) ((equal? (gi nd) (normalize "note")) (string-append %admon-graphics-path% (string-append "note" admon-graphic-default-extension))) ((equal? (gi nd) (normalize "important")) (string-append %admon-graphics-path% (string-append "important" admon-graphic-default-extension))) ((equal? (gi nd) (normalize "caution")) (string-append %admon-graphics-path% (string-append "caution" admon-graphic-default-extension))) ((equal? (gi nd) (normalize "warning")) (string-append %admon-graphics-path% (string-append "warning" admon-graphic-default-extension))) (else (error (string-append (gi nd) " is not an admonition."))))) (define ($admon-graphic-width$ #!optional (nd (current-node))) ;; REFENTRY admon-graphic-width ;; PURP Admonition graphic file width ;; DESC ;; Given an admonition node, returns the width of the graphic that will ;; be used for that admonition. ;; ;; All of the default graphics in the distribution are 0.3in wide. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0.3in) ;; REFERENCE Quadding (define %default-quadding% ;; REFENTRY default-quadding ;; PURP The default quadding ;; DESC ;; The default quadding ('start', 'center', 'justify', ;; or 'end'). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'start) (define %division-title-quadding% ;; REFENTRY division-title-quadding ;; PURP Division title quadding ;; DESC ;; The quadding of division-level titles ('Set', 'Book', and 'Part'). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'center) (define %division-subtitle-quadding% ;; REFENTRY division-subtitle-quadding ;; PURP Division subtitle quadding ;; DESC ;; The quadding of division-level subtitles ('Set', 'Book', and 'Part'). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'center) (define %component-title-quadding% ;; REFENTRY component-title-quadding ;; PURP Component title quadding ;; DESC ;; The quadding of component-level titles ('Chapter', ;; 'Appendix', 'Glossary', etc.). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'start) (define %component-subtitle-quadding% ;; REFENTRY component-subtitle-quadding ;; PURP Component subtitle quadding ;; DESC ;; The quadding of component-level subtitles ('Chapter', ;; 'Appendix', 'Glossary', etc.). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'start) (define %article-title-quadding% ;; REFENTRY article-title-quadding ;; PURP Article title quadding ;; DESC ;; The quadding of article titles. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'center) (define %article-subtitle-quadding% ;; REFENTRY article-subtitle-quadding ;; PURP Article subtitle quadding ;; DESC ;; The quadding of article subtitles. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'center) (define %section-title-quadding% ;; REFENTRY section-title-quadding ;; PURP Section title quadding ;; DESC ;; The quadding of section-level titles. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'start) (define %section-subtitle-quadding% ;; REFENTRY section-subtitle-quadding ;; PURP Section subtitle quadding ;; DESC ;; The quadding of section-level subtitles. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 'start) ;; REFERENCE Bibliographies (define biblio-citation-check ;; REFENTRY biblio-citation-check ;; PURP Check citations ;; DESC ;; If true, the content of CITATIONs will be checked against possible ;; biblioentries. If the citation cannot be found, an error is issued ;; and the citation is generated. If the citation is found, it is generated ;; with a cross reference to the appropriate biblioentry. ;; ;; A citation matches if the content of the citation element matches the ;; ID, XREFLABEL, or leading ABBREV of a biblioentry. ;; ;; This setting may have significant performance implications on large ;; documents, hence it is false by default. ;; ;; (This option can conveniently be set with '-V biblio-citation-check' ;; on the Jade command line). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define biblio-filter-used ;; REFENTRY filter-used ;; PURP Suppress unreferenced bibliography entries ;; DESC ;; If true, bibliography entries which are not cited are suppressed. ;; A biblioentry is cited if an XREF or LINK matches its ID, or if ;; a CITE element matches its ;; ID, XREFLABEL, or leading ABBREV. ;; ;; A BIBLIOGRAPHY with no entries will still be output (making a whole ;; component conditional would be _A LOT_ of work and seems unnecessary), ;; but BIBLIDIVs with no entries will be suppressed. ;; ;; This setting may have significant performance implications, ;; hence it is false by default. ;; ;; (This option can conveniently be set with '-V biblio-filter-used' on the ;; Jade command line). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define biblio-number ;; REFENTRY biblio-number ;; PURP Enumerate bibliography entries ;; DESC ;; If true, bibliography entries will be numbered. If you cross-reference ;; bibliography entries, you should probably use biblio-number or ;; consistently use XREFLABEL or ABBREV. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define biblio-xref-title ;; REFENTRY biblio-xref-title ;; PURP Use the titles of bibliography entries in XREFs ;; DESC ;; If true, cross references to bibliography entries will use the ;; title of the entry as the cross reference text. Otherwise, either ;; the number (see 'biblio-number') or XREFLABEL/ABBREV will be used. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) ;; REFERENCE OLinks (define %olink-outline-ext% ;; REFENTRY olink-outline-ext ;; PURP Extension for olink outline file ;; DESC ;; The extension used to find the outline information file. When searching ;; for outline information about a document, the extension is discarded ;; from the system ID of the file and '%olinke-outline-ext%' is appended. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY ".olink") ;; REFERENCE Footnotes (define %footnote-ulinks% ;; REFENTRY footnote-ulinks ;; PURP Generate footnotes for ULinks? ;; DESC ;; If true, the URL of each ULink will appear as a footnote. ;; Processing ULinks this way may be very, very slow. It requires ;; walking over every descendant of every component in order to count ;; both ulinks and footnotes. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define bop-footnotes ;; REFENTRY bop-footnotes ;; PURP Make "bottom-of-page" footnotes? ;; DESC ;; If true, footnotes will be done at the bottom of the page instead ;; of collected together as notes at the end of the section. ;; This variable is ignored if the print backend does not support ;; bottom-of-the-page footnotes. At present, only the TeX backend ;; supports them. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) ;; REFERENCE Graphics (define %graphic-default-extension% ;; REFENTRY graphic-default-extension ;; PURP Default extension for graphic FILEREFs ;; DESC ;; The '%graphic-default-extension%' will be ;; added to the end of all 'fileref' filenames on ;; 'Graphic's if they do not end in one of the ;; '%graphic-extensions%'. Set this to '#f' ;; to turn off this feature. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %graphic-extensions% ;; REFENTRY graphic-extensions ;; PURP List of graphic filename extensions ;; DESC ;; The list of extensions which may appear on a 'fileref' ;; on a 'Graphic' which are indicative of graphic formats. ;; ;; Filenames that end in one of these extensions will not have ;; the '%graphic-default-extension%' added to them. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY '("eps" "epsf" "gif" "tif" "tiff" "jpg" "jpeg" "png")) (define image-library ;; REFENTRY image-library ;; PURP Load image library database for additional info about images? ;; DESC ;; If true, an image library database is loaded and extra information ;; about web graphics is retrieved from it. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define image-library-filename ;; REFENTRY image-library-filename ;; PURP Name of the image library database ;; DESC ;; If 'image-library' is true, then the database is loaded from ;; 'image-library-filename'. It's a current limitation that only a ;; single database can be loaded. ;; ;; The image library database is stored in a separate directory ;; because it must be parsed with the XML declaration. The only ;; practical way to accomplish this with Jade, if you are processing a ;; document that uses another declaration, is by having a catalog ;; file in the directory that contains the image library that ;; specifies the SGMLDECL. (So if it was in the same directory ;; as your document, your document would also be parsed with the ;; XML declaration, which may not be correct.) ;; /DESC ;; AUTHOR N/A ;; /REFENTRY "imagelib/imagelib.xml") ;; REFERENCE Tables (define ($table-element-list$) ;; REFENTRY table-element-list ;; PURP List of table element names ;; DESC ;; The list of table elements in the DTD. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY (list (normalize "table") (normalize "informaltable"))) (define %simplelist-column-width% ;; REFENTRY simplelist-column-width ;; PURP Width of columns in tabular simple lists ;; DESC ;; If set to '#f', the table will span the entire ;; page width. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) ;; REFERENCE VariableLists (define %default-variablelist-termlength% ;; REFENTRY default-variablelist-termlength ;; PURP Default term length on variablelists ;; DESC ;; When formatting a 'VariableList', this value is used as the ;; default term length, if no 'TermLength' is specified. ;; ;; If all of the terms in a list shorter than the term length, ;; the stylesheet may format them "side-by-side" in a table if ;; 'may-format-variablelist-as-table' is '#t'. ;; /DESC ;; /REFENTRY 20) (define %may-format-variablelist-as-table% ;; REFENTRY may-format-variablelist-as-table ;; PURP Format VariableLists as tables? ;; DESC ;; If '%may-format-variablelist-as-table%' is '#t', a ;; 'VariableList' will be formatted as a table, if *all of* ;; the terms are shorter than the specified 'TermLength'. ;; /DESC ;; /REFENTRY #f) (define %always-format-variablelist-as-table% ;; REFENTRY always-format-variablelist-as-table ;; PURP Always format VariableLists as tables? ;; DESC ;; When a 'VariableList' is formatted, if any of the ;; terms in the list are too long, the whole list is formatted as a ;; list. ;; ;; If '%always-format-variablelist-as-table%' is ;; '#t', the 'VariableList' will be ;; formatted as a table, even if some terms are too long. The terms that ;; are too long will format span above their associated description. ;; /DESC ;; /REFENTRY #f) ;; REFERENCE Vertical Spacing (define %line-spacing-factor% ;; REFENTRY line-spacing-factor ;; PURP Factor used to calculate leading ;; DESC ;; The leading is calculated by multiplying the current font size by the ;; '%line-spacing-factor%'. For example, if the font size is 10pt and ;; the '%line-spacing-factor%' is 1.1, then the text will be ;; printed "10-on-11". ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 1.3) (define %head-before-factor% ;; REFENTRY head-before-factor ;; PURP Factor used to calculate space above a title ;; DESC ;; The space before a title is calculated by multiplying the font size ;; used in the title by the '%head-before-factor%'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0.75) (define %head-after-factor% ;; REFENTRY head-after-factor ;; PURP Factor used to calculate space below a title ;; DESC ;; The space after a title is calculated by multiplying the font size used ;; in the title by the '%head-after-factor%'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0.5) (define %body-start-indent% ;; REFENTRY body-start-indent ;; PURP Default indent of body text ;; DESC ;; The default indent of body text. Some elements may have more or less ;; indentation. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 4pi) (define %para-sep% ;; REFENTRY para-sep ;; PURP Distance between paragraphs ;; DESC ;; The '%para-sep%' is the distance between the last line ;; of one paragraph and the first line of the next. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY (/ %bf-size% 4.0)) (define %block-sep% ;; REFENTRY block-sep ;; PURP Distance between block-elements ;; DESC ;; The '%block-sep%' is the vertical distance between ;; block elements (figures, tables, etc.) ;; /DESC ;; AUTHOR N/A ;; /REFENTRY (* %para-sep% 2.0)) ;; REFERENCE Indents (define %para-indent% ;; REFENTRY para-indent ;; PURP First line start-indent for paragraphs (other than the first) ;; DESC ;; The '%para-indent%' is the amount of extra indentation that the ;; first line of a paragraph should receive. This parameter applies ;; only to the second and subsequent paragraphs in a section. See ;; '%para-indent-firstpara%'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0pt) (define %para-indent-firstpara% ;; REFENTRY para-indent-firstpara ;; PURP First line start-indent for the first paragraph ;; DESC ;; The '%para-indent-firstpara%' is the amount of extra indentation ;; that the first line of the first paragraph of a section should receive. ;; This parameter is frequently '0pt' even when '%para-indent%' is ;; not. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0pt) (define %block-start-indent% ;; REFENTRY block-start-indent ;; PURP Extra start-indent for block-elements ;; DESC ;; Block elements (tables, figures, verbatim environments, etc.) will ;; be indented by the specified amount. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 0pt) ;; REFERENCE Object Rules (define %example-rules% ;; REFENTRY example-rules ;; PURP Specify rules before and after an Example ;; DESC ;; If '#t', rules will be drawn before and after each ;; 'Example'. ;; /DESC ;; /REFENTRY #f) (define %figure-rules% ;; REFENTRY figure-rules ;; PURP Specify rules before and after an Figure ;; DESC ;; If '#t', rules will be drawn before and after each ;; 'Figure'. ;; /DESC ;; /REFENTRY #f) (define %table-rules% ;; REFENTRY table-rules ;; PURP Specify rules before and after an Table ;; DESC ;; If '#t', rules will be drawn before and after each ;; 'Table'. ;; /DESC ;; /REFENTRY #f) (define %equation-rules% ;; REFENTRY equation-rules ;; PURP Specify rules before and after an Equation ;; DESC ;; If '#t', rules will be drawn before and after each ;; 'Equation'. ;; /DESC ;; /REFENTRY #f) (define %informalexample-rules% ;; REFENTRY informalexample-rules ;; PURP Specify rules before and after an InformalExample ;; DESC ;; If '#t', rules will be drawn before and after each ;; 'InformalExample'. ;; /DESC ;; /REFENTRY #f) (define %informalfigure-rules% ;; REFENTRY informalfigure-rules ;; PURP Specify rules before and after an InformalFigure ;; DESC ;; If '#t', rules will be drawn before and after each ;; 'InformalFigure'. ;; /DESC ;; /REFENTRY #f) (define %informaltable-rules% ;; REFENTRY informaltable-rules ;; PURP Specify rules before and after an InformalTable ;; DESC ;; If '#t', rules will be drawn before and after each ;; 'InformalTable'. ;; /DESC ;; /REFENTRY #f) (define %informalequation-rules% ;; REFENTRY informalequation-rules ;; PURP Specify rules before and after an InformalEquation ;; DESC ;; If '#t', rules will be drawn before and after each ;; 'InformalEquation'. ;; /DESC ;; /REFENTRY #f) (define %object-rule-thickness% ;; REFENTRY object-rule-thickness ;; PURP Width of rules around formal and informal objects ;; DESC ;; Specifies the width of the rules drawn before and after an object. ;; This only applies if the appropriate ;; '%*-rules%' variable ;; is '#t'. ;; /DESC ;; /REFENTRY 2pt) ;; REFERENCE Miscellaneous (define ($object-titles-after$) ;; REFENTRY object-titles-after ;; PURP List of objects who's titles go after the object ;; DESC ;; Titles of formal objects (Figures, Equations, Tables, etc.) ;; in this list will be placed below the object instead of above it. ;; ;; This is a list of element names, for example: ;; '(list (normalize "figure") (normalize "table"))'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY '()) (define formal-object-float ;; REFENTRY formal-object-float ;; PURP Do formal objects float? ;; DESC ;; If '#t', formal objects will float if floating is supported by the ;; backend. At present, only the TeX backend supports floats. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %default-title-end-punct% ;; REFENTRY default-title-end-punct ;; PURP Default punctuation at the end of a run-in head. ;; DESC ;; The punctuation used at the end of a run-in head (e.g. on FORMALPARA). ;; /DESC ;; AUTHOR N/A ;; /REFENTRY ".") (define %content-title-end-punct% ;; REFENTRY content-title-end-punct ;; PURP List of punctuation chars at the end of a run-in head ;; DESC ;; If a run-in head ends in any of these characters, the ;; '%default-title-end-punct%' is not used. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY '(#\. #\! #\? #\:)) (define %honorific-punctuation% ;; REFENTRY honorific-punctuation ;; PURP Punctuation to follow honorifics in names ;; DESC ;; The honorific punctuation is placed after the honorific in ;; a name. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY ".") (define %default-simplesect-level% ;; REFENTRY default-simplesect-level ;; PURP Default section level for 'SimpleSect's. ;; DESC ;; If 'SimpleSect's appear inside other section-level ;; elements, they are rendered at the appropriate section level, but if they ;; appear in a component-level element, they are rendered at ;; '%default-simplesect-level%'. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 4) (define %show-ulinks% ;; REFENTRY show-ulinks ;; PURP Display URLs after ULinks? ;; DESC ;; If true, the URL of each ULink will appear in parenthesis after ;; the text of the link. If the text of the link and the URL are ;; identical, the parenthetical URL is suppressed. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define %show-comments% ;; REFENTRY show-comments ;; PURP Display Comment elements? ;; DESC ;; If true, comments will be displayed, otherwise they are suppressed. ;; Comments here refers to the 'Comment' element, which will be renamed ;; 'Remark' in DocBook V4.0, not SGML/XML comments which are unavailable. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #t) (define firstterm-bold ;; REFENTRY firstterm-bold ;; PURP Make FIRSTTERM elements bold? ;; DESC ;; If '#t', FIRSTTERMs will be bold, to distinguish them from ;; simple GLOSSTERMs. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY #f) (define %min-leading% ;; REFENTRY min-leading ;; PURP Minumum leading between lines ;; DESC ;; The '%min-leading%' parameter specifies the smallest amount of leading ;; to allow between lines. The default value, '#f', has the side-effect ;; that leading cannot change. This means that graphics that appear in ;; a paragraph are truncated if they are taller than the current leading. ;; By setting this parameter to some small value, we get stretchable ;; space between lines. ;; /DESC ;; AUTHOR N/A ;; /REFENTRY 2pt) (define %hyphenation% ;; REFENTRY hyphenation ;; PURP Allow automatic hyphenation? ;; DESC ;; The '%hyphenation%' parameter indicates whether or ;; not the backend should allow automatic hyphention of text, for example ;; in paragraphs. The default value, '#f', indicates that ;; it should not. ;; /DESC ;; /REFENTRY #f) (declare-initial-value writing-mode %writing-mode%) (declare-initial-value input-whitespace-treatment 'collapse) (declare-initial-value left-margin %left-margin%) (declare-initial-value right-margin %right-margin%) (declare-initial-value page-width %page-width%) (declare-initial-value page-height %page-height%) (declare-initial-value min-leading %min-leading%) (declare-initial-value top-margin %top-margin%) (declare-initial-value bottom-margin %bottom-margin%) (declare-initial-value header-margin %header-margin%) (declare-initial-value footer-margin %footer-margin%) sisc-1.16.6.orig/doc/sss/debug.xml0000644000175000017500000005671711445752462015350 0ustar amoeamoe Debugging Facilities No Scheme system would be complete without facilities to assist the programmer in debugging his or her code. &SISC; provides aid for passive debugging (requiring no action on the part of the programmer) and active debugging (requiring code instrumentation to facilitate debugging). Passive Debugging Passive debugging facilities are provided that collect information on an error that occurred at runtime and was not caught by the executing code. The programmer can then inspect the last error, obtain information about the call stack of the error, or even attempt to restart the computation.
get-last-exception &procedure; exception get-last-exception
Retrieves the last exception that occurred in &SISC;.
One of the most common desires is to obtain a trace of the call stack, to determine what sequence of calls resulted in the error. &SISC; provides procedures for accessing the call stack of any continuation.
&requires; (import debugging) stack-trace &procedure; list stack-trace continuation
Returns the stack trace for continuation in form of a list. The format of the list is stack-trace := (call-frame ...) call-frame := sisc-expr | (sisc-expr overflown . stack) overflown := #t | #f stack := (stack-entry ...) stack-entry := sisc-expr | (repetitions . stack) repetitions := integer Each element in the list represents one level in the &SISC; interpreter's call stack, starting from the top. The element contains the &SISC; virtual machine expression that would be executed next in that frame, and, if available, a compact representation of a virtual stack created by collecting information on tail calls carried out in that frame. The virtual stack is bounded in size by the value of the see maxStackTraceDepth configuration parameter (see ). If old information was dropped due to the bound being exceeded then the overflown flag is set. Each entry in the virtual stack contains either the &SISC; virtual machine expression that was executed, or a sub-stack annotated with a repetition count, indicating that the entries in that sub-stack were repeated several times. &SISC; expressions are annotated with source locations if the emitAnnotations parameter is set to true. Additional annotations are produced when emitDebuggingSymbols is set to true. See . The annotations can be retrieved using the annotation function with the keys source-file, line-number, column-number, source-kind, and proc-name. Stack trace entries for expressions with a source-kind mentioned on suppressed-stack-trace-source-kinds are suppressed.
suppressed-stack-trace-source-kinds &procedure; list suppressed-stack-trace-source-kinds list
Retrieves or sets the list of source kinds to suppress in stack traces returned by stack-trace. This is a dynamic parameter. The default value is (#f) which causes all stack trace entries for expressions with no specified source kind to be suppressed. The annotation of expressions with source kinds and other information is controlled by the source-annotations parameter.
source-annotations &procedure; alist source-annotations alist
Retrieves or sets the association list of additional annotations for expressions that are being read. This is a dynamic parameter. All system and core library code is loaded with this parameter set to (), resulting in no additional annotations being produced. However, on entry to the REPL, the parameter is set to ((source-kind . user)). In combination with the default settings for suppressed-stack-trace-source-kinds this results in system code being omitted from stack traces.
print-stack-trace &procedure; print-stack-trace continuation
Displays the call stack of the continuation in a human-readable form.
The error message, location information and call stack associated with an exception can be displayed in human-readable form using the following procedure.
print-exception &procedure; print-exception exception stack-trace?
Displays the error message and location of exception. A stack trace is displayed if stack-trace? is absent or set to #t. Furthermore the procedure calls itself recursively in order to display similar information for nested exceptions.
In order to obtain the source file location of a call, your Scheme code must have been loaded while &SISC;'s reader had annotations enabled. Annotations are a means of attaching metadata to compiled Scheme code. To allow the reader to attach annotations related to the source file position of the code it reads, enable the emission of annotations with the emitAnnotations configuration parameter (see ). &SISC; can also produce more detailed stack traces if code was generated with debugging symbols. These are extra annotations generated by the compiler that track function and variable names that would ordinarily be discarded. By including these annotations, the stack trace can display the name of more of the calls involved. To enable the generation of debugging symbols, the emitDebuggingSymbols configuration parameter must be set to true (see ). Finally, when debugging a program for a long period of time, it may be desirable to have stack traces displayed whenever an error occurs, rather than needing to invoke print-exception or other functions each time. For this, the stackTraceOnError configuratin parameter must be set to true (see ).
Active Debugging &requires; (import debugging) &SISC; provides active debugging aids; procedures and syntax that can be used in source code to assist in tracing the activities of running Scheme code. Runtime Tracing When a function is traced, each call to the function will be displayed to the console with the function's trace identifier and the values of the operands the function is being applied to. Each nested call is indented slightly, so as to illustrate the depth of calls. When the function application returns, the value of the function-call is displayed at the same indentation as the call itself. Once indented to a certain depth, the same indentation is kept for further nesting, but the depth of the call is displayed as an integer preceding the call.
trace-lambda &syntax; procedure trace-lambda trace-name formals body
When replaced with a trace-lambda, all calls to a lambda defined procedure are traced on the console. trace-name is an identifier which will disambiguate the procedure in the trace. formals and body have identical semantics to lambda.
trace-let &syntax; value trace-let loop-identifier formal-bindings body
Replaces a named-let expression in a similar manner to trace-lambda.
trace &procedure; undefined trace symbol
Begins traces on the procedures named by the symbols given. The procedures must be defined in the top-level environment. If no procedures are given, a message is displayed indicating the names of top-level procedures currently being traced. If a traced procedure is redefined, it will not retain the instrumenting installed by trace, until trace or untrace is called again (with any arguments). At that time, the traced procedures are reinspected and instrumenting reinstalled on redefined procedures.
untrace &procedure; undefined untrace symbol
Stops tracing the top-level procedures named by the symbols given. If no procedures are given, a message is displayed indicating the names of top-level procedures currently being traced.
trace-lambda and trace-let are useful for debugging anonymous lambdas and named-lets respectively. trace and untrace ar useful for tracing any top-level bound procedure, including calls to builtin procedures and stored continuations. Tracing a function installs instrumentation code around the procedure which does not preserve the continuation of a call to that function. Thus, tail calls made in a traced function are no longer tail calls. This may affect the memory usage characteristics of running code.
Breakpoints A user may wish to halt execution of a running Scheme program when a given procedure is called. &SISC; provides means to install breakpoints at top-level visible functions without having to redefine the function. When a breakpoint is set using set-breakpoint!, and the function is called, execution will halt, returning to the REPL and displaying an informational message indicating a break, the procedure called, the arguments passed to the breakpointed procedure, and, if possible, the location in a source file of the call. The user may then continue execution using the continue procedure.
set-breakpoint! &procedure; undefined set-breakpoint! symbol
Instruments the top-level procedure named by the given symbol, such that when called, execution will halt and return to the REPL and the name of the breakpointed function and its arguments are displayed.
clear-breakpoint! &procedure; undefined clear-breakpoint! symbol
Removes the instrumentation on the named top-level procedure, if present. Execution will continue normally through occurances of the formally breakpointed procedure.
continue &procedure; does not return continue
Continues execution from the most recent break. It is an error to call this procedure if a breakpoint has not been hit, or to call this procedure more than once for a given break.
current-breakpoint-continuation &procedure; continuation current-breakpoint-continuation
Returns the continuation of the most recent breakpoint, or #f if execution is not currently interrupted at a breakpoint. The continuation is useful for obtaining stack traces, e.g. with (print-stack-trace (current-breakpoint-continuation)).
current-breakpoint-args &procedure; list current-breakpoint-args
Returns a list containing the current breakpoint's continuation procedure and arguments that will be used when execution is resumed with continue, or #f if execution is not currently interrupted at a breakpoint. This procedure is useful for performing deep inspection of the breakpointed procedure and its arguments. The returned values are also handy for constructing modified breakpoint continuations with set-current-breakpoint-args!.
set-current-breakpoint-args! &procedure; #t/#f set-current-breakpoint-args! procedure value
Sets the current breakpoint's continuation procedure and arguments that will be used when execution is resumed with continue. If execution is not currently interrupted at a breakpoint then invoking this procedure has no effect and it returns #f. Otherwise it returns #t.
sisc-1.16.6.orig/doc/sss/intro.xml0000644000175000017500000001652311445752462015404 0ustar amoeamoe Introduction &SISC; The pronunciation is written as sIsk in the International Phonetic Alphabet. This is similar to the English word 'whisk'. is a lightweight, platform independent Scheme system whose primary goals are rapid execution of the complete &R5RS; and future Scheme standards, plus a useful superset for real-world application development. &SISC;'s development progresses in two directions, to improve the core interpreter to be simpler, more elegant, and more efficient; and to add necessary functionality through extensions that do not complicate the core. &SISC; as a project began as the successor to the Lightweight Interpreter of Scheme Code (LISC). LISC was a small, stack-based almost R4RS compliant Scheme. &SISC; was born out of the desire to create an interpreter that was of a similar footprint to LISC, but which executed Scheme code much faster, complied fully to the &R5RS; standard, and which wasn't limited by the stack-based model. &SISC; met these goals very quickly, and has since progressed in active development to be a competitive Scheme system. As a successor to LISC the interpreter was named the Second Interpreter of Scheme Code. Features Full &R5RS; compliance Efficient number tower, with support for integers, floating-point numbers, rationals, and complex numbers of arbitrary precision Lightweight Scheme engine, implementing all &R5RS; functionality in approximately 10,000 lines of native code plus approximately 5,000 lines of Scheme code. Flexible runtime extensibility through a scopeable module system, which may add arbitrary bindings and new first-class types. About this document This document explains the &SISC; Scheme system. It assumes knowledge of the Scheme language. As such, when discussing the Scheme language, we will focus primarily on differences between the Scheme standard and the language implemented by &SISC;. Secondly, &SISC; implements the &R5RS; standard. As such, any code written to that standard should run without reading any further. About procedure documentation Throughout this document, procedures will be defined using the following syntax:
&procedure; return value function-name required-argument optional-argument rest-argument
Description of the procedure's semantics.
A procedure is any function that takes zero or more arguments and returns a value.
¶meter; parameter-name new-parameter-value
Description of the parameter.
A Parameter is a special function that is used to store a value in the dynamic-environment. When given no arguments, a parameter will return its current value. When provided an argument, the value of the parameter is set to the value of that argument.
&syntax; syntactic-keyword structure
Description of the syntactic transform.
Syntax refers to a syntactic keyword that when compiled will be transformed into some expression composed only of basic Scheme forms. let, cond, and or are all examples of syntactic forms.
Procedures, parameters, and syntax may take one or more arguments. The name of an argument in a description summarizes the semantics of the expected argument. The type of an argument, when not clear, should be described in the procedure summary paragraph that follows the prototype. If the argument is enclosed in square brackets ([]), that argument is optional, and may be omitted. If an argument is optional and is followed by ellipses (...), then the argument is a rest argument, and may be satisfied by zero or more values. Finally, some of the functions described in this document are encapsulated in modules (see ). Sections that describe functions in modules will have a requires statement indicating the expression that must be evaluated to make those functions available in the Scheme environment. The requires statement will appear as follows: &requires; (import module-name) module-name is will be a name uniquely identifying the name of the module that contains the functions.
Where to obtain this document This document is produced from DocBook sources and is made available in HTML, Adobe Acrobat (PDF), and PostScript forms. Other formats, and up-to-date versions of this document should be available from the &SISC; website, http://sisc.sourceforge.net . The DocBook sources are available from the same site, packaged in the source distribution of &SISC;, and available from the project's CVS tree. Details for accessing both are linked off the project site. Starting with &SISC; version 1.8.4, the HTML render of this manual is included in the full binary distributions of &SISC;. Version Applicability &version;
sisc-1.16.6.orig/doc/sss/inst.xml0000644000175000017500000007726111445752462015234 0ustar amoeamoe Installation and Invocation Required Environment &SISC; primarily targets the Java Virtual Machine, and the Java v1.3 and higher class libraries. The 1.2 libraries and VM are required due to a reliance on memory reference functionality used to properly garbage collect unused symbols while still maintaining pointer equality between those that remain active, while the 1.3 libraries are needed for the proxy functionality of the Java bridge library. &SISC; does not require any particular operating system, though the official distribution currently provides launching assistance for Windows and Unix based systems. Theoretically any machine that supports Java 1.3 or higher should be able to run &SISC;. The Read-Eval-Print-Loop As in most Scheme systems, &SISC;'ss primary human interface is a REPL, or Read-Eval-Print-Loop. &SISC; presents the user with a prompt ('#;>'), then reads an s-expression from the console. &SISC; then evaluates the s-expression, producing a value or error, which it then prints. Finally the process begins again with a new prompt. The process terminates with a forced kill of the JVM (with Control-C or similar), or when an end of file is detected on the console. Also, the exit procedure may be used to exit the current REPL.
exit &procedure; does not return exit return-value
Instructs the current REPL to exit. If the optional return value is given, the value will be passed out of the REPL to the calling code or environment.
Evaluation may be prematurely interrupted on some platforms by sending SIGQUIT (usually by pressing Control-C) to the &SISC; process. If supported, this will cause an interrupted error to be raised at whichever expression is currently being evaluated in the REPL thread. If not caught, this will cause the error to be raised at the console and a new prompt will be displayed. Issuing the signal twice will terminate &SISC;.
Display Conventions Executing or loading code in the REPL ordinarily produces a value result which is displayed during the Print phase. However, two other message types may be displayed. First, if an error is raised that is not handled by the running program, the message will be described in one of several forms, depending on what combinations of a location, a message, and a parent message the error has: Error. Error in <error-location>. Error: <description> Error in <error-location>: <description> Error in nested call. <nested-error> Error in nested call: <description> <nested-error> Error in nested call from <error-location>. <nested-error> Error in nested call from <error-location>: <description> <nested-error> The location of an error often refers to the name of a procedure, syntax, or parameter. Errors that do not contain a location often originate in an anonymous function. Nested errors occur when one function makes a call to another function and the second raises an error. If the first function wishes, it may catch this error and generate its own, with the second functions error as a parent. Thus a nested error consists of an error message on the first line, and the nested error message or messages on following lines. In addition to errors, it is possible for code to produce warnings during compilation or run-time. A warning is a message to the user about a condition that is unusual but not terminal to the program flow. The compiler, for example, does a minimal amount of sanity checking on code and may produce warnings about code that has the potential to raise errors during execution. Warnings are always distinguished from ordinary messages by surrounding braces ({}) and starting with the word 'warning'. {warning: <description>} Running &SISC; &SISC;'s official distribution provides a startup script for Windows and Unix based hosts. Simply executing this script starts the &SISC; REPL. Zero or more Scheme source files can also be specified on the command line after the script name, which will be loaded in order before the REPL prompt is displayed. It may be desirable to pass options to the underlying JVM. This can be done by setting the JAVAOPT environment variable to the options you wish to pass to the JVM. This includes switches for heap size, system properties, etc. &SISC; itself has a number of properties that can affect its operation. See for a list of these properties and their meanings. Command-line Switches &SISC; can, in addition to loading Scheme source programs, also accept a few command-line switches to change its behavior. Any non-switch argument is considered a Scheme source file to load on startup, until the end of options characters "--" are reached. Any item after those characters are considered arguments to the function specified in the "call-with-args" switch. All command-line switches have both a short and long form. These forms are equivalent in meaning. &SISC; Command line Switches Long Switch Short Switch Switch meaning --call-with-args <name> -c <name> Call the top-level procedure name with the remaining command-line arguments after the "--" sequence. --eval <expression> -e <expression> Evaluate the provided expression. --no-repl -x Exit after loading all the Scheme source files and processing all command-line switches. --heap <heap-file> -h <heap-file> File containing pre-compiled code and data for a complete Scheme top-level environment. This parameter is mandatory if the heap cannot be located automatically. --properties <config-file> -p <config-file> Specifies a Java properties file that contains application properties. Typically some of these properties define defaults for configuration parameters (. The file can be specified as a URL. --listen [<host>:]<port> -l [<host>:]<port> Listen on host/port for REPL connections, i.e. connecting to the specified host/port will create a new REPL.
The order of processing the command line is as follows: Process the entire command line, noting the settings of each switch and accumulating all Scheme source files and arguments after the end of options sequence. Load the heap file. Load each Scheme source file found in the order they occured on the command line. Note whether any errors occurred. If present, evaluate the expression in an --eval switch. Note its success or failure. If present, apply the named function in a --call-with-args switch to the arguments after the end of options sequence. Note its return value. If --no-repl was not specified, invoke the REPL, otherwise exit. If the REPL was run if its return value is an integer, return that integer as &SISC;'s overall return code. If the REPL was not run, and any return code supporting step above was run, return the most recent return code. If no return code step was performed, but a success/failure step was performed, return 1 if any failures occured, 0 otherwise.
Configuration Parameters SISC's behaviour is affected by a number of configuration parameters. These fall into two categories: Static configuration parameters that can only be specified at system startup and apply across all &SISC; applications that use the same classloader. Dynamic configuration parameters that can be altered on a per-thread basis without impacting other threads. These kind of parameters are also called "thread locals", or, in Scheme terminology, dynamic parameters. Static Parameters Static configuration parameters can be set using Java system properties. Their value can be retrieved with a Scheme function, but it is not possible to alter it. Static configuration parameters default to pre-defined system-internal settings if left unspecified. &SISC; has the following static configuration parameters: Java property The names of all properties for configuration parameters must be prefixed with sisc.. Scheme parameter default description permit-interrupts permitInterrupts permit-interrupts true If set to true, thread/interrupt is permitted to interrupt running Scheme code, in addition to sending an interrupt signal to the host language. min-float-precision minFloatPrecision min-float-precision 16 Specifies the minimum precision, in decimal places, to be maintained by the Quantity lib if using arbitrary precision floats. max-float-precision maxFloatPrecision max-float-precision 32 Specifies the maximum precision, in decimal places, to be maintained by the Quantity lib if using arbitrary precision floats. When static configuration parameters are retrieved with their associated Scheme function, the value is of the type specified for the parameter. See . Dynamic Parameters There are four ways to specify a configuration parameter, in decreasing order of precedence: Invoking a scheme function. Dynamic configuration parameters are special Scheme parameters (see . Invoking the parameter with a value sets the parameter for the current thread without affecting other dynamic contexts / threads. Defining an application property. A single &SISC; runtime can host multiple applications simultaneously. Application properties define default values for dynamic configuration parameters across all dynamic contexts / threads of an application. They can be specified at application initialisation time. See . When &SISC; is started from the command line, the location of a Java properties file containing application properties can be specified with a command line option. See . Defining a Java system property. Java system properties define default values for dynamic configuration parameters that apply across all applications inside a single &SISC; runtime. System defaults. All dynamic configuration parameters have a reasonable default value. &SISC; has the following dynamic configuration parameters: Java property Scheme parameter default description case-sensitive caseSensitive case-sensitive false Determines whether symbols read via the Scheme reader are to be treated case sensitively. character-set characterSet character-set "UTF8" Defines the default character set used by character ports (see ) if no character set is otherwise specified. emit-annotations emitAnnotations emit-annotations true If set to true, this parameter causes source files loaded with load or import, as well as source entered in the console, to be annotated by the Scheme reader. Annotations include source file location information, which simplifies debugging. See . emit-debugging-symbols emitDebuggingSymbols emit-debugging-symbols true If set to true, additional annotations useful for debugging, such as function and variable names, are produced by &SISC;'s compiler. See . max-stack-trace-depth maxStackTraceDepth max-stack-trace-depth 0 Specifies the maximum depth of virtual call stacks, which are used to obtain proper stack traces even in the presence of tail recursion and continuation capture and invocation, while still preserving tail-call semantics and safe-for-space guarantees. See . Collecting this information is computationally expensive, so this feature is turned off by default. A value of 16 is about right for debugging most applications. Large values allow collection of more information but carry a large performance penalty, small values result in some call information being lost. permissive-parsing permissiveParsing permissive-parsing false If set to true, the Scheme parser will warn rather than raise an error for various syntactic errors such as unbalanced parentheses. This allows one to continue parsing a syntactically invalid file, finding many errors at once. print-shared printShared print-shared true If set to true, write and the REPL detect shared structures in data and invoke a version of write capable of emitting the shared structure's external representation of data. See . The user may wish to set this parameter to false because of the overhead of both scanning all data, and constructing this representation when shared structures are detected. repl-prompt replPrompt repl-prompt String to be displayed as part of &SISC;'s REPL prompt. stack-trace-on-error stackTraceOnError stack-trace-on-error true If set to true, whenever an uncaught error is encountered a full stack trace is displayed automatically. See . strict-r5rs-compliance strictR5RSCompliance strict-r5rs-compliance false If set to true, strict &R5RS; syntax and semantics are followed. This will cause SISC to raise errors in all situations described as "an error" in the Scheme standard. This will override and invalidate all the interpretation liberties described in . synopsis-length synopsisLength synopsis-length 30 Limit on the length (in characters) of the external representation of data structures in error messages and warnings. When the limit is reached, an ellipsis (...) is appended to the curtailed external representation. vector-length-prefixing vectorLengthPrefixing vector-length-prefixing true If set to true, this parameter will instruct the pretty-printer to emit length prefixed, trailing-duplicate-eliminated vectors in its output. If false, ordinary full-length vectors without prefixes will be emitted. See . When dynamic configuration parameters are retrieved or set with their associated Scheme function, the value is of the type specified for the parameter. See . Value Conversion When specifying configuration parameters via Java properties, a Java-like notation is used, e.g. boolean parameters are specified as true and false. By contrast, when getting and setting configuration parameters from Scheme, their values are of the appropriate Scheme type, e.g. boolean parameters are specified as #t and #f. Strings and symbols undergo a similiar conversion; they are specified without their double/single quotes in the Java properties. For parameter types other than boolean, string and symbol, Java properties are read as Scheme values, i.e. Scheme literal notation should be used in the properties.
Running Scheme Programs Loading &SISC; supports loading Scheme programs using the &R5RS; optional procedure load. A number of file types for loading Scheme code are supported. The common extensions are: scm - Scheme source code sce - Scheme code expanded. This type of code has been processed by the syntax expander and contains only core Scheme forms. scc - &SISC; Compiled Code. This contains expanded and compiled code in a &SISC; specific representation. The code gets executed when loaded. In addition to code loaded, &SISC; requires a heap, which contains the default set of libraries and functions for the initial environment. &SISC; will look for a heap file called sisc.shp in the current directory, the directory referenced by the SISC_HOME environment variable, and as a resource paired with the HeapAnchor class in the sisc.boot package of the classpath. The standard &SISC; distribution contains sisc.shp in the same directory as the supporting .jar files. It isn't uncommon to want the heap to reside on the classpath, where it can be more easily resolved in applets or in web applications. This file, usually called sisc-heap.jar can be added to the classpath in any usual fashion, and the heap loading routines will discover it if not found elsewhere. To create a jar file containing the heap, create the following file structure in the jar: sisc/ sisc/boot/ sisc/boot/HeapAnchor.class sisc/boot/sisc.shp The HeapAnchor.class class file is distributed in the sisc-opt.jar file of the full binary distribution. Scheme Shell Scripts On Unix or Unix-like systems, &SISC; supports SRFI-22, a mechanism for writing shell-like scripts that can be invoked directly as executable programs. The text of the SRFI, which can be found at http://srfi.schemers.org, describes how such programs are written.
sisc-1.16.6.orig/doc/sss/gpl.xml0000644000175000017500000005300711445752462015031 0ustar amoeamoe GNU General Public License Version 2, June 1991 1989, 1991 Free Software Foundation, Inc.
Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
.
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Version 2, June 1991
GNU General Public License Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software - to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: copyright the software, and offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION Section 0 This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a work based on the Program means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term modification .) Each licensee is addressed as you. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. Section 1 You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Section 2 You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. Exception: If the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. Section 3 You may copy and distribute the Program (or a work based on it, under Section 2 in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. Section 4 You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. Section 5 You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. Section 6 Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. Section 7 If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. Section 8 If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. Section 9 The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. Section 10 If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY Section 11 BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. Section 12 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> 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 of the License, 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
sisc-1.16.6.orig/doc/sss/extensibility.xml0000644000175000017500000011673711445752462017155 0ustar amoeamoe Extensibility Occasionally functionality may be desired that is not easily accomplished at the Scheme level. A new first-class type may be desired, or efficient access to a Java library. &SISC; provides a simple API for such modifications. Adding Types A Scheme value is represented in &SISC; as a subclass of the abstract Java class sisc.data.Value. External Representation of Values In order to be able to display the value in the Scheme system, all Values must implement the display method:
display public display sisc.io.ValueWriter writer
Uses the various output methods of sisc.io.ValueWriter to construct an external representation of the given Value suitable for output from the display Scheme function.
If the programmer desires the Value to have a different representation when written with write, the write method must be overridden. If it is not, the output of display is used for write as well.
write public write sisc.io.ValueWriter writer
Uses the various output methods of sisc.io.ValueWriter to construct an external representation of the given Value suitable for output from the write Scheme function. If not implemented, the output constructed the by the display method is used as output from write.
Finally, if the external representation of a new Value is likely to be long, the programmer should implement the synopsis method, which generates a summary representation of the value.
synopsis public String synopsis int limit
Returns approximately limit characters from the printable representation of this value as if returned by write. This method is used for displaying the value in error messages where the entire representation may be superfluous.
The sisc.io.ValueWriter type that is passed as an argument to both display and write contains a number of methods to generate the representation. First there are several methods for appending Java Strings, characters, and SISC Values. In each, the called ValueWriter is returned, to allow for easy chaining of calls.
append public sisc.io.ValueWriter append char c
Appends a single character to the external representation.
public sisc.io.ValueWriter append String s
Appends the contents of a Java String to the external representation.
public sisc.io.ValueWriter append sisc.data.Value v
Appends the contents of a Scheme value to the external representation. The value is converted to an external representation using the print style with which the ValueWriter was constructed (for example, display or write).
In addition to the above append methods, the programmer may wish to force display or write rather than use the same method as the ValueWriter. To do this, one can call the display or write methods on the ValueWriter.
display public display sisc.data.Value v
Appends the external representation of the given value as returned by display.
write public write sisc.data.Value v
Appends the external representation of the given value as returned by write.
Equality If the one wants a Value to be comparable for any more than pointer equality, or for the concept of pointer equality to be less strict than actual pointer equality, one or more of the equality methods must be overridden.
eq public boolean eq Object other
Returns true if another provided Java object is equal in the sense of eq? to this Value.
valueEqual public boolean valueEqual Value other
Returns true if another provided Scheme value is equal in the sense of equal? to this Value.
Serializable Values If the type that is being added will be serialized in a &SISC; heap, and it contains one or more member variables, the Value must include a default constructor (a constructor with no arguments), and implement the deserialize, serialize, and visit methods described in .
Adding Native Bindings One can add native bindings to the Scheme environment by implementing a subclass of the abstract class sisc.nativefun.NativeLibrary. Such a subclass needs to implement four methods:
getLibraryName public String getLibraryName
Returns the name of this library. The name should also be acceptable for use in filenames.
getLibraryVersion public float getLibraryVersion
Returns the version of this library.
getLibraryBindingNames public sisc.data.Symbol[] getLibraryBindingNames
Returns an array of the names of the bindings exported by this library. Each name is a Scheme symbol.
getBindingValue public Value getBindingValue sisc.data.Symbol name
Returns the value of a given binding exported by this library.
Native Procedures It is possible to implement Scheme functions whose behavior is implemented natively in Java code. Many of &SISC;'s procedures are implemented this way. Native procedures extend the sisc.nativefun.NativeProcedure abstract class. Working NativeProcedure subclasses must implement the doApply method, as described below.
doApply public Value doApply sisc.interpreter.Interpreter interp
Perform the necessary computations of the NativeProcedure, returning a Value as the result of the procedure call. The arguments to the procedure can be found in the value rib array field, vlr, of the Interpreter passed as an argument. The number of arguments to the procedure can be found from the length of the array (vlr.length).
If the native procedure wishes to raise an error, it may do so by throwing any Java runtime exception (subclass of java.lang.Runtime). For a more descriptive error, one may raise a &SISC; error using any of a number of error forms in sisc.util.Util. Consult the source of Util or inquire on the sisc-devel mailinglist for assistance.
Fixable Native Procedures Often it is unnecessary to have access to the full Interpreter context to implement a native procedure. If the arguments to the procedure are sufficient and the procedure is purely functional (causes no side effects), it is recommended that the programmer create a fixable native procedure. These native procedures may be inlined into generated code when enabled, allowing much faster execution. In addition, the fixable native procedure interface is simpler to use. The FixableProcedure abstract class consists of five methods which may or may not be subclassed. These five methods correspond to the case of calling the procedure with no, one, two, three, and more than three arguments respectively. Not overriding one of these methods will cause a call to the fixable procedure to throw the invalid number of arguments error to the caller.
apply public Value apply
Perform the necessary computations of the FixableNativeProcedure, returning a Value as the result of the procedure call. No argument variant.
apply public Value apply Value v1
Perform the necessary computations of the FixableNativeProcedure, returning a Value as the result of the procedure call. One argument variant.
apply public Value apply Value v1 Value v2
Perform the necessary computations of the FixableNativeProcedure, returning a Value as the result of the procedure call. Two argument variant.
apply public Value apply Value v1 Value v2 Value v3
Perform the necessary computations of the FixableNativeProcedure, returning a Value as the result of the procedure call. Three argument variant.
apply public Value apply Value[] v
Perform the necessary computations of the FixableNativeProcedure, returning a Value as the result of the procedure call. More than three argument variant.
Indexed Native Libraries In the most common case, a Library is created to define several bindings, including procedures whose implementations are in Java code. For this common case, a skeleton subclass of NativeLibrary, sisc.nativefun.IndexedLibraryAdapter is provided. The IndexedLibraryAdapter class provides implementations for all four required NativeLibrary methods, and introduces a new abstract method which must be implemented, called construct. In addition, the method define is provided. In an indexed native library, each binding is associated with a Java int unique to that binding within the library. The IndexedLibraryAdapter subclass should in its constructor call define for each binding provided by the library, according to the contract of the method:
define public void define String name int id
Register the native binding with the given name, and assign it the given library-unique id.
In implementing the getBindingValue method of the NativeLibrary class, an IndexedLibraryAdapter will call the abstract method construct required by the its subclasses:
construct public sisc.data.Value construct int id
Return an instance of the indexed binding.
Most frequently, the bindings created in an indexed library are native procedures. In such a case, a second class is created which subclasses sisc.nativefun.IndexedProcedure. IndexedProcedure is subclass of NativeProcedure. An IndexedProcedure subclass' constructor must call the superconstructor with an int, the unique id for that binding. That int is stored in the id field of IndexedProcedure. A subclass can then use the id instance variable to dispatch to many native procedures in the body of the doApply method required by native procedures. So, typically, an IndexedNativeLibrary subclass is created whose construct method creates instances of IndexedProcedure subclasses. The IndexedNativeLibrary subclass its itself nested in the IndexedProcedure class which it is constructing. See the various indexed libraries in sisc.modules for concrete examples.
Serialization &SISC; provides an API for serializing the state of a running Interpreter. The &SISC; heap is a dump of the state of an Interpreter with the necessary code to implement &R5RS; Scheme, for example. In order to facilitate this serialization, &SISC; Expressions and Values can implement helper methods to define the serialization of the object. If the Expression or Value contains no internal state that need be serialized, the serialization methods may be ignored. If not, the Expression or Value must contain a default (no argument) constructor, and implement the following three methods:
serialize public serialize sisc.ser.Serializer serializer java.io.IOException
Serializes the contents of the Expression to the given Serialization context.
deserialize public deserialize sisc.ser.Deserializer deserializer java.io.IOException
Sets the state of the Expression to the serialized data read from deserializer.
visit public boolean visit sisc.util.ExpressionVisitor visitor
When called, the Expression should call visitor.visit(n) on any nested Expressions.
The Serializer and Deserializer objects implement Java's java.io.DataOutput and java.io.DataInput interfaces, respectively. This means that you can use any of the write/read functions in those interfaces to serialize the state of your Expression or Value. In addition, a number of methods are provided that are helpful for this domain. The ExpressionVisitor passed to visit contains only one method, visit, which bears the same contract as the visit above. When called, an Expression would then call the ExpressionVisitor's visit method once for each nested Expression. This method is used during serialization and during printing to detect cycles in data and code structures. Deserializer methods
readBigInteger public BigInteger readBigInteger java.io.IOException
Reads a BigInteger from the stream.
readBigDecimal public BigDecimal readBigDecimal java.io.IOException
Reads a BigDecimal from the stream.
readClass public Class readClass java.io.IOException
Reads a Java Class object from the stream.
readExpression public Expression readExpression java.io.IOException
Reads a &SISC; Expression from the stream.
readInitializedExpression public Expression readInitializedExpression java.io.IOException
Reads a &SISC; Expression from the stream, fully initialized. This method should only be used if fields internal to the Expression returned must be available during deserialization.
readExpressionArray public sisc.data.Expression[] readExpressionArray java.io.IOException
Reads an array of Expressions from the stream.
readValueArray public sisc.data.Value[] readValueArray java.io.IOException
Reads an array of Values from the stream.
readSymbolicEnvironment public SymbolicEnvironment readSymbolicEnvironment java.io.IOException
Reads a &SISC; Symbolic Environment from the stream.
Serializer methods
writeBigInteger public void writeBigInteger BigInteger bigint java.io.IOException
Writes a BigInteger to the stream.
writeBigDecimal public void writeBigDecimal BigDecimal bigdecim java.io.IOException
Writes a BigDecimal to the stream.
writeClass public void writeClass Class clazz java.io.IOException
Writes a Java Class object to the stream.
writeExpression public void writeExpression Expression expr java.io.IOException
Writes a &SISC; Expression to the stream.
writeInitializedExpression public void writeInitializedExpression Expression expr java.io.IOException
Writes a &SISC; Expression to the stream. This method should only be used if fields internal to the Expression returned must be available during deserialization.
writeExpressionArray public void writeExpressionArray sisc.data.Expression[] ary java.io.IOException
Writes an array of Expressions to the stream.
writeValueArray public void writeValueArray sisc.data.Value[] ary java.io.IOException
Writes an array of Values to the stream.
writeSymbolicEnvironment public void writeSymbolicEnvironment SymbolicEnvironment e java.io.IOException
Writes a &SISC; Symbolic Environment to the stream.
sisc-1.16.6.orig/doc/sss/html.xsl0000644000175000017500000001025211445752462015214 0ustar amoeamoe 0 sss.css Unrecognized language on : [ ( ) ] ( ) ... ( ) => sisc-1.16.6.orig/doc/sss/scheme.xml0000644000175000017500000024115111445752462015512 0ustar amoeamoe Scheme Language In this chapter we will examine the language that &SISC; interprets, which is a superset of the &R5RS; Scheme Standard. Types Numbers The full Scheme number tower is supported: Integers Floating Point numbers Rational numbers Complex numbers Depending on the numeric library compiled into &SISC;, floating point numbers have either 32 or 64 bit IEEE precision, or arbitrary Essentially arbitrary, see for a discussion of the physical limits of number representation precision. Regardless, &SISC;'s complex numbers have floating point components of the same precision as the reals. Integers have arbitrary precision in all numeric libraries, and rational numbers are built with arbitrary precision components. Numeric constants The precision specifying exponents (S, F, L, and D) are ignored in &SISC;, all inexact numbers are kept in the precision of the numeric library. The exponents are read and used to scale the real number as expected. In the case of arbitrary precision floats, specific precision constraints are maintained to prevent a runaway increase of precision. The constraints can be set by minFloatPrecision and maxFloatPrecision configuration parameters on startup. See . All four base specifiers (#x, #o, #d, #b) are supported for integers and rationals. Only decimal (#d), the default, is supported for floating point and complex numbers. &SISC; will produce infinite or not-a-number quantities from some operations. Those quantities are represented and can be used in Scheme programs as #!+inf (positive infinity), #!-inf (negative infinity), and #!nan (not-a-number). Exactness Exactness and inexactness contagion behaves as expected. Rational's are made inexact through division. Floats are made exact by conversion to a rational number. &SISC; attempts as accurate a conversion as possible, by converting the decimal portion of the number to a ratio with a denominator of the form 10^n, where n is the scale of the floating point number. Then the fraction is reduced as usual. Since complex numbers must have floating point components currently, conversion to an exact merely rounds the components to integers. Characters &SISC;'s characters are double-byte wide. This means that they are capable of representing the full range of unicode characters. Unicode characters can be created with number->character; #\nnnnnn, where nnnnnn is an octal number in the range 000000 -> 177777; or #\uxxxx, where xxxx is a hexadecimal number in the range 0000 -> ffff. At least two zeros must be specified to distinguish from the '0' character when using an octal character literal. At least one zero must be specified to distinguish a hexadecimal character from the 'u' character. &SISC; also provides additional named characters, to add to the Scheme standard's space and newline: Named character literals Character Name Unicode Value (hex) backspace 0008 newline 000a nul 0000 page 000c return 000d rubout 007f space 0020 tab 0009
Formally, &SISC;'s lexer modifies the &R5RS; grammar with the following productions for character literals: <character> --> #\ <any character> | #\u <uinteger 16> | #\ <uinteger 8> | #\ <character name> <character name> --> backspace | newline | nul | page | return | rubout | space | tab Characters are not compared with respect to the locale of the running system. Character comparison is equivalent to numeric comparison of the character value as returned by char->integer. There are a number of reasons why a full Unicode system is non-trivial, especially within the framework of the &R5RS; string and character functions. Such a discussion is outside the scope of this document. Unicode compliant processing may be made available in the future as a library, however.
Symbols &SISC;'s symbols are ordinarily case-insensitive. &SISC; maintains true pointer equality between symbols with like contents, unless the symbol is created uninterned. An uninterned symbol is one which is guaranteed to be pointer distinct from any other symbol in the Scheme system, even another with the same contents. Uninterned symbols can be generated with:
string->uninterned-symbol &procedure; symbol string->uninterned-symbol string
Converts the provided string into an uninterned, pointer distinct symbol.
Uninterned symbols, while always pointer-distinct, may still be equal? to another symbol if its representation matches another. Case Sensitivity &SISC; also allows symbols to be created that are case-sensitive. This can be done one of two ways. The first is by setting the caseSensitive configuration parameter (see . The second method is via a non-standard symbol syntax. If a symbol is enclosed in pipe ('|') characters, the reader will treat that individual symbol as cased. The syntax extends the &R5RS; grammar with the following production: <cased symbol> --> |<identifier>| Case sensitive Symbol literals (eq? 'a '|A|) ; => #f (eq? 'a '|a|) ; => #t (eq? '|A| '|a|) ; => #f Printed Representation Symbols may contain characters that are disallowed by &R5RS; using symbol->string. In such a case, the printed representation of that symbol will contain those characters, prefaced with the escape ('\') character. Likewise, such symbols may be created without symbol->string by escaping non-standard characters. Symbols which contain characters that could only be present in a case-sensitive environment will be printed in one of two ways, depending on the value of the case-sensitive parameter. If true, the symbols will be printed as is, containing the upper and lower case letters. If false, the symbol will be printed surrounded by pipe characters.
Strings Strings are built from Unicode characters, and are compared lexicographically in a manner derived from character comparison. In addition to using backslash to escape the double-quote (") character and the backspace character itself, &SISC; provides several escape codes to ease string literal construction. String escape codes Escape Value \f Inserts the formfeed character (unicode 000c) \n Inserts the newline character (unicode 000a) \r Inserts the rubout character (unicode 007f) \t Inserts the tab character (unicode 0009) \uxxxx Inserts the unicode character described by the hex number 'xxxx'. All four hex digits must be specified. \\ Inserts the backslash ('\') character \" Inserts the double quote ('"') character
Pairs and Lists A function is provided to determine if a given pair is a proper list.
proper-list? &procedure; #t/#f proper-list? datum
Returns #t if the given argument is a proper-list. That is, if the argument is a pair, whose cdr is either the empty-list or also a proper-list, and which contains no references to itself (is not circular).
Vectors &SISC; supports the length prefix method of creating Vector constants. For example, '#5(x) creates a vector constant containing five identical symbols. In addition, the length-prefix form is used when printing vectors, and if elements repeat at the end of a Vector, only the last unique element is printed. This form is referred to as the compact vector representation. The unprefixed form with all elements displayed is called the verbose representation. Vectors are displayed differently depending on the call used. When called with display, in addition to the ordinary &R5RS; rules regarding the output of values displayed with display, the verbose representation is displayed. Using write, on the other hand produces the compact representation. Displaying a vector with pretty-print may output either the verbose or compact representation of a vector. The behavior in this regard is controlled by the vectorLengthPrefixing configuration parameter (see ). If set to #t, pretty-print will emit the compact representation. If #f, the verbose representation is produced. Boxes &SISC; supports boxes, a container for a Scheme value. Boxing is often used to implement call-by-reference semantics. Boxes are created and accessed using the following three functions:
box &procedure; box box value
Creates a box filled with the given value.
unbox &procedure; value unbox box
Returns the value contained in the given box.
set-box! &procedure; undefined set-box! box value
Replaces the value contained in the given box with the value provided.
In addition to the box function for creating boxes, &SISC; provides an external representation for boxes and boxed values. It extends the &R5RS; grammar with the following: <boxed value> --> #&<datum> This syntax denotes a boxed value, with <datum> as the contained value. Boxes are a distinct first class type. The box? predicate tests a value to see if is a box.
box? &procedure; #t/#f box? value
Returns #t only if the given value is a box.
Boxes, like pairs, are only equal in the sense of eq? and eqv? when a box is compared with itself. A box is equal to another in the sense of equal? if the value contained within the box is equal? to the value contained in the other.
Parameters A parameter is a named dynamic variable that is accessed through a function. The function, when given no arguments, returns the current value of the parameter. When given an argument, the value of the parameter is set to the provided value. &SISC;'s parameters are fully compatible with those specified by SRFI-39. Consult the SRFI-39 specification at srfi.schemers.org for documentation on how to construct and use parameters. SRFI-39 does not specify the semantics for parameters in the presence of threads. SISC's parameters bind into the dynamic environment, which means their semantics are defined based on the semantics of dynamic environments' interactions with threads, specified in . Immutable types &SISC; follows the &R5RS; recommendation of immutable list, string, and vector constants. Quoted lists and vectors are immutable. Attempting to modify elements in these constants will raise an error. String constants are immutable as well when created with symbol->string.
Equivalence &SISC;'s storage model maintains true pointer equality between symbols, booleans, the end-of-file object, void, and the empty list. Thus two instances of any of those types is guaranteed to return #t from eq? if they would have produced #t from equal?. Numbers and characters are not pointer equal ordinarily (unless actually occupying the same storage). &SISC; will return #t from eqv? if two numbers are both exact, or both inexact, and are numerically equal. Two characters are equivalent from eqv? if they occupy the same code-point in the unicode character set. This is the behavior specified by &R5RS;. Strings, vectors, lists, and boxes are containers for other Scheme types. As such they are not pointer equal unless they are referenced by two variables that point to the same storage location (i.e. they are actually pointer equal). &SISC; holds that only equal? will return #t if two objects are the same type and their contents contain equivalent values with respect to equal?. Syntax and Lexical Structure Comments In addition to the single line comments of the Scheme standard, &SISC; supports both s-expression commenting and nested, multiline comments. An s-expression comment is used to comment out an entire s-expression. To do this, the sharp sequence #; is used. It extends the &R5RS; grammar with the following production: <expression-comment> --> #;<datum> The reader, upon encountering this sharp sequence, will read and discard the next datum. The expression commented out must still be a valid s-expression, however. Nested, multiline comments are as defined in SRFI-30. Briefly, a multiline comment begins with the sharp sequence #| and ends with the sequence |#. The comment may contain nested comments as well. Unfortunately, this extension cannot be represented in a stateless grammar for the lexical structure. Shared Structures Reader Syntax &SISC; provides a parse-time syntax for creating data (primarily vectors and lists) that contain references to themselves or data which contains several pointer-equal elements. This can be useful to create streams, graphs, and other self-referencing structures while maintaining readability and avoiding complex construction code. The reader syntax has two parts, defining a pointer, and later referencing the pointer to create the circular reference. Below is an additional production in the &R5RS; formal syntax (specifically section 7.1.2, external representations) to support circular structures: <pointer definition> --> #<uinteger 10>=<datum> <pointer reference> --> #<uinteger 10># The first form instructs the reader to create a pointer identified by the specified integer, which maps to the datum that follows, and is active during the reading of the datum on the right-hand side of the definition. If a second definition occurs during the reading of the datum with the same integral identifier, the previous definition is overwritten for the duration of the read. The definitions are not scoped in any way. The pointer identifiers should be kept unique by the programmer to prevent any unintended effects of identifier collisions. The second form references a previously created pointer definition. It is an error to reference an undefined pointer. The reader will handle a valid reference by placing a pointer at the current read position back to the location of the definition. At this point some examples might be helpful: Circular Structures (define x '#0=(1 2 . #0#)) (caddr x) ; => 1 (list-ref x 15) ; => 2 (define y '(1 2 #1=#(3 4) . #1#)) (eq? (caddr y) (cdddr y)) ; => #t Writing Ordinarily, the display of cyclical data would cause a problem for a Read-Eval-Print-Loop. For this reason, the REPL will attempt to check the structure it is about to print for circularities before printing. If a cycle is found in the structure, the REPL will refuse to print if the printShared configuration parameter, described below, is false. In that case the REPL will issue a warning to the user that the structure contains a cycle. If a circular structure is printed with display, write, etc, and the printShared parameter is set to false, the environment may enter an infinite loop which may or may not cause the Scheme system to exit with an error. The printShared configuration parameter (see ), if set to true enables &SISC; to scan data for circularity and data sharing before writing values. If such sharing is found, an alternate printer is invoked which will emit a representation compatible with the circular structure representation described in the previous section. Alternately, &SISC; also supports SRFI-38, which describes the functions write-showing-shared and read-with-shared-structure. Control Features In addition to the &R5RS; standard control features, two additional forms, when and unless, are supported by &SISC;.
when &syntax; value when condition expression expressions
Evaluates condition, an expression. If true, the expressions that follow are evaluated, in order, the value of the last being returned. If not true, the result is unspecified.
unless &syntax; value unless condition expression expressions
Evaluates condition, an expression. If false, the expressions that follow are evaluated, in order, the value of the last being returned. If true, the result is unspecified.
Syntactic Extension &SISC; provides a hygienic macro system that fully conforms to the &R5RS; standard. The macro system is provided by the portable syntax-case macro expander. In addition to &R5RS; macros, the expander provides a more flexible macro definition tool called syntax-case. A full description of the capabilities of the expander is best found in the Chez Scheme Users Guide , specifically Section 9.2, Syntax-Case . In addition, &SISC; supports non-hygienic, legacy macro support in two forms; define-macro and defmacro. These forms, found in older Scheme code written for R4RS compliant Scheme systems, should be used only for executing legacy code which relies on it. New code should use the safer and more flexible syntax-case or the standard syntax-rules macros.
define-macro &syntax; define-macro (name . args) body &syntax; define-macro name transformer
In the first form, define-macro creates a macro transformer bound to name, which when applied will have raw s-expressions bound to one or more parameters (args). The (name . args) name and formal parameter form is identical to the short form for procedure definition with define. The transformer's body will then, using the s-expressions bound to its arguments, return a new s-expression that is the result of the macro transformation. The second form binds an arbitrary procedure to the syntactic keyword name, using that procedure to transform occurences of that named syntax during future evaluations.
defmacro &syntax; defmacro name args body
defmacro is another macro definition form supported by some Scheme systems. Its semantics are equivalent to: (define-macro (name . args) body ...)
Errors and Error Handling Errors can be raised by primitives in libraries and Scheme-level code. &SISC; provides a sophisticated mechanism for handling these errors when they occur during program execution. Failure Continuations During the execution of any program, there is always a continuation that represents the rest of a computation. In addition, one can imagine all the activities that will occur as a result of an error. This sequence of actions is explicitly represented in &SISC; as a failure continuation. Two values must be applied to a failure continuation. The first is an error record, a datastructure which describes the error (and may contain information about the name of the function that generated the error, a descriptive message about the error, etc.). The second is the continuation of the expression that raised the error. All errors raised in &SISC; automatically and implicitly obtain and apply these values to the active failure continuation. Applying the error record and error continuation to the failure continuation will not return to the continuation of the application, unless that continuation was captured and later invoked in a non-local entrance. Creation A programmer may wish to augment current failure continuation, choosing a different set of actions to occur for a body of code if it raises an error. To facilitate this, &SISC; provides the with-failure-continuation procedure.
with-failure-continuation &procedure; value with-failure-continuation handler thunk with/fc &procedure; value with/fc handler thunk
with-failure-continuation takes as arguments a thunk (a zero-argument procedure) to be evaluated. The thunk will be evaluated in the continuation of the with/fc function, and with a failure continuation defined by the provided error handler. If during the evaluation of the thunk an error is raised, the first, two argument procedure is called with values describing the error and its context. If no error occurs, value of the thunk is applied to the continuation of the with/fc expression.
The error handler required as an argument to with-failure-continuation must accept two values. The first is a value containing information about the error that occurred. This is often an association list containing a number of attributes of the error. The second is a procedure encapsulating the continuation that was in place at the site of the error. This continuation is referred to as the error continuation When an error occurs, the error handler may choose one of three courses in dealing with the error. First, the handler may choose to return an alternate value to be applied to the continuation of the with/fc expression. Second, the handler may restart the computation from the error site by invoking the error continuation with a value that should be returned in place of the expression that caused the error. Finally, the handler may choose to propagate the error (or a new error) to the failure continuation of the with/fc expression. This can be done with the throw function described in .
Capture The currently active failure continuation may be obtained explicitly using the call-with-failure-continuation procedure. This continuation may be applied to appropriate values at any time in the future.
call-with-failure-continuation &procedure; value call-with-failure-continuation procedure call/fc &procedure; value call/fc procedure
Calls the given one-argument procedure with the currently active failure continuation.
Interaction with Ordinary Continuations Failure continuations exist as an attribute of the ordinary continuations of Scheme expressions. Because of this, the invocation of a continuation may cause a different failure continuation to become active in the region of the captured continuation. Specifically, the failure continuation in place at the call/cc expression will be reinstated when that continuation is later invoked. Similarly, invoking a continuation that escapes a region of code will cause any created failure continuations to be abandoned, unless the region is itself captured in a continuation and later invoked. See also .
Error Records An error record is the value usually propagated with an error in &SISC;. It is a datastructure containing such information as the location of the error, a descriptive message about the error, and possibly other error metadata. Creating Error Records Error records can be created in advance of actually raising an error with the make-error function. The function allows the programmer to create error records that contain a location and a message or value. No field of an error record is required.
make-error &procedure; error-record make-error location message arguments
Constructs an error record. If present, a symbol, and not #f, the first argument is the location of the error, which may be a symbol equivalent to a function identifier. If present, the message is a format-string processed with the optional arguments that follow as by format in SRFI-28. The remaining arguments must only be present if the format-string is present as the message.
&procedure; error-record make-error location error-value
Constructs an error record. If present, a symbol, and not #f, the first argument is the location of the error. The second argument is an arbitrary Scheme value that will be the error value. This value will be accessible with the error-message function.
None of the fields of an error-record are required. One may create an error record with no information, an error record with only a location, or an error record with only a message or value. Below are some examples (for an explanation of the throw procedure see ). (throw (make-error)) ; => Error. (throw (make-error 'foo)) ; => Error in foo. (throw (make-error "something ~a happened" 'bad)) ; => Error: something bad happened (throw (make-error 3)) ; => Error: 3 (throw (make-error #f 'foo)) ; => Error: foo (throw (make-error 'foo "something ~a happened" 'bad)) ; => Error in foo: something bad happened In addition, an error record may be created that adds additional information to an error record that was already created. This is useful when an error was caught in an error handler, and one wishes to raise an error from the handler that contains additional information about the local location or error message as well as the error that was caught.
make-nested-error &procedure; error-record make-nested-error local-error parent-error parent-error-continuation &procedure; error-record make-nested-error local-error exception
The first version creates an error record which has parent-error (and its associated parent-error-continuation) as the root cause of an error-record passed as local-error. The second version creates an error record which has exception (see ) as the root cause of an error passed as local-error.
An example of the creating, throwing, and display of a nested error follows. (with-failure-continuation (lambda (m e) (throw (make-nested-error (make-error 'foo "could not call bar.") m e))) (lambda () (error 'bar "something went wrong."))) ;=> Error in foo: could not call bar. ; Caused by Error in bar: something went wrong.
Accessors An error record contains several useful pieces of information. The following functions allow the programmer to access that information.
error-location &procedure; symbol error-location error-record
Obtains the location of the error, a symbol which may be a function identifier. If there is no location specified, #f is returned.
error-message &procedure; value error-message error-record
Obtains the message of the error, which may be a string which is a descriptive message of the error, or an arbitrary value (as created by the second form of make-error). If there is no message specified, #f is returned.
error-parent-error &procedure; error-record error-parent-error error-record
Obtains the parent error of the error. This is the value of the second argument to the make-nested-error function. If there is no parent specified, #f is returned.
error-parent-continuation &procedure; error-continuation error-parent-continuation error-record
Obtains the parent error continuation of the error. This is the value of the third argument to the make-nested-error function. If there is no parent specified, #f is returned.
Raising Errors The fundamental mechanism for raising an error in application code is provided by the throw procedure.
throw &procedure; does not return throw error-record error-continuation &procedure; does not return throw exception
The first verison applies the given error record to the current failure continuation. If provided, the error continuation is designated by the optional parameter. If not, the continuation of the throw expression is used. The second form applies the current failure continuation to the error record and error continuation extracted from the supplied exception (see ).
If invoked from an error-handler with the values of the handler's formal parameters, throw has the effect of propagating the error in a manner that is equivalent to the absence of the modified failure-continuation. throw could be defined in terms of call-with-failure-continuation as: (define (throw error . args) (call-with-failure-continuation (lambda (fk) (if (null? args) (call-with-current-continuation (lambda (k) (fk error k))) (fk error (car args)))))) For convenience and compatibility with SRFI-23, the function error is provided. Its syntax is identical to make-error, but it immediately applies the resulting error record to the current failure continuation with the current continuation as the error continuation.
error &procedure; does not return error location message arguments
Raises an error record whose location, if provided, is location, a symbol; and whose error message, if present, is message. If provided, the error message is a format-string that is processed, with the optional arguments, as with the format function in SRFI 28.
&procedure; does not return error location error-value
Raises an error record whose location, if present, is the symbol location, and and whose error-value is any arbitrary Scheme value.
error can be implemented in terms of throw and make-error: (define (error . args) (throw (apply make-error args)))
Exceptions Exceptions in &SISC; are a simple wrapper around an error record and an associated error continuation. Exceptions are created with
make-exception &procedure; exception make-exception error-record error-continuation
Constructs an exception from an error-record and an error-continuation, e.g. as obtained from the arguments of a handler procedure passed to with-fc.
Accessors and a type-test are provided by the following procedures:
exception-error &procedure; error-record exception-error exception
Returns the exception's error record.
exception-continuation &procedure; error-continuation exception-continuation exception
Returns the exception's error continuation.
exception? &procedure; #t/#f exception? value
Returns #t if value is an exception object, #f otherwise.
Examples At this point, a few examples may be helpful: (+ 1 (/ 1 0) 3) ; => A divide by zero error is raised Return a new value (with-failure-continuation (lambda (error-record error-k) 'error) (lambda () (+ 1 (/ 1 0) 3))) ; => The symbol 'error Restart with a different value (with-failure-continuation (lambda (error-record error-k) (error-k 2)) (lambda () (+ 1 (/ 1 0) 3))) ; => 6 Propagate the error (with-failure-continuation (lambda (error-record error-k) (throw error-record error-k)) (lambda () (+ 1 (/ 1 0) 3))) ; => A divide by zero error is raised Propagate a different error with the same error continuation (with-failure-continuation (lambda (error-record error-k) (throw (make-error '/ "could not perform the division.") error-k)) (lambda () (+ 1 (/ 1 0) 3))) ; => An error is raised: Error in /: could not perform the division. Raise a new error (with-failure-continuation (lambda (error-record error-k) (error 'example-function "could not evaluate the expression.")) (lambda () (+ 1 (/ 1 0) 3))) ; => An error is raised: Error in example-function: could not evaluate the expression. Note that the difference between and is that in the former, the computation can still be restarted from the second argument of the addition if an outside handler catches the newly raised exception and applies the continuation. This is not true in the last example, as its a new error whose continuation is the same as the with-failure-continuation expression. <function>dynamic-wind</function> &R5RS; does not specify the behavior of dynamic-wind in the case where an error is raised while evaluating the during thunk. &SISC; chooses to view an error raised in that section as an instance of the dynamic extent being exited. In other words, if an error is raised in the dynamic extent of a dynamic-wind expression, &SISC; will ensure that the after thunk is evaluated before the error is propagated to the failure-continuation of the dynamic-wind expression. Errors and <function>dynamic-wind</function> (define x 0) (dynamic-wind (lambda () (set! x (+ x 1))) (lambda () (/ 1 0)) (lambda () (set! x (+ x 1)))) ; => A divide by zero error is raised, and the value of x is 2 If an error is raised in either the before or after thunks, no additional measures are taken. The error is propagated to the failure-continuation of the dynamic-wind as if the dynamic-wind call was an ordinary function application. Explicitly, if an error is raised from before, neither during nor after will be executed. If an error is raised in after, the results of evaluating before and during remain valid. Also noteworthy is what happens if a continuation is invoked that exits from either the before or after thunks. Such a case is treated just as if a continuation was invoked during the evaluation of an operand to an application. This is to say that no additional steps will be taken by &SISC;. If before is escaped by a continuation invocation, neither during nor after will be executed. If after is escaped, the results of before and during remain valid. In summary, extraordinary evaluation is only possible during the evaluation of the during thunk. The before and after thunks are evaluated with the dynamic environment and dynamic-wind stack of the call to dynamic-wind itself.
Symbolic Environments and Property Maps Symbolic environments and property maps provide additional named global environments useful for storing program specific data without exposing it to the general purpose top-level environment. A property map is dictionary structure tied to the interaction environment which maps symbolic names to Scheme values. First-class symbolic environments provide a similar mapping, but can be used as first class values (including as an argument to eval). Symbolic environments are used to implement &SISC;'s global (top level)and report environments. Access Functions Access to symbolic environments is performed through the getprop and putprop functions. All symbolic environment operations are thread safe.
getprop &procedure; value getprop binding-name plist-name default-value &procedure; value getprop binding-name environment default-value
Attempts a lookup of binding-name in an environment. In the first form, the the binding is resolved in the interaction-environment's property list named plist-name, a symbol. If the environment is not found or the binding doesn't exist, default-value is returned if provided, otherwise #f is returned. In the second form, the binding is resolved in a first-class symbolic environment.
putprop &procedure; undefined putprop binding-name plist-name value &procedure; undefined putprop binding-name environment value
Sets the value of a binding named with the symbol binding-name in a property list or first class symbolic environment. In the first form, the binding is resolved using a symbolic name (plist-name) in the interaction environment's property lists. If the map does not yet exist, it is created as an empty map. In the second form, the binding is resolved in the provided first class symbolic environment. If the binding does not yet exist in the given environment, it is created. If a binding previously existed, its previous value is discarded.
Obtaining and Naming Symbolic environments are a first class datatype in &SISC;. The top-level environment itself is merely a special cased symbolic environment. To obtain the top-level environment as a first class value, one can use the interaction-environment function that is an optional procedure in &R5RS;. Another useful environment is the &R5RS; report environment available by calling: (scheme-report-environment 5) Each call to scheme-report-environment returns a new environment that contains only the bindings available in the Scheme report. Finally, the initial environment available to the programmer when &SISC; starts can be retrieved using the sisc-initial-environment function:
sisc-initial-environment &procedure; environment sisc-initial-environment
Returns the initial &SISC; interaction environment.
Like scheme-report-environment, each call to sisc-initial-environment returns a distinct environment which contains only the bindings initially available when &SISC; starts. An interesting use of this would be to define one or more distinct initial-environments, bound to toplevel variables. One could then define Scheme code and data in each environment that can use the full &SISC; language but cannot see any bindings in other environments. Finally, &R5RS; states that it is an error to modify the contents of a top-level variable that has not yet been created. &SISC; adheres to the standard, and raises an error when any unbound variable in a symbolic environment (including the top-level) is modified using set!. This differs from some Scheme systems that will silently create the binding and set it to the new value.
Chained Symbolic Environments &SISC; contains a mechanism for creating a symbolic environment which is chained to another environment, such that new and modified bindings are created in the new, child environment, but bindings may also be resolved from the parent if not present in the child. &SISC; uses this functionality to protect the contents of the &R5RS; and &SISC; initial environments from modification. One can use it in a similar way, protecting the bindings in the parent for sandboxing or other purposes.
make-child-environment &procedure; environment make-child-environment parent-environment
Creates a new environment, initially empty of its own bindings, but which chains to the provided parent-environment when resolving a binding.
parent-environment &procedure; environment parent-environment environment
Obtains the parent environment of a symbolic environment. If the given environment has no parent (e.g. is not chained), #f is returned.
Miscellaneous Functions The remaining functions in this chapter are not easily classified, but nevertheless are useful and worth describing.
circular? &procedure; #t/#f circular? datum
Returns #t if the given datum is circular. A datum is circular if it is a compound datum (lists or vectors for example), and one of its elements is a reference to itself, or a reference to a sub-element which creates a cycle.
compose &procedure; procedure compose function
compose takes zero or more functions of one argument and returns a new function of one argument that will apply to that argument to the selected functions in reverse order. If no functions are provided, the identity function is returned. For example, the function caddr could be simply defined as: (define caddr (compose car cdr cdr))
iota &procedure; pair iota n
The iota function produces a list whose elements are the integers 0 to n-1 inclusive.
time &syntax; list time iterations expression
Evaluates the given expression iterations times, or if iterations is not provided, only once. When complete, a list is returned of the following form: (result (n ms)) where result is the Scheme value that resulted from the last evaluation of the expression, and n is the number of milliseconds taken to evaluate the expression. If more than one iteration occurred, then the average number of milliseconds elapsed during each iteration is returned.
sisc-1.16.6.orig/doc/sss/modules.xml0000644000175000017500000003062411445752462015717 0ustar amoeamoe Modules and Libraries Modules Modules provide an additional level of scoping control, allowing symbolic and syntactic bindings to be bundled in a named or anonymous package. The package can then be imported into any scope, making the bindings contained in the module visible in only that scope. &SISC;'s modules are provided by the portable syntax-case macro expander by R. Kent Dybvig and Oscar Waddell. A comprehensive explanation of the provided module system is best found in the Chez Scheme Users Guide , specifically Section 9.3, Modules . What follows is an informal introduction to that module system. Overview The basic unit of modularization in &SISC; is a module. A typical module definition has this appearance: (module foo (bar baz) (import boo1) (import boo2) (include "file.scm") (define (bar x) ...) (define-syntax baz ...) (define (something-else ...) ...) (do-something) (do-something-else)) A module definition consists of a name (foo), a list of exports (bar and baz) and a body. Expressions which can appear in the body of a module are the same as those which can appear in a lambda body. The import form imports bindings from a named module (in this case boo1 and boo2) into the current lexical scope. The include form performs a textual inclusion of the source code found in the named file (file.scm). In other words, it works as if the contents of the file had appeared literally in place of the include statement. All identifiers appearing in the export list must be defined or define-syntaxed in the body of the module, or imported from another module. Style It is recommended to clearly separate modularization from actual code. The best way to accomplish this is to List all imports in the module body rather than in included files Include all files directly from the module body, avoiding nested includes Place all definitions and expressions in included files, avoiding them in the module body There are several reasons for this. First, it makes refactoring easier, as one can move relevant code from module to module merely by rewriting the module definitions, leaving the implementation code unchanged. Second, it makes debugging easier, as one can load the implementation code directly into the Scheme system to have access to all bindings, or load the module definition to view the finished, encapsulated exports. Finally, it stylistically separates interface (the modules) from implementation (the included Scheme source). Modularizing Existing Code Since module bodies are treated like the bodies of lambdas, the &R5RS; rules of how internal definitions are treated apply to all the definitions in the module body (both ordinary and syntax), including all code included from files. This is often a source of errors when moving code from the top-level into a module because: All definitions must appear before all expressions, The list of definitions is translated into letrec/letrec-syntax, which means it must be possible to evaluate each right-hand side without assigning or referring to the value of any of the variables being defined. This often necessitates re-arranging the code and the introduction of set! expressions. Here is an example of a sequence of top-level definitions/expressions and how they need to be rewritten so that they may appear in a module body: (define (foo) 1) (define bar (foo)) (do-some-stuff) (define (baz) (bar)) ==> (define (foo) 1) (define bar) (define (baz) (bar)) (set! bar (foo)) (do-some-stuff) The general strategy is to go through the list of expressions/definitions from top to bottom and build two lists - one of definitions and one of expressions - as follows: If a non-definition is encountered, append it to the expression list If a "naked" definition (i.e. a definition whose right-hand side is not a function) that refers to a binding defined within the module is encountered, append an empty definition to the definition list and append a set! with the right-hand side expression to the expression list Otherwise, i.e. for an ordinary definition, append it to the definition list The concatenation of the resulting definition list with the expression list makes a suitable module body. Evaluation Modules are lexically scoped. It is possible to define modules inside lambdas and inside other modules and to export modules from modules. Example: (define (f c) (module foo (bar) (module bar (baz) (define (baz x y) (- x y)) (display "defining baz\n"))) (if (> c 0) (let ((a 1)) (import foo) (let loop ((b c)) (import bar) (if (> b 0) (loop (baz b a)) (f (- c 1))))))) The expressions in a module body get executed at the time and in the context of module definition. So, in the above example, the body of bar containing the display statement is executed once for every call to f rather than once for every iteration of the inner loop containing the import of the bar module. There are quite a few more things you can do with modules. For instance one can define anonymous modules, which are a short cut for defining a named module and then importing it, import selected bindings from a module and renaming them rather then importing all bindings as is etc etc. For more details again refer to the Chez Scheme user manual. Libraries Libraries provide a means of encapsulating code that can be shared by many, independently developed applications. Libraries are simply bundles of Scheme code, usually precompiled, which are packaged so that they may be resolved relative to a library path. Libraries are typically compiled using the meachanism from . Loading the resulting library makes the library available to the loading code. To create a compiled library from a module, compile a source file which contains any necessary require-library calls, followed by the module definition. When loaded, this will cause the necessary libraries to be loaded, and then define the module into the environment. For example, the source file may resemble: (require-library 'sisc/libs/srfi/srfi-1) (require-library 'com/foo/lib2) (module lib3 (a-function) (import srfi-1) (import com/foo/lib2) (define (a-function) (do-something (another-function))) (define (another-function) (something-else)) Libraries should not depend on any top-level definitions outside the standard &SISC; top-level, except the definition of other library modules. Otherwise it is not possible to use the libraries portably. Libraries can be packaged with supporting code (e.g. ordinary Java code and native modules) and other libraries into jar files. A typical structure for such a jar file would be com/foo/lib1.scc com/foo/lib1/Class1.class com/foo/lib1/Class2.class com/foo/lib2.scc com/foo/lib2/Class1.class com/foo/lib2/Class2.class com/foo/lib3.scc com/foo/lib3/Class1.class com/foo/lib3/Class2.class It is usually a good idea to name a module after the path names in the jar, for example com/foo/lib{1,2,3} in the above example. <function>require-extension</function> require-extension &SISC; supports SRFI-55 for loading libraries and extensions as well. SRFI-55 provides require-extension, which in &SISC; simultaneously loads a library, then imports its module definition into the current interaction environment. This may be more convenient than the combination of require-library and import, when one is loading dependent top-level libraries for a program. It is less flexible, though, since you cannot import into a lexical scope. SRFI-55 is supported in the initial &SISC; environment, no require-library or import is needed to use require-extension. At the time of this writing, &SISC; supports two extension identifier schemes, the srfi scheme as required by SRFI-55 itself, and a &SISC; specific lib scheme for loading a &SISC; library. Some examples: Loading and importing with <function>require-extension</function> ; Load and import SRFI 1 (require-extension (srfi 1)) ; Load and import SISC library com/foo/lib1 (require-extension (lib com/foo/lib1)) ; Load and import SRFIs 13 and 14, ; and SISC libraries com/foo/lib2 and com/foo/lib3 (require-extension (srfi 13 14) (lib com/foo/lib2 com/foo/lib3)) &SISC; modules loaded using the lib extension scheme must use the full path and file as the module name. For example, in the above example, com/foo/lib1's module name must be com/foo/lib1. sisc-1.16.6.orig/doc/sss/oo.xml0000644000175000017500000026517211445752462014674 0ustar amoeamoe Types and Objects Type System &requires; (import type-system) &SISC;'s extensible type system provides programmatic access to the type information of values and provides a core set of type testing and comparison procedures. The type system is extensible in two ways. Firstly any new native types are recognised automatically. Secondly, hooks are provided for Scheme-level extensions of the type-system. By convention, type names start with < and end with >, with normal Scheme identifier naming conventions applying for everything in-between, i.e. all lower-case with words separated by dashes. For example, <foo-bar-baz>. This convention helps to visually distinguish type names from names of procedures and top-level data bindings. Core Procedures and Predicates
type-of &procedure; type type-of value
Returns the type of value. There is no standard representation for types, leaving type extensions free to choose a representation that suits them most. The procedure is equipped with an extension hook, type-of-hook. See for more details on hooks. The default implementation of the hook type-of returns a type based on the Java type of the internal representation of value.
(type-of 1) &arrow; #<scheme sisc.data.Quantity> (type-of (lambda (x) x)) &arrow; #<scheme sisc.data.Closure>
types<= &procedure; &t;/&f; type<= type1 type2
Returns &t; if type1 is a sub-type of type2. The predicate is equipped with an extension hook, type<=-hook. See for more details on hooks. The default implementation of the hook determines sub-typing based on the inheritance relationship of the Java types representing native types.
(type<= (type-of 'a) (type-of 'b)) &arrow; &t; (type<= (type-of 'b) (type-of 'a)) &arrow; &t; (type<= (type-of 1) (type-of 'a)) &arrow; &f; (type<= (type-of 1) <number>) &arrow; &t; (type<= (type-of 'a) <symbol>) &arrow; &t; (type<= <number;> <symbol>) &arrow; &f; (type<= <symbol;> <number>) &arrow; &f; (type<= <number> <value>) &arrow; &t; (type<= <symbol> <value>) &arrow; &t;
compare-types &procedure; 'equal,'more-specific,'less-specific compare-types type1 type2 type3
Determines the relationship of type1 and type2 with respect to type3. type3 must be a sub-type of type1 and type2. type1 and type2 are first compared using type<=. If that comparison indicates that the types are disjoint (i.e. type1 is not sub-type of type2, type2 is not a sub-type of type1 and the types are not equal) then additional information from type3 is taken into account for the comparison. The predicate is equipped with an extension hook, compare-types-hook that is invoked in the case the comparison of type1 with type2 using type<= finds the two types to be disjoint. See for more details on hooks. The default implementation of the hook returns an error
(compare-types <number> <value> <number>) &arrow; 'more-specific (compare-types <value> <number> <number>) &arrow; 'less-specific (compare-types <number> <number> <number>) &arrow; 'equal
Derived Procedures and Predicates The type system's derived procedures and predicates are implemented in terms of the core procedures and predicates.
instance-of? &procedure; &t;/&f; instance-of? value type
Determines whether value is an instance of type. The predicate obtains value's type using type-of and then compares it to type using type<=.
(instance-of? 1 <number>) &arrow; &t; (instance-of? 'a <symbol>) &arrow; &t; (instance-of? 1 <symbol>) &arrow; &f; (instance-of? 1 <value>) &arrow; &t;
types= &procedure; &t;/&f; type= type1 type2
Determines whether two types are equal by comparing them using type<=.
(type= (type-of 'a) (type-of 'b)) &arrow; &t; (type= (type-of 1) (type-of 'a)) &arrow; &f; (type= (type-of 1) <number>) &arrow; &t; (type= (type-of 'a) <symbol>) &arrow; &t; (type= <number;> <symbol>) &arrow; &f;
types<= &procedure; &t;/&f; types<= type-list1 type-list2
Determines whether all of the types in type-list1 are sub-types of the the corresponding (by position) types in type-list2. A pair-wise comparison of the elements in the two lists using type<= is performed until a test returns &f;, in which case &f; is returned, or one (or both) of the lists has been exhausted, in which case &t; is returned.
(types<= (list <number> <symbol>) (list <value> <value>)) &arrow; &t; (types<= (list <number> <symbol>) (list <number> <number>)) &arrow; &f;
instances-of? &procedure; &t;/&f; instances-of? value-list type-list
Determines whether all of the values in value-list are instances of the the corresponding (by position) types in type-list. A pair-wise comparison of the elements in the two lists using instance-of? is performed until a test returns &f;, in which case &f; is returned, or one (or both) of the lists has been exhausted, in which case &t; is returned.
(instances-of? (list 1 'a) (list <number> <symbol>)) &arrow; &t; (instances-of? (list 1 'a) (list <number> <number>)) &arrow; &f;
types= &procedure; &t;/&f; types= type-list1 type-list2
Determines whether all of the types in type-list1 are equal to the the corresponding (by position) types in type-list2. A pair-wise comparison of the elements in the two lists using type= is performed until a difference is found, in which ase &f; is returned, or one (or both) of the lists has been exhausted, in which case &t; is returned.
(types= (list <number> <symbol>) (list <number> <symbol>)) &arrow; &t; (types= (list <number> <symbol>) (list <number> <number>)) &arrow; &f;
Hooks type-of-hook type-<=-hook compare-typess-hook Hooks are the main mechanism by which Scheme code can extend the default type system. The core type system procedures type-of, type<= and compare-types all provide such hooks, called type-of-hook, type-<=-hook, and compare-types-hook respectively. Extension takes place by installing labelled handler procedures on the hook, which is done by invoking the hook procedure. Installing a handler procedure with a label of an already installed procedure replaces the latter with the former. The handler procedures are called with a next procedure as the first argument and all the arguments of the call to the hook-providing procedures as the remaining arguments. Typically a handler procedure first determines whether it is applicable, i.e. is capable of performing the requested comparison etc. If not it calls the next handler procedure, which invokes the next hook or, if no further hooks exist, the default implementation of the hooked procedure. Hook Installation This example shows how &SISC;'s record type module adds record types to the type system by installing handler procedure on type-of-hook and type<=-hook. (type-of-hook 'record (lambda (next o) (if (record? o) (record-type o) (next o)))) (type<=-hook 'record (lambda (next x y) (cond [(record-type? x) (if (record-type? y) (eq? x y) (type<= <record> y))] [(record-type? y) #f] [else (next x y)]))) Standard Types <value> <eof> <symbol> <list> <procedure> <number> <boolean> <char> <string> <vector> <input-port> <output-port> The type system pre-defines bindings for the native types corresponding to all the data types defined in R5RS: <eof>, <symbol>, <list>, <procedure>, <number>, <boolean>, <char>, <string>, <vector>, <input-port>, <output-port>. One notable exception is that pairs and null are combined into a <list> type. The type system also defines a <value> type that is the base type of all &SISC; values, i.e. all &SISC; values are instances of <value> and all types are sub-types of <value>. The representations of other native types can be obtained using
make-type &procedure; type make-type symbol
Constructs a type representing a built-in type. The symbol must denote a Java class that is a sub-class of sisc.data.Value, the base of the &SISC; value type hierarchy.
(define <record> (make-type '|sisc.modules.record.Record|)) (type<= <record> <value>) &arrow; &t;
Generic Procedures &requires; (import generic-procedures) Generic procedures are procedures that select and execute methods based on the types of the arguments. Methods have a type signature, which generic procedures use for method selection, and contain a procedure which is invoked by generic procedures when the method has been selected for execution. Generic procedures have several advantages over ordinary procedures: It is not necessary to come up with unique names for procedures that perform the same operation on different types of objects. This avoids cluttering the name space. All these procedures can be defined separately but yet be part of the same, single generic procedure. The functionality of a generic procedure can be extended incrementally through code located in different places. This avoids "spaghetti code" where adding a new type of objects requires changes to existing pieces of code in several locations. Code using generic procedures has a high degree of polymorphism without having to resort to ugly and hard-to-maintain test-type-and-dispatch branching. Generic procedures make extensive use of &SISC;s type system. See . The use of generic procedures proceeds through three stages: definition of the generic procedure adding of methods to the generic procedure adding of methods to the generic procedure The adding of methods can be interleaved with invocation, i.e. methods can be added to generic procedures while they are in use. Defining Generic Procedures There are one procedure and two special forms for defining generic procedures. Typical usage will employ one of the special forms.
make-generic-procedure &procedure; generic-procedure make-generic-procedure generic-procedure
Creates a generic procedure. If generic-procedure parameters are specified, then their method lists are merged, in effect combining the generic procedures into one. For more details on generic procedure combination see .
(define pretty-print1 (make-generic-procedure)) (define pretty-print2 (make-generic-procedure)) &arrow; <procedure> (define pretty-print (make-generic-procedure pretty-print1 pretty-print2))
define-generic &syntax; define-generic name generic-procedure
Creates a binding for name to a new generic procedure. This form is equivalent to (define name (make-generic-procedure generic-procedure ...)).
(define-generic pretty-print1) (define-generic pretty-print2) (define-generic pretty-print pretty-print1 pretty-print2)
define-generics &syntax; define-generics form
where form is of the form name or (name generic-procedure ...) Creates bindings for several new generic procedures. The form expands into several define-generic forms.
(define-generic pretty-print1) (define-generic pretty-print2) (define-generics foo (pretty-print pretty-print1 pretty-print2) bar)
Defining Methods Methods can be define and subsequently added to generic procedures, or the two operations can be combined, which is the typical usage. There is one procedure and one special form to create methods:
make-method &procedure; method make-method procedure type-list rest?
Creates a new method containing procedure whose type signature is type-list. If rest? is &t; then the procedure can take rest arguments. Generic procedures always invoke method procedures with a special next: argument as the first parameter (see ), followed by all the arguments of the generic procedure invocation. Hence procedure needs to accept (length type-list)+1 arguments.
(make-method (lambda (next x y) (next x y)) (list <number> <number>) #f) &arrow; <method> (make-method (lambda (next x . rest) (apply + x rest)) (list <number>) #t) &arrow; <method>
method &syntax; method method signature . body
where signature is of the form ([(next: next)] (type param) ... [ . rest]) and body can contain anything that is valid inside the body of a lambda. Creates a method. This form is similar to a lambda form, except that all parameters must be typed. The form expands into an invocation of the make-method procedure. The first parameter name in the method's signature can be the special next: parameter. See .
(method ((next: next)(<number> x)(<number> y)) (next x y)) &arrow; <method> (method ((<number> x) . rest) (apply + x rest)) &arrow; <method>
There are two procedures to add methods to a generic procedure:
add-method &procedure; add-method generic-procedure method
Adds method to generic-procedure. Any existing method with the same signature as method is removed. Method addition is thread-safe.
(define-generic m) (add-method m (method ((next: next)(<number> x)(<number> y)) (next x y))) (add-method m (method ((<number> x) . rest) (apply + x rest)))
add-methods &procedure; add-methods generic-procedure method-list
Adds all methods in method-list to generic-procedure. Any existing method with the same signature as one of the methods in method-list is are removed. When several methods in method-list have the same signature, only the last of these methods is added. Method addition is thread-safe. Calling add-methods instead of add-method when adding several methods to a generic procedure is more efficient.
(define-generic m) (add-methods m (list (method ((next: next)(<number> x)(<number> y)) (next x y)) (method ((<number> x) . rest) (apply + x rest))))
The creation of methods and adding them to generic procedures can be combined using one of two special forms:
define-method &syntax; define-method (generic-procedure . signature) . body
Creates a method and adds it to generic-procedure. This form is equivalent to (add-method generic-procedure (method signature . body)
(define-generic m) (define-method (m (next: next)(<number> x)(<number> y)) (next x y))) (define-method (m (<number> x) . rest) (apply + x rest))
define-methods &syntax; define-methods generic-procedure (signature . body)
Creates several methods and adds them to generic-procedure. This form is equivalent to (add-methods generic-procedure (list (method signature . body) ...)
(define-generic m) (define-methods m [((next: next)(<number> x)(<number> y)) (next x y)] [((<number> x) . rest) (apply + x rest)])
The list of methods contained in a generic procedure can be obtained as follows:
generic-procedure-methods &procedure; method-list generic-procedure-methods generic-procedure
Returns the list of methods currently associated with generic-procedure.
(define-generic m) (define-methods m [((next: next)(<number> x)(<number> y)) (next x y)] [((<number> x) . rest) (apply + x rest)]) (generic-procedure-methods m) &arrow; (<method> <method>)
Invoking Generic Procedures Generic procedures are invoked like ordinary procedures. Upon invocation, generic procedures compute a list of applicable methods, ordered by their specificity, based on the types of the parameters supplied in the invocation. If the resulting list is empty an error is raised. Otherwise the first (i.e. most specific) method is invoked. The remaining methods come into play when a method invokes the "next best matching method". See for details on the method selection algorithms. The logic by which generic procedures select methods for invocation is made accessible to the programmer through the following procedures:
applicable-methods &procedure; method-list applicable-methods generic-procedure type-list
Returns all methods of generic-procedure that are applicable, as determined by method-applicable? to parameters of the types specified in type-list. The methods are returned ordered by their specificity, determined by pair-wise comparison using compare-methods.
(define-generic m) (define-methods m [((next: next)(<number> x)(<number> y)) (next x y)] [((<number> x) . rest) (apply + x rest)]) (applicable-methods m (list <number> <number>)) &arrow; (<method> <method>)
method-applicable? &procedure; &t;/&f; method-applicable? method type-list
Determines whether method is applicable to arguments of the types specified in type-list. The rules for determining method applicability are defined in .
(method-applicable? (method ((next: next)(<number> x)(<number> y)) (next x y)) (list <number>)) &arrow; &f; (method-applicable? (method ((<number> x) . rest) (apply + x rest)) (list <number>)) &arrow; &t;
compare-methods &procedure; 'equal,'more-specific,'less-specific compare-methods method method type-list
Determines the relationship of two methods by comparing their type signatures against each other and using the supplied type-list for disambiguation. Both methods must be applicable to type-list, as determined by method-applicable?. The comparison algorithm is described in .
(compare-methods (method ((next: next)(<number> x)(<number> y)) (next x y)) (method ((<number> x) . rest) (apply + x rest)) (list <number> <number>)) &arrow; 'more-specific
Calling a generic will dispatch on the argument types as described above. This dispatch can change if new methods are added to a generic procedure. On occasion the programmer may wish to fix the dispatch of a particular generic function, either to guarantee a specific function is called for a given part of a Scheme program, or to improve performance by avoiding the type dispatch at each call. &SISC; provides a syntactic form which allows the programmer to bind/rebind a generic procedure to a new lexical variable which is the monomorphized variant of the function call.
let-monomorphic &syntax; let-monomorphic bindings expressions
where bindings are of the form ((generic type...) ...) or (((binding generic) type...) ...) In the former binding form, the generic procedure specified by generic is rebound lexically with the same name, and monomorphized to the method which is applicable for the given types. In the latter form, the generic is rebound lexically to the new name specified by binding. Both forms may be used in a given call to let-monomorphic. The bindings are made as if by let, i.e. no assumptions can be made as to the order in which they are bound. The expressions are evaluated as in let as well, in order using an implicit begin.
(let-monomorphic ([foo-generic <number> <string>] [(bar bar-generic) <char>]) (foo-generic 3 "four") (bar #\x))
Procedures on Methods <method> Methods are instances of the abstract data type <method>, which has range of procedures:
method? &procedure; &t;/&f; method? value
Returns &t; if value is a method, &f; otherwise.
(method? (method ((<number> x) . rest) (apply + x rest))) &arrow; &t; (method? (lambda (x) x)) &arrow; &f;
method-procedure &procedure; procedure method-procedure method
Returns method's body as a procedure. Note that a method's procedure always takes a "next method" procedure as the first argument. See .
((method-procedure (method ((<number> x) . rest) (apply + x rest))) #f 1 2 3) &arrow; 6
method-types &procedure; type-list method-types method
Returns method's type signature, i.e. the types of the declared mandatory parameters.
(method-types (method ((next: next)(<number> x)(<number> y) . rest) (next x y))) &arrow; (<number> <number>)
method-rest? &procedure; &t;/&f; method-rest? method
Returns &t; if method has a rest parameter, &f; otherwise.
(method-rest? (method ((<number> x) . rest) (apply + x rest))) &arrow; &t; (method-rest? (method ((next: next)(<number> x)(<number> y) . rest) (next x y))) &arrow; &f;
method-arity &procedure; number method-arity method
Returns the number of mandatory arguments of method. Note that the special next: parameter is not counted.
(method-arity (method ((<number> x) . rest) (apply + x rest))) &arrow; 1 (method-arity (method ((next: next)(<number> x)(<number> y) . rest) (next x y))) &arrow; 2
method= &procedure; &t;/&f; method= method method
Returns &t; if the two methods have identical signatures, i.e. have equal parameter types (as determined by types=) and rest parameter flag. &f; is returned otherwise.
(method= (method ((next: next)(<number> x)(<number> y) . rest) (next x y)) (method ((<number> a)(<number> b) . rest) (+ x y))) &arrow; &t; (method= (method ((<number> x)(<number> y) . rest) (+ x y)) (method ((<number> a)(<number> b)) (+ x y))) &arrow; &f; (method= (method ((<number> x)(<value> y)) (+ x y)) (method ((<number> a)(<number> b)) (+ x y))) &arrow; &f;
Miscellaneous Generic Procedure Combination Generic procedure combination merges the method lists of multiple generic procedures. The typical scenario for using this features is when several modules have defined generic procedure (and procedures using these generic procedures) that perform identical operations but on different data types. Generic procedure combination extends to coverage of the individual generic procedures and the dependent procedures to the combined set of data types. Furthermore, the coverage of the dependent procedures is implicitly extended to the combined set of data types. The following example illustrates how generic procedure combination can be used to combine the functionality of two p-append procedures defined independently by two modules. It also shows how generic procedure combination implicitly extends the coverage of the p-reverse-append and p-repeat procedures defined by the modules. (import* misc compose) (module foo (p-append p-reverse-append) (define (p-reverse-append . args) (apply p-append (reverse args))) (define-generic p-append) (define-methods p-append [((<list> x) . rest) (apply append x rest)] [((<vector> x) . rest) (list->vector (apply append (vector->list x) (map vector->list rest)))])) (module bar (p-append p-repeat) (define (p-repeat n x) (let loop ([res '()] [n n]) (if (= n 0) (apply p-append res) (loop (cons x res) (- n 1))))) (define-generic p-append) (define-methods p-append [((<string> x) . rest) (apply string-append x rest)] [((<symbol> x) . rest) (string->symbol (apply string-append (symbol->string x) (map symbol->string rest)))])) (import* foo (p-append1 p-append) p-reverse-append) (import* bar (p-append2 p-append) p-repeat) (define-generic p-append p-append1 p-append2) (define-method (p-append (<procedure> x) . rest) (apply compose x rest)) (p-append '(a b)) &arrow; '(a b) (p-append '(a b) '(c d) '(e f)) &arrow; '(a b c d e f) (p-append '#(a b)) &arrow; '#(a b) (p-append '#(a b) '#(c d) '#(e f)) &arrow; '#(a b c d e f) (p-append "ab") &arrow; "ab" (p-append "ab" "cd" "ef") &arrow; "abcdef" (p-append 'ab) &arrow; 'ab (p-append 'ab 'cd 'ef) &arrow; 'abcdef ((p-append car cdr cdr cdr) '(1 2 3 4)) &arrow; 4 (p-reverse-append "ab" "cd" "ef") &arrow; "efcdab" (p-repeat 3 '(a b)) &arrow; '(a b a b a b) ((p-reverse-append cdr cdr cdr car) '(1 2 3 4)) &arrow; 4 ((p-repeat 3 cdr) '(1 2 3 4)) &arrow; (4) Scoping Rules Generic procedures are lexically scoped, but their methods are not. Hence defining methods in a local scope is generally a bad idea. One exception are module definitions. It is perfectly safe for modules to define private (i.e. not exported) generic procedures and add methods to them without interfering with other modules. However, care must be taken when generic procedures are imported or exported - methods are added to generic procedures when the module gets defined rather then when it gets imported. The following example illustrates the scoping rules. (define-generic m) (define-method (m (<value> v)) v) (m 1) &arrow; 1 (let ([x 1]) (define-method (m (<number> v)) (+ x v)) (m 1)) &arrow; 2 (m 1) &arrow; 2 (module foo (m) (define-generic m) (define-method (m (<value> v)) v)) (import foo) (m 1) &arrow; 1 (module bar () (import foo) (define-method (m (<number> v)) (+ 1 v))) (m 1) &arrow; 2 Method Selection When generic procedures are invoked they select the most specific applicable method and call it, with the remaining applicable methods being made available to the invoked method via the next:. Method applicability is determined on the basis of the types of the parameters passed in the invocation of the generic procedure. A method is applicable to a list of parameter types if and only if the following conditions are met: If the method accepts rest arguments then the length of the list of parameter types must be equal or greater than the method arity (as returned by method-arity). If the method does not accepts rest arguments then the length of the list of parameter types must be equal to the method arity (as returned by method-arity). All the types in the method's type signature (as returned by method-types) must be super-types of the corresponding parameter types. This comparison is performed using the types<= procedure. This algorithm is encapsulated by the method-applicable? procedure. Method specificity is an ordering relation on applicable methods with respect to a specific list of parameter types. Informally, the relative specificity of two methods is determined by performing a left-to-right comparison of the type signatures of the two methods and the parameter types using compare-types, returning the result of the type comparison at the point of the first discernable difference. More formally, the relative specificity of two applicable methods is computed by a triple-wise comparison on successive elements of the method signatures (as returned by method-types) and actual parameter types, using compare-types, such that If we run out of elements in both method signatures then If both or neither method return rest arguments (as determined by method-rest?) then the methods are of equal specificity. If the first method takes rest arguments (as determined by method-rest?) then the first method is less specific than the second. If the second method takes rest arguments (as determined by method-rest?) then the first method is more specific than the second. If we run out of elements in the first method's signature only then the first method is less specific than the second. If we run out of elements in the second method's signature only then the first method is more specific than the second. If compare-types returns 'equal we proceed to the next triple. If compare-types returns 'less-specific then the first method is less specific than the second. If compare-types returns 'more-specific then the first method is more specific than the second. This algorithm is encapsulated by the compare-methods procedure. The method form and derived forms (i.e. define-method and define-methods) permit the specification of a special first parameter to the method invocation. When a generic procedure invokes a method, this parameter is bound to a procedure that when called will invoke the "next best matching" method. This is the next method in the list of applicable methods returned by applicable-methods when it was called by the generic procedure upon invocation. If no "next best matching" method exists, i.e. the current method is the last in the list, then the next parameter is &f;. This allows methods to invoke the next best matching method selectively depending on whether it is present. This is an important feature since the dynamic nature of method selection makes it impossible to determine at the time of writing the method whether there is going to be a next best matching method. The next best matching method must be invoked with arguments to which the current method is applicable. The following example illustrates the method selection algorithm, and use of the next: parameter: (define-generic m) (define-methods m [((next: next) (<number> x) (<value> y) (<number> z) . rest) (cons 'a (if next (apply next x y z rest) '()))] [((next: next) (<number> x) (<value> y) (<number> z)) (cons 'b (if next (next x y z) '()))] [((next: next) (<number> x) (<number> y) . rest) (cons 'c (if next (apply next x y rest) '()))] [((next: next) (<number> x) (<number> y) (<value> z)) (cons 'd (if next (next x y z) '()))]) (m 1 1 1) &arrow; '(d c b a) (m 1 1) &arrow; '(c) (m 1 'x 2) &arrow; '(b a) (m 1 1 'x) &arrow; '(d c) (m 1 'x 'x) &arrow; error
Object System &requires; (import oo) Programming in the &SISC; object system usually entailse the definition of generic procedures, so typically one also has to (import generic-procedures) . The key features of the object system are: class-based, with a restricted form of multiple inheritance instance variables (aka slots) are accessed and modified via generic procedures generic procedures implement all behaviour; there is no separate notion of methods introspection API complete integration into &SISC;'s extensible type system The examples in this section follow a few naming conventions: Classes are types in the &SISC; type system and therefore class names follow the naming convention for type names (see ), for example <foo-bar-baz>. Generic procedures whose sole purpose it is to access slots of objects have names starting with : and otherwise follow the usual Scheme identifier naming conventions, i.e. all lower-case with dashes for separating words. For example :foo-bar-baz. This helps to visually distinguish slot access from ordinary procedure invocations and avoids name clashes with other procedures. Generic procedures whose sole purpose it is to modify slots of objects, are named after the corresponding accessor procedure (whether that exists or not) with a ! appended, thus following the usual Scheme convention of denoting procedures that perform mutations on their arguments. For example :foo-bar-baz!. Classes <class> <object> Classes have a name, a list of direct superclasses, and a list of direct slot descriptions. All classes are instances of the type <class> and are themselves types in &SISC;'s extensible type system. All classes are direct or indirect sub-classes of the class <object>, except for <object> itself, which has no super-classes. Classes are created as follows:
make-class &procedure; class make-class symbol class-list slot-list guid-symbol
Creates a class named symbol with the classes in class-list as its direct super-classes. See for restrictions on super-classes. When no super-classes are specified, the superclass is <object>. slot-list is a list of slot names (symbols). Slots are inherited by sub-classes. For details on slot inheritance see . If guid-symbol is specified then the new class is non-generative: if guid-symbol is already bound to a class then that class is modified, instead of a new class being created. Non-generative classes are serialised specially such that deserialising them also performs this check. By contrast, deserialisation of ordinary, generative classes and their instances results in duplicate types being created, which is usually not desirable.
(define-generics :x :y :y!) (define <foo> (make-class '<foo> '() '())) (define <bar> (make-class '<bar> '() '())) (define <baz> (make-class '<baz> (list <foo> <bar>) '(x y)))
define-class &syntax; define-class name-and-supers slot-def
where name-and-supers is of the form (class-name super-class ...) and slot-def is of the form ( slot-name [accessor [modifier]] ) Binds class-name to a newly created class. This form expands into a definition with call to make-class on the right hand side. slot-name names a slot. accessor must be a generic procedure. An accessor method for the slot will be added to it. modifier must be a generic procedure. A modifier method for the slot will be added to it.
(define-generics :x :y :y!) (define-class (<foo>)) (define-class (<bar>)) (define-class (<baz> <foo> <bar>) (x :x) (y :y :y!))
define-nongenerative-class &syntax; define-nongenerative-class name-and-supers guid slot-def
This is the same as define-class, except that the resulting class is non-generative with guid, a symbol, as the unique identifier. The significance of this is explained in make-class.
One can test whether a particular value is a class:
class? &procedure; &t;/&f; class? value
Returns &t; if value is a class, &f; otherwise.
(class? (make-class '<foo> '() '())) &arrow; &t; (class? (lambda (x) x)) &arrow; &f; (define-class (<foo>)) (class? <foo>) &arrow; &t;
The following procedures provide access to the various elements of the <class> abstract data type:
class-name &procedure; symbol class-name class
Returns the name of the class class.
(class-name (make-class '<foo> '() '())) &arrow; '<foo> (define-class (<foo>)) (class-name <foo>) &arrow; '<foo>
class-direct-superclasses &procedure; class-list class-direct-superclasses class
Returns the list of direct super-classes of the class class.
(define-class (<foo>)) (define-class (<bar>)) (define-class (<baz> <foo> <bar>)) (map class-name (class-direct-super-classes <foo>) &arrow; '()) (map class-name (class-direct-super-classes <baz>) &arrow; '(<foo> <bar>))
class-direct-slots &procedure; slot-list class-direct-slots class
Returns the list of descriptions of the direct slots of the class class. Slot descriptions are created by make-class for each slot definitions. The procedures operating on slot descriptions are documented in .
(class-direct-slots (make-class '<foo> '() '())) &arrow; '() (define-generics :x :y :y!) (define-class (<baz>) (x :x) (y :y :y!)) (class-direct-slots <baz> &arrow; (<slot> <slot>))
Slots <slot> Slot descriptions are instances of the abstract data type <slot>. They are created implicitly when classes are created; it is not possible to create them directly.
slot? &procedure; &t;/&f; slot? value
Returns &t; if value is a slot description, &f; otherwise.
(define-class (<baz>) (x) (y)) (map slot? (class-direct-slots <baz>)) &arrow; '(&t; &t;)
slot-name &procedure; symbol slot-name slot
Returns the name of the slot described by slot. This is the name given to the slot when its class was created.
(define-class (<baz>) (x) (y)) (map slot-name (class-direct-slots <baz>)) &arrow; '(x y)
slot-class &procedure; class slot-class slot
Returns the class to which the slot description slot belongs.
(define-class (<baz>) (x) (y)) (eq? (slot-class (car (class-direct-slots <baz>))) <baz>) &arrow; &t;
Slot definitions can produce procedures that allow access and modification of slots. Since slots can be defined without accessors and modifiers, this may be the only way to access/modify a particular slot.
slot-accessor &procedure; procedure slot-accessor slot
Returns a procedure than when applied to an instance of slot's class, will return the slot's value on that instance.
(define-class (<baz>) (x)) (define baz (make <baz>)) ((slot-accessor (car (class-direct-slots <baz>))) baz) &arrow; 1
slot-modifier &procedure; procedure slot-modifier slot
Returns a procedure than when applied to an instance of slot's class and a value, will set the slot's value on that instance to the supplied value.
(define-generics :x :x!) (define-class (<baz>) (x :x)) (define baz (make <baz>)) (:x baz) &arrow; 1 ((slot-modifier (car (class-direct-slots <baz>))) baz 2) (:x baz) &arrow; 2
In addition to procedures for slot access and modification, slot definitions can also produce equivalent methods. These are suitable for adding to generic procedures and can, for instance, be used to achieve the same effect as specifying generic procedures for slot access/modification at class creation time.
slot-accessor-method &procedure; method slot-accessor-method slot
This is the same as slot-accessor, except it returns a method instead of a procedure.
slot-modifier-method &procedure; method slot-modifier-method slot
This is the same as slot-modifier, except it returns a method instead of a procedure.
Instantiation initialize Class instantiation is a two-stage process. First a new object is created whose type is that of the instantiated class. Then the initialize generic procedure is called with the newly created instance and additional arguments. initialize serves the same purpose as constructors in other object systems. All the phases of class instantiation are carried out by a single procedure:
make &procedure; instance make class value
Creates a new object that is an instance of class. The instance and values are then passed as parameters to a call to the initialize generic procedure. The result of calling make is the instance.
(define-generics :x :x!) (define-class (<baz>) (x :x :x!)) (define-method (initialize (<baz> b) (<number> x)) (:x! b x)) (define baz (make <baz> 2)) (:x baz) &arrow; 2
By default the initialize contains a no-op method for initialising objects of type <object> with no further arguments. Since all objects are instances of <object> all classes can be instantiated by calling (make class). (define-generics :x :x!) (define-class (<baz>) (x :x :x!)) (define baz (make <baz>)) (:x baz) &arrow; #f
Inheritance Inheritance is a form of sub-typing. A class is a sub-type of all its direct and indirect superclasses. Method selection in generic procedures (and hence also slot access/modification) is based on a relationship called class precedence; a total order of classes based on the partial orders established by the direct super-classes:
class-precedence-list &procedure; class-list class-precedence-list class
Returns the total order of class and all direct and indirect super-classes, as determined by the partial orders obtained from calling class-direct-superclasses. The ordering of classes returned by class-direct-superclasses is considered "weak" whereas the ordering of the class itself to its direct super-classes is considered strong. The significance of this is that when computing the class precedence list weak orderings are re-arranged if that is the only way to obtain a total order. By contrast, strong orderings are never rearranged.
(define-class (<foo>)) (define-class (<bar> <foo>)) (define-class (<baz> <foo>)) (define-class (<boo> <bar> <baz>)) (define-class (<goo>)) (define-class (<moo1> <bar> <baz> <goo>)) (map class-name (class-precedence-list <moo1>)) &arrow; (<moo1> <bar> <baz> <goo> <foo> <object>) (define-class (<moo2> <bar> <baz> <foo> <goo>)) (map class-name (class-precedence-list <moo2>)) &arrow; (<moo1> <bar> <baz> <foo> <goo> <object>) (define-class (<moo3> <baz> <bar> <boo>)) (map class-name (class-precedence-list <moo3>)) &arrow; (<moo3> <boo> <baz> <bar> <foo> <object>)
For any two classes in the class precedence list that have direct slots, one must be a sub-class of the other. In effect this enforces single inheritance of slots while still giving control over the order of classes in the class-precedence list. Slots from a superclass are only ever inherited once, regardless of the number of paths in the inheritance graph to that class. If a sub-class defines a slot with the same name as one of its super-classes, instances of the resulting class ends up with two slots of the same name. If the slots are define with different accessors and modifiers then this does not cause any problems at all. If they are not then an invocation of the accessor/modifier will acess/modify the slot of the sub-class. Note that it is still possible to access/modify the slot of the superclass by using procedures/methods obtained from the slot descriptor. See . The following example illustrates the rules governing slot inheritance. ;;ordinary slot access and modification (define-generics :x :x! :y :y! :z :z! :xb :xb! :yb :yb! :zb :zb!) (define-class (<foo>) (x :x :x!) (y :y :y!) (z :z)) (define f (make <foo>)) (:x f) &arrow; #f (:y f) &arrow; #f (:z f) &arrow; #f (:x! f 2) (:y! f 2) (:x f) &arrow; 2 (:y f) &arrow; 2 ;;overloading slots in sub-class (define-class (<bar> <foo>) (x :x :x!) (y :yb :yb!) (zb :zb :zb!)) (define b (make <bar>)) (:x b) &arrow; #f (:y b) &arrow; #f (:z b) &arrow; #f (:yb b) &arrow; #f (:zb b) &arrow; #f (:y! b 3) (:yb! b 4) (:y b) &arrow; 3 (:yb b) &arrow; 4 ;;accessing a fully shadowed slot (define :foo-x (cdr (assq 'x (map (lambda (x) (cons (slot-name x) (slot-accessor x))) (class-direct-slots <foo>))))) (:foo-x b) &arrow; 1 ;;inheritance restriction on slots (define-class (<boo> <baz>) (yb :yb :yb!)) (define-class (<goo>)) (define-class (<moo> <bar> <boo> <goo>)) &arrow; error
sisc-1.16.6.orig/doc/sss/java.xml0000644000175000017500000041423511445752462015174 0ustar amoeamoe Java Interaction &SISC; can be used as a scripting language for Java, or Java may be used to provide functionality to Scheme. Such activity is collectively termed 'bridging'. In &SISC; bridging is accomplished by a Java API for executing Scheme code and evaluating Scheme expressions, and a module that provides Scheme-level access to Java objects and implementation of Java interfaces in Scheme. Calling Scheme from Java Calling programmer-defined Scheme code from Java is a simple process, but requires some initialization before proceeding. Depending on the use case of &SISC;, the initialization may be largely automatic. Any Scheme call first requires four resources: An Application Context (AppContext), which encapsulates the entirety of a single application's interactions with &SISC;. This is initialized with ... A Heap, which provides the environments and base code to execute programs using ... A Dynamic Environment, which contains thread specific values such as the current I/O ports, and An Interpreter, which provides the engine and API for actually evaluating Scheme code. Each resource is described in the sections below. The gateway for interacting with these resources is primarily the sisc.interpreter.Context utility class. Application Contexts The Application Context, represented by the class sisc.interpreter.AppContext, holds references to the top-level environment, global configuration properties, and other resources which are unique to a single usage of &SISC;. This should not be confused with multiple threads or invocations into the same application. An AppContext is created simply using the default constructor, or a constructor which takes a Java Properties class with overrides for global Scheme properties as described throughout this manual. The application context is the token used by most of the API for calling Scheme from Java code, though many of the API calls can either infer the AppContext from the currently executing thread, or defer to a default context. A default application context may be necessary when Scheme code is called through callbacks or other Java mechanisms in code which is not aware of &SISC; or the Scheme code which is being called. The default application context can be set explicitly after creating the context, but is also set implicitly by &SISC; if there is not already a default context when one is needed. To set the default application context, use the following method from Context: public setDefaultAppContext sisc.interpreter.AppContext ctx
Set the default AppContext to the instance provided.
public sisc.interpreter.AppContext getDefaultAppContext
Retrieves the current default AppContext, possibly creating and initializing one using the default heap if no default was set.
Remember that an application context is nearly always useless until initialized with a heap, as described in the next section.
The &SISC; Heap The heap is a serialization of all the pre-compiled code which makes up both the base Scheme language provided by &SISC;, and many of its libraries. Distributions of &SISC; come with a prepackaged heap which is sufficient for most usages, and customizing a heap should be viewed as a last resort, as precompiled libraries usually solve the same problem. A heap is a randomly accessed structure which must be loaded into an application context. The heap can be automatically located if it is in the directory pointed to by the SISC_HOME environment variable, the current directory, or on the Java classpath. In the last case however, it will be loaded into memory entirely, rather than read in as needed. The automatic heap location involves calling addDefaultHeap on the AppContext, and is used when an application context is created implicitly.
addDefaultHeap public addDefaultHeap
Uses findHeap, openHeap, and addHeap to find and register a default heap with this application context
The URL that is produced through this discovery can be obtained using the findHeap method in AppContext:
findHeap public static java.net.URL findHeap String heapName
Searches for the heap with the given name, or if null, sisc.shp in several candidate locations. If a heap is found, a URL pointing to it is returned, otherwise null is returned.
One of the locations searched is the classpath, by searching for a heap anchor, and loading the heap file from the same package. To do this, the heap must be on the classpath in the same location as HeapAnchor.class. A utility script, build-heapjar.scm, executed as an SRFI-22 script, is included in the scheme-src directory of the full distribution. It is invoked from the directory containing the heap, and will by default emit sisc-heap.jar into the current directory. If that jar file is on the classpath, findHeap will locate it automatically. Once located, the heap is opened and registered with the AppContext, allowing the context to then be used for Scheme evaluation. This is done with the openHeap and addHeap methods:
openHeap public static sisc.ser.SeekableInputStream openHeap java.net.URL heapURL
Opens the heap pointed to by the given URL, returning an appropriate random access input stream suitable for passing to addHeap.
addHeap public boolean addHeap sisc.ser.SeekableInputStream heap
Registers the given heap stream with the application context. Returns true if the registration is successful, false otherwise.
The Dynamic Environment The dynamic environment, represented by the sisc.env.DynamicEnvironment class, is the datastructure which stores dynamic variables. That is, variables whose values are not scoped lexically and are associated with threads rather than code. This includes such values as the current input and output ports, Scheme parameters, and the class path. Each interpreter contains a reference to its current dynamic environment, and the dynamic environment cannot be shared between two threads, or by more than one application context called in the same thread. They should be shared across call boundaries in a single thread and single application, but must be created anew for external calls and cross application calls, and cloned for new threads. It should seem obvious, then, that maintaining the correct dynamic environment in all call situations can be tricky. Fortunately, the supported API calls in Context detect and do the Right Thing in most situations. The Interpreter The Interpreter class contains the engine for evaluating Scheme code, and API methods for triggering that evaluation. Each thread of execution must have its own Interpreter instance. Interpreters are obtained before one or more calls into Scheme, and using methods on the Context helper class depending on whether the call is an Internal or External call. A Scheme application can execute in multiple threads. Each thread must have its own dynamic environment, containing entities such as the current input and output ports. Dynamic environments are represented by instances of the sisc.env.DynamicEnvironment class. Internal calls need to create fresh interpreters in order to preserve and subsequently restore the state of the surrounding Scheme execution. Thus a single thread may be home to several interpreters. In any case, the programmer must ensure that all calls to an interpreter are made by the same thread. If another thread wishes to execute Scheme code, it must follow the API below to obtain a different interpreter. External Calls An external call is a call made from Java to Scheme with no preceding call from Scheme to Java, in other words, the call is entirely external to the Scheme environment. For example, this may occur as a result of a timer expiration or a thread created by Java. In this case, the application context must be specified, and a new dynamic environment (containing thread specific information such as the current input and output ports) must be created. The preferred method for an external call is called a managed external call, and uses the visitor pattern with one of the following methods in the Context class:
execute public static Object execute sisc.interpreter.AppContext ctx sisc.interpreter.SchemeCaller caller sisc.interpreter.SchemeException
Creates an Interpreter context for the application context if provided, or the default application context if ctx is null, and calls execute in the caller with the new Interpreter. When the caller returns, the Interpreter is freed, and the return value of the caller is returned.
execute public static Object execute sisc.interpreter.SchemeCaller caller sisc.interpreterSchemeException
Creates an Interpreter context for the default application context, loading the default heap if necessary, and calls the execute method of the caller object with the new Interpreter (that is, it is equivalent to execute(null, caller)). This simple interface is the one you should use if you do not have a particular reason to use a non-default application context.
The visitor instances implement sisc.interpreter.SchemeCaller and are responsible for implementing the following method:
execute public Object execute sisc.interpreter.Interpreter r sisc.interpreter.SchemeException
Utilizes the given Interpreter to make Java to Scheme calls. Any Object may be returned.
As an alternative to this managed external call, a call from Java to Scheme can be made by using the enter method of Context to obtain an interpreter, then making several calls to the interpreter, then releasing it using exit. This has some weaknesses, however. Because this pair of calls cannot enforce that all intervening calls to the Interpreter run in the same thread, subtle issues can arrise if the Interpreter context is saved as a reference in a program and used by competing threads. Other, more subtle issues exist, such as the association of a thread handle (as retrievable using SRFI-18) in Scheme with the Java thread which is making the call. For this reason, the managed external call form is preferred whenever possible.
enter public sisc.interpreter.Interpreter enter sisc.interpreter.AppContext ctx sisc.env.DynamicEnvironment ctx
Obtains an instance of Interpreter for the provided application context if provided, the current or default otherwise. If provided, the given dynamic environment is used rather than the environment selected automatically for the type of call.
The dynamic environment optional argument in the enter method may be specified if one wants to use a different mechanism for finding applications and dynamic environments. For instance, threads created from Scheme should probably execute within the application that created them and using a dynamic environment that is cloned from the dynamic environment present when the thread is started. The enter method can therefore be used as general mechanism for obtaining a new interpreter that uses a specific application and dynamic environment. When the Interpreter is no longer by the current thread needed it must be released using:
exit public exit
Release the resources of the current interpreter.
Internal Calls Internal calls are calls to Scheme made from Java, from a previous call into Java from Scheme. In other words, the call to Scheme is made internally from other Scheme code. One can determine if a call is internal in the following manner: Interpreter current = Context.currentInterpreter(); if (current == null) { ...make external call...} else { ...make internal call... } This case is more complex, as it requires maintaining the correct dynamic environment and Interpreter instance to preserve return context. When making an internal call, one typically wants to make the call in an interpreter that shares the same application context and dynamic enviornment as the calling interpreter. Fortunately, the details are managed by the Context helper class. The same calling mechanisms are used as in an external call, but the application context is ommited as a parameter to the functions. The Interpreter API No matter which mechanism is used, the Interpreter is eventually used to call Scheme code, using any of the following methods: eval public Value eval String expr sisc.interpreter.SchemeException java.io.IOException
Evaluates expressions read from a string, returning the result of the evaluation of the last expression.
public Value eval InputStream stream String sourceId sisc.interpreter.SchemeException java.io.IOException
Evaluates expressions read from an input stream, returning the result of the evaluation of the last expression. The sourceId identifies the source of the stream for display purposes.
public Value eval Value val sisc.interpreter.SchemeException
This is the same as calling (eval val) in Scheme.
public Value eval Procedure proc Value[] args sisc.interpreter.SchemeException
This is the same as calling (proc arg ...) in Scheme. This is the most efficient type of call, as it requires no parsing or compilation.
Several such calls can be made consecutively on the same interpreter. A SchemeException may be thrown by any of these methods if an error occurs in the Scheme code.
Miscellaneous Features Error Handling Interpreter.eval() throws a sisc.interpreter.SchemeException when an evaluation causes an exception that is not caught inside the evaluation. When making internal calls the exception can be propagated to the calling interpreter in one of four ways: by throwing a RuntimeException - this will be reported as"Error in "prim-name: description". by calling Module.throwPrimException("description") - this will be reported as "Error in prim-name: description". by calling throwNestedPrimException("description", schemeException) - this will be reported as "Error in prim-name: description\nnested-description". by calling throwNestedPrimException(schemeException) - this will be reported as "Error in prim-name: exception during nested call\nnested-description". Scheme code can throw Java exceptions (see ). The sisc.modules.s2j.Util class contains a static method javaException(schemeException) that extracts the Java exception from a SchemeException, or, if no Java exception is present, returns the SchemeException. Continuations Continuations do not cross the Scheme/Java boundary. In the embedded call scenario invoking a continuation inside the embedded call will not discard the computation of the caller. The embedded call will return when the continuation returns. If the continuation contains the read-eval-print loop the return will never happen. Similarly, capturing a continuation inside a call (embedded or external) will only capture the continuation to point where the call was made. Capturing and invoking a continuation within the same call works correctly. Scheme I/O Scheme ports are thin wrappers around the Java I/O hierarchy, adding some functionality needed by Scheme. As such, it is trivial to obtain Java compatible I/O objects from Scheme ports. For information on obtaining Scheme and Java compatible I/O objects in Scheme, see the Java I/O module described in . Scheme ports are encapsulated in the SchemeBinaryInputPort, SchemeBinaryOutputPort, SchemeCharacterInputPort, SchemeCharacterOutputPort classes in the sisc.data package. An instance of a port class contains an accessor which returns the relevant Java I/O type, as described for each class below.
public sisc.data.SchemeBinaryInputPort getInputStream public java.io.InputStream getInputStream
Return a Java InputStream for accessing this Scheme port.
public sisc.data.SchemeBinaryOutputPort getOutputStream public java.io.OutputStream getOutputStream
Return a Java OutputStream for accessing this Scheme port.
public sisc.data.SchemeCharacterInputPort getReader public java.io.Reader getReader
Return a Java Reader for accessing this Scheme port.
public sisc.data.SchemeCharacterOutputPort getWriter public java.io.Writer getWriter
Return a Java Writer for accessing this Scheme port.
Quick Reference The tables below cover the most common use cases for calling Scheme from Java, and provide simple pseudocode examples. Typical Java to Scheme, External Calls Situation Code Default Application Context Heap can be located automatically... No action required. ...or, with a custom heap AppContext ctx=new AppContext(); SeekableInputStream myHeap=AppContext.openHeap(myHeapURL); ctx.addHeap(myHeap); Context.setDefaultAppContext(ctx); Then, making the external call. Context.execute(mySchemeCaller); Custom Application Context Creating the context. AppContext ctx=new AppContext(myProperties); Heap can be located automatically ... ctx.addDefaultHeap(); ... or, with a custom heap SeekableInputStream myHeap=AppContext.openHeap(myHeapURL); ctx.addHeap(myHeap); Then, making the external call. Context.execute(ctx, mySchemeCaller);
Typical Java to Scheme, Internal Calls Situation Code Making the internal call. Context.execute(mySchemeCaller);
Calling Java from Scheme &requires; (import s2j) The High-Level S2J API allows Scheme code to instantiate Java classes, call methods on Java objects, access/modify fields of Java objects and implement Java interfaces that delegate to Scheme code. Classes Java classes are types in &SISC;'s extensible type system (see ). They are made accessible to Scheme code by one of the following procedures / special forms:
java-class &procedure; jclass java-class symbol
Returns the Java class of name symbol, which can also be the name of a primitive type or an array type.
(java-class '|java.lang.String|) &arrow; <jclass> (define <java.io.object-input-string/get-field**> (java-class '|java.io.ObjectInputStream$GetField[][]|))
define-java-class &syntax; define-java-class scheme-name java-name
Binds scheme-name to the Java class named by java-name, or, if no such parameter is supplied, by the mangled scheme-name.
(define-java-class <jstring> |java.lang.String|) (define-java-class <java.io.object-input-string/get-field**>)
define-java-classes &syntax; define-java-classes form
where form is of the form scheme-name or (scheme-name java-name ) Creates bindings for several Java classes. The form expands into several define-java-class forms.
(define-java-classes (<jstring> |java.lang.String|) <java.io.object-input-string/get-field**>)
Mangling of class names allows classes to be identified more schemely, e.g. <java.io.object-input-stream/get-field**> corresponds to the Java type java.io.ObjectInputStream.GetField[][] (note that GetField is a nested class). More formally, mangling of class names checks for the presence of angle brackets (<>) around the scheme-name. If they are present they are stripped. All the identifiers between the dots (.) are passed through field name mangling (see ). The character following the last dot is upcased. A slash (/) is treated as a nested class indicator; it is replaced with dollar ($ and the character following it is upcased. Trailing stars (*) characters are replaced with pairs of brackets ([]).
There are predicates for determining whether a Scheme value is a Java class or interface. All Java interfaces are also Java classes.
java-class? &procedure; &t;/&f; java-class? value
Returns &t; if value is a Java class, &f; otherwise.
(java-class? (java-class '|java.lang.String|) &arrow; &t; (define <java-io-object-input-string/get-field**> (java-class '|java.io.ObjectInputStream$GetField[][]|)) (java-class? <java.io.object-input-string/get-field**>) &arrow; &t;
java-interface? &procedure; &t;/&f; java-interface? value
Returns &t; if value is a Java interface, &f; otherwise.
(java-interface? (java-class '|java.util.Map|)) &arrow; &t; (java-interface? (java-class '|java.lang.String|) &arrow; &f;
Java classes are serializable by the &SISC; runtime.
Methods Java methods are made accessible to Scheme code as procedures that can invoke any method of a given name on any Java object. Method selection is performed based on the types of the arguments to the procedure call. Static Java methods can be invoked by passing an instance of the appropriate class or an appropriately typed null object (see ) as the first argument to the procedures.
generic-java-method &procedure; procedure generic-java-method symbol
Returns a procedure that when invoked with a Java object as the first argument and Java values as the remaining arguments, invokes the best matching named method named symbol on the Java object and returns the result.
(generic-java-method '|getURL|) &arrow; <jmethod> (define empty-list? (generic-java-method '|isEmptyList|))
define-generic-java-method &syntax; define-generic-java-method scheme-name java-name
Binds scheme-name to the generic Java method named by java-name, or, if no such parameter is supplied, by the mangled scheme-name.
(define-generic-java-method get-url |getURL|) (define-generic-java-method empty-list?)
define-generic-java-methods &syntax; define-generic-java-methods form
where form is of the form scheme-name or (scheme-name java-name ) Creates bindings for several generic Java methods. The form expands into several define-generic-java-method forms.
(define-generic-java-methods (get-url |getURL|) empty-list?)
Method name mangling allows methods to be identified more schemely, e.g. empty-list? corresponds to the Java method name isEmptyList. More formally, mangling of method names removes trailing exclamation marks (!) and replaces trailing question marks (?) with a leading is-. The result of this mangling is passed through field mangling (see ).
Generic Java methods are serializable by the &SISC; runtime.
Fields Fields are made accessible to Scheme code as procedures that can get / set any field of a given name on any Java object. If several fields of the same name are present in the object due to the object class's inheritance chain, the most specific field, i.e. the one bottommost in the inheritance hierarchy, is selected. Static Java fields can be accessed / modified by passing an instance of the appropriate class or an appropriately typed null object (see ) as the first argument to the procedures. Generic Java field accessors, i.e. procedures that allow Scheme code to obtain the value of a Java field, can be defined as follows:
generic-java-field-accessor &procedure; procedure generic-java-field-accessor symbol
Returns a procedure that when invoked with a Java object as the first argument, retrieves the value of the Java field named symbol in the Java object.
(generic-java-field-accessor '|currentURL|) &arrow; <jfield> (define :current-input-port (generic-java-field-accessor '|currentInputPort|))
define-generic-java-field-accessor &syntax; define-generic-java-field-accessor scheme-name java-name
Binds scheme-name to the generic Java field accessor for fields named java-name, or, if no such parameter is supplied, the mangled scheme-name.
(define-generic-java-field-accessor :current-url |currentURL|) (define-generic-java-field-accessor :current-input-port)
define-generic-java-field-accessors &syntax; define-generic-java-field-accessors form
where form is of the form scheme-name or (scheme-name java-name ) Creates bindings for several generic Java field accessors. The form expands into several define-generic-java-field-accessor forms.
(define-generic-java-field-accessor (:current-url |currentURL|) :current-input-port)
Generic Java field modifiers, i.e. procedures that allow Scheme code to set the value of a Java field, can be defined as follows:
generic-java-field-modifier &procedure; procedure generic-java-field-modifier symbol
Returns a procedure that when invoked with a Java object as the first argument and a Java value as the second argument, sets the value of the Java field named symbol in the Java object to that value.
(generic-java-field-modifier '|currentURL|) &arrow; <jfield> (define :current-input-port! (generic-java-field-modifier '|currentInputPort|))
define-generic-java-field-modifier &syntax; define-generic-java-field-modifier scheme-name java-name
Binds scheme-name to the generic Java field modifier for fields named java-name, or, if no such parameter is supplied, the mangled scheme-name.
(define-generic-java-field-modifier :current-url! |currentURL|) (define-generic-java-field-modifier :current-input-port!)
define-generic-java-field-modifiers &syntax; define-generic-java-field-modifiers form
where form is of the form scheme-name or (scheme-name java-name ) Creates bindings for several generic Java field modifiers. The form expands into several define-generic-java-field-modifier forms.
(define-generic-java-field-modifier (:current-url! |currentURL|) :current-input-port!)
The mangling of field names allows fields to be identified more schemely. By convention field accessors should be named with a leading colon (:) followed by the field name, and field modifiers with a leading colon (:) followed by the field name followed by an exclamation mark (!), e.g. :foo-bar and :foo-bar! are the names of the accessor and modifier for Java fields named fooBar. Mangling of field names upcases any character following a dash (-) and removes all characters that are not legal as part of Java identifiers. Generic Java field accessors and modifiers are serializable by the &SISC; runtime.
Instances Scheme code can instantiate Java classes with a call to the following procedure:
java-new &procedure; jobject java-new jclass jobject
Selects a constructor of jclass based on the types of the jobjects and calls it, returning the newly created object.
(define-java-class <java.util.linked-hash-set>) (java-new <java.util.linked-hash-set> (->jint 100)) &arrow; <jobject>
There is a predicate for determining whether a value is a Java object:
java-object? &procedure; &t;/&f; java-object? value
Returns &t; if value is a Java object, &f; otherwise. Note that, unlike in Java, instances of primitive Java types are considered to be Java objects.
(define-java-class <java.util.linked-hash-set>) (define hs (java-new <java.util.linked-hash-set> (->jint 100))) (java-object? hs) &arrow; &t; (java-object? (->jint 100)) &arrow; &t;
Unlike in Java, null objects are typed. Typed null objects play a key role in invoking static methods an accessing / modifying static fields.
java-null &procedure; jnull java-null jclass
Returns a Java null object of type jclass.
(define-java-class <java.util.linked-hash-set>) (java-null <java.util.linked-hash-set>) &arrow; <jnull>
There is a predicate for determining whether a value is a Java null. All nulls are also Java objects.
java-null? &procedure; &t;/&f; java-null? value
Returns &t; if value is a Java null object, &f; otherwise.
(define-java-class <java.util.linked-hash-set>) (java-null? (java-null <java.util.linked-hash-set>)) &arrow; &t;
jnull For convenience, jnull is bound to the typed null object obtained by calling java-null on java.lang.Object.
Any invocation of a Java method, or access to a Java fields that returns a Java null does so typed based on the declared return / field type. Comparison of Java objects using eqv? compares the objects using Java's == comparison. equal?, on the other hand, compares the objects using Java's equals method. eq? uses pointer equality on the Scheme objects representing the Java objects and is therefore not generally useful. Applying eq?, eqv? or equal? to a mixture of Java objects and other Scheme values returns &f;. Java objects are only serializable by the &SISC; runtime if they support Java serialization. Java nulls are always serializable.
Arrays Scheme code can create Java arrays with a call to the following procedure:
java-array-new &procedure; jarray java-array-new jclass size
Creates an array of component type jclass with dimensions size, which can be a number (for a single-dimensional array), or a vector / list of numbers (for multi-dimensional arrays).
(java-array-new <jint> 2) &arrow; <jarray> (define-java-class <java.lang.string>) (java-array-new <java.lang.string> '#(2 2 2)) &arrow; <jarray>
There is a predicate for determining whether a value is a Java array. All Java arrays are also Java objects.
java-array? &procedure; &t;/&f; java-array? value
Returns &t; if value is a Java array, &f; otherwise.
(java-array? (java-array-new <jint> 2)) &arrow; &t;
Elements of arrays are accessed and modified with:
java-array-ref &procedure; jobject java-array-ref jarray index
Returns the element at index index of jarray. index can be a number, for indexing into the first dimension of the array, or vector / list of numbers for multi-dimensional indexing.
(define a (->jarray (map ->jint (iota 10)) <jint>)) (java-array-ref a 1) &arrow; <java int 1> (java-array-ref a '(1)) &arrow; <java int 1>
java-array-set! &procedure; java-array-set! jarray index jobject
Sets the element at index index of jarray to jobject. index can be a number, for indexing into the first dimension of the array, or vector / list of numbers for multi-dimensional indexing.
(define a (->jarray (map ->jint (iota 10)) <jint>)) (java-array-set! a 1 (->jint 2)) (java-array-ref a 1) &arrow; <java int 2> (define a (java-array-new <jint> '#(2 2 2))) (java-array-set! a '#(1 1 1) (->jint 1))
The length of a Java array can be determined with
java-array-length &procedure; number java-array-length jarray
Returns the length of jarray.
(define a (->jarray (map ->jint (iota 10)) <jint>)) (java-array-length a) &arrow; 10 (define a (java-array-new <jint> '#(2 3 4))) (java-array-length a) &arrow; 2
Scheme vectors and lists can be converted to Java array and vice versa.
->list &procedure; list ->list jarray
Creates a list containing the elements of jarray.
(define a (->jarray (map ->jint (iota 5)) <jint>)) (map ->number (->list a)) &arrow; '(0 1 2 3 4)
->vector &procedure; vector ->vector jarray
Creates a vector containing the elements of jarray.
(define a (->jarray (map ->jint (iota 5)) <jint>)) (map ->number (vector->list (->vector a))) &arrow; '(0 1 2 3 4)
->jarray &procedure; jarray ->jarray list-or-vector jclass
Creates a one-dimensional array of type jclass and fills it with the values obtained from the Scheme vector or list.
(define a (->jarray (map ->jint (iota 5)) <jint>))
Proxies Scheme code cannot create sub-classes of existing Java classes. It is, however, possible to create classes implementing existing Java interfaces. These classes are called proxies. Calling a method on a proxy invokes a user-definable Scheme procedure, based on the name of the method, passing the proxy object and the parameters of the method invocation as arguments. The result of the invocation is returned as the result of the method call.
define-java-proxy &syntax; define-java-proxy signature interfaces method
where signature is of the form (name param ...), interfaces is of the form (interface ...), and method is of the form (define method-name procedure), or (define ( method-name method-arg ...) . body) Creates a proxy generator procedure and binds it to name. A proxy class is created that implements all the interfaces. When the generator is invoked, an instance of the proxy class is returned that delegates all method invocations to the Scheme procedures in the method definition list, based on the names of the methods. The first kind of definition form defines procedure to be the method handler for the java method named method-name. method-name undergoes name mangling as described in . Note that procedure is inside the lexical scope of the generator procedure, so params are accessible inside it. The second kind of definition form is equivalent to the following first-type form: (define method-name (lambda (method-arg ...) . body)). If a method is invoked on a proxy for which no method handler exists and error is returned to the caller.
(define-java-classes <java.util.comparator> <java.util.arrays> <java.lang.object>) (define-java-proxy (comparator fn) (<java.util.comparator>) (define (.compare this obj1 obj2) (let ([x (java-unwrap obj1)] [y (java-unwrap obj2)]) (->jint (cond [(fn x y) -1] [(fn y x) +1] [else 0]))))) (define-generic-java-method sort) (define-java-class <java.lang.object>) (define (list-sort fn l) (let ([a (->jarray (map java-wrap l) <java.lang.object>)]) (sort (java-null <java.util.arrays>) a (comparator fn)) (map java-unwrap (->list a)))) (list-sort < '(3 4 2 1)) &arrow; '(1 2 3 4) (list-sort string<? '("foo" "bar" "baz")) &arrow; '("bar" "baz" "foo")
Types and Conversions <jvoid> <jboolean> <jdouble> <jfloat> <jlong> <jint> <jshort> <jbyte> <jchar> For convenience, all the primitive Java types, i.e. void, boolean, double, float, long, int, short, byte, char, are predefined and bound to <jvoid>, <jboolean>, <jdouble>, <jfloat>, <jlong>, <jint>, <jshort>, <jbyte>, <jchar>, respectively. When calling Java methods, invoking Java constructors, accessing or modifying Java fields, no automatic conversion is performed between ordinary Scheme values and Java values. Instead explicit conversion of arguments and results is required. Automatic conversion is not performed for the following reasons: For some Scheme types, such as numbers, the mapping to Java types is one-to-many, e.g. a Scheme number could be converted to a byte, short, int, etc. This causes ambiguities when automatic conversion of parameters is attempted. Some Java types have several corresponding Scheme types, e.g. a Java array could be represented as Scheme list or vector - this causes ambiguities when automatic conversion of results is attempted. Conversion carries an overhead that can be significant. For instance, Java strings have to be copied "by value" to Scheme strings since the former are immutable and the latter aren't. In a chained-call scenario, i.e. where the results of one method invocation are passed as arguments to another, the conversion is unnecessary and a wasted effort. Conversion breaks the object identity relationship. In a chained-call scenario, the identities of the objects passed to the second call are different from the ones returned by the first. This causes problems if the called Java code relies on the object identity being preserved. Conversion conflicts with generic procedures. The method selection mechanism employed by generic procedures relies on objects having exactly one type. Automatic conversion effectively gives objects more than one type - their original type and the type of the objects they can be converted to. While it would be technically possible to devise a method selection algorithm that accommodates this, the algorithm would impose a substantial overhead on generic procedure invocation and also make it significantly harder for users to predict which method will be selected when invoking a generic procedure with a particular set of arguments. Conversion functions are provided for converting instances of primitive Java types to instances of standard Scheme types:
->boolean &procedure; &t;/&f; ->boolean jboolean ->character &procedure; character ->character jchar ->number &procedure; number ->number jbyte/jshort/jint/jlong/jfloat/jdouble
Conversion functions also exists for the opposite direction, i.e. converting instances of standard Scheme types to instances of primitive Java types
->jboolean &procedure; jboolean ->jboolean boolean ->jchar &procedure; jchar ->jchar character ->jbyte &procedure; jbyte ->jbyte number ->jshort &procedure; jshort ->jshort number ->jint &procedure; jint ->jint number ->jlong &procedure; jlong ->jlong number ->jfloat &procedure; jfloat ->jfloat number ->jdouble &procedure; jdouble ->jdouble number
Finally, there are conversion functions for converting between Java strings and Scheme strings and symbols:
->string &procedure; string ->string jstring ->symbol &procedure; symbol ->symbol jstring ->jstring &procedure; jstring ->jstring string/symbol
Scheme values are not Java objects and hence cannot be passed as arguments in Java method or constructor invocations or when setting Java fields. However, all Scheme values are internally represented by instances of classes in the SISC runtime. S2J provides a mechanism to get hold of this internal representation as an S2J Java object. The converse operation is also supported - a Java instance obtained via a Java method or constructor invocation or field access in S2J can be turned into a Scheme value if it is an instance of an appropriate &SISC; runtime class. These two operations are called "wrapping" and "unwrapping" respectively because conceptually the scheme object is wrapped to make it appear like a Java object and the wrapper is removed in order to recover the original Scheme object.
java-wrap &procedure; jobject java-wrap value
Returns the Java object that represents the Scheme value in &SISC;'s runtime.
java-unwrap &procedure; value java-unwrap jobject
Returns the Scheme value represented by the jobject. If jobject is not an object representing a Scheme value in SISC's runtime and error is thrown.
(define-java-class <java.lang.object>) (define a (java-array-new <java.lang.object> '#(1))) (java-array-set! a '#(0) (java-wrap 'foo)) (java-unwrap (java-array-ref a '#(0))) &arrow; 'foo
Wrapping and unwrapping allows Scheme values to be used in generic (i.e. not type-specific) Java operations, such as those of the Java collection API. It is also frequently used in connection with proxies when Scheme objects are passed back and forth through layers of Java to a Scheme-implemented proxy that manipulates them. Finally, wrapping and unwrapping permit &SISC; Scheme code to interface to the &SISC; runtime.
Multi-threading In Java each object is a potential thread synchronization point. Therefore Scheme code needs to be able to synchronize on Java objects in order for it to interoperate properly with Java in a multi-threaded application. This is accomplished by the following procedure:
java-synchronized &procedure; value java-synchronized jobject thunk
Runs thunk in a block synchronized on jobject, returning the result returned by thunk. This is the equivalent to synchronized (jobject) { return thunk(); } in Java. It is illegal for thunk to invoke continuations that escape thunk, or for code outside thunk to invoke a continuation captured inside thunk.
(define-java-class <java.lang.object>) (define mtx (java-new <java.lang.object>)) (define v 0) (define (inc-v) (java-synchronized mtx (lambda () (set! v (+ v 1)) v))) (define (dec-v) (java-synchronized mtx (lambda () (set! v (- v 1)) v))) (import threading) (begin (parallel inc-v dec-v inc-v inc-v dec-v dec-v) v) &arrow; 0
Exception Handling Java exceptions are propagated to scheme and can be caught like any other exception, e.g. with with/fc as defined in . The s2j module exports augmented versions of the print-stack-trace and print-exception functions that handle Java exceptions. For example (define-generic-java-method char-at) (with/fc (lambda (m e) (print-exception (make-exception m e))) (lambda () (char-at (->jstring "foo") (->jint 3)))) will catch the IndexOutOfBoundsException, print its stack trace and return &f;. In Scheme, Java exceptions can be thrown by raising an error containing the Java exception as the message, e.g. (define-java-class <java.util.no-such-element-exception>) (error (java-new <java.util.no-such-element-exception>)) or (throw (make-error (java-new <java.util.no-such-element-exception>))) If this occurs inside a proxy method (see ), the exception is propagated to the invoking Java code. Access Permissions Invoking [define-]java-class[es], java-new or any of the procedures defined with [define-]generic-java-{method,field-accessor,field-modifier}[s] causes S2J to perform reflection on the named Java class(es), the class passed as the first argument, or the class corresponding to the type first argument passed to the other procedures, respectively. This process collects information about all the constructors, methods and fields of the class and its superclasses/interfaces. The only class members processed during this automatic reflection are public ones declared in public classes. This almost exactly mimics the visibility rules in Java for code residing in packages other than the one the member is residing in. It is also in line with the default permissions granted to the Java reflection API. There is one rare case where this rule is more restrictive than Java's: public members of package-protected classes are not visible even when accessed via a public sub-class. Depending on the security settings, the Java reflection API is in fact capable of granting access to any members of any class. However, using this in the automatic reflection performed by S2J would constitute a significant departure from normal Java behaviour and result in unpredictable results to the user. For instance, undocumented private methods would be invoked in preference to documented public methods if the formers type signature provided a better match. Automatic reflection ignores security exceptions thrown by the Java reflection API, i.e. the class in question will appear to have no constructors, methods and fields. This is designed to cope with situations where the default security settings have been altered in a way that prevents access to members of some (or even all) classes. In some applications the reflection API permissions depend on the context of the invocation. For instance, in applets it is usually possible to access class member information as part of the initialisation but not after that. Since [define-]java-class[es] triggers automatic reflection, it can be used to control when automatic reflection for specific classes takes place. Common Usage This section provides a summary of all the commonly used S2J features, correlating them with the corresponding Java code. It makes use of some functions from the srfi-1, srfi-26 and misc modules (require-library 'sisc/libs/srfi) (import* srfi-1 fold) (import* srfi-26 cut cute) (import* misc compose) Common S2J Usage Java Scheme create bindings for classes, methods and fields n/a (define-java-classes <foo.bar-baz> <foo.bar-boo>) (define-generic-java-methods get-bar get-baz set-bar! set-baz!) (define-generic-java-field-accessors :bar :baz) (define-generic-java-field-modifiers :bar! :baz!) instantiate class foo.BarBaz fooObj = new foo.BarBaz(a, b, c); (define foo-obj (java-new <foo.bar-baz> a b c)) invoke method on instance Object res = fooObj.barBaz(a, b, c) (define res (bar-baz foo-obj a b c)) invoke method on class Object res = foo.Bar.baz(a, b, c) (define res (baz (java-null <foo.bar>) a b c)) access instance field Object res = fooObj.bar; (define res (:bar foo-obj)) access class field Object res = foo.Bar.baz; (define res (:bar (java-null <foo.bar>))) modify instance field fooObj.bar = val; (:bar! foo-obj val) modify class field foo.Bar.baz = val; (:bar! (java-null <foo.bar>) val) chained field access Object res = fooObj.bar.baz.boo (define res (fold (cut <> <>) foo-obj (list :bar :baz :boo))) or (define res ((compose :boo :baz :bar) foo-obj)) This works equally well for bean fields. chained field modification fooObj.bar.baz.boo = moo; (:boo! (fold (cut <> <>) foo-obj (list :bar :baz)) moo) or (:boo! ((compose :baz :bar) foo-obj) moo) This works equally well for bean fields. accessing several fields a = fooObj.bar; b = fooObj.baz; c = fooObj.boo; (apply (lambda (a b c) ...) (map (cute <> foo-obj) (list :bar :baz :boo))) This works equally well for bean fields. modifying several fields fooObj.bar = a; fooObj.baz = b; fooObj.boo = c; (for-each (cute <> foo-obj <>) (list :bar! :baz! :boo!) (list a b c)) This works equally well for bean fields. creating an array int[][] ar = new int[2][2]; (define ar (java-array-new <jint> '(2 2))) This works equally well for bean fields. accessing an array element int res = ar[1][1]; (define res (java-array-ref ar '(1 1))) modifying an array element ar[1][1] = val; (java-array-set! ar '(1 1) val) iterating over an array for(int i=0; i<ar.length; i++) ar[i].fooBar(a,b); (for-each (cute foo-bar <> a b) (->list ar)) implementing interfaces public class Foo implements Bar, Baz { private int x; private int y; public Foo(int x, int y) { this.x = x; this.y = y; } public int barMethod(int z) { return x+y+z; } public int bazMethod(int z) { return x+y-z; } } ... Foo fooObj = new Foo(1, 2); (define-java-proxy (foo x y) (<bar> <baz>) (define (bar-method p z) (->jint (+ x y (->number z)))) (define (baz-method p z) (->jint (+ x y (- (->number z)))))) ... (define foo-obj (foo 1 2))
Java Reflection Interface &requires; (import s2j) The S2J Reflection API lets Scheme code access all the core functions of the Java reflection API. It underpins the High Level S2J Interface (see ). Normal interaction with Java from Scheme does not require knowledge of this API, just like normal use of Java does not require knowledge of the Java reflection API. Classes These functions access attributes and members of classes.
java-class-name &procedure; symbol java-class-name jclass
Returns the name of jclass.
java-class-flags &procedure; list of symbols java-class-flags jclass
Returns the modifiers of jclass, for example public static final.
java-class-declaring-class &procedure; jclass java-class-declaring-class jclass
Returns the Java class in which jclass was declared, or null if it was declared at the top level.
java-class-declared-superclasses &procedure; list of jclass java-class-declared-superclasses jclass
Returns the direct superclasses of jclass. Normally this is the class' superclass followed by all of its interfaces in the order they were specified in the class declaration. There are a number of exceptions which ensure that the result is consistent with the precedence order employed by Java for method lookup on overloaded method. Interfaces and classes that directly inherit from java.lang.Object are all given java.lang.Object as the last element in their superclass list. For primitive and array types the direct superclass or superclasses reflect the widening conversions performed by Java. For example, <jint>'s superclass is <jlong> and <java.util.array-list[][]> 's superclasses are: <java.util.abstract-list[][]> <java.util.list[][]> <java.util.random-access[][]> <java.lang.cloneable[][]> <java.io.serializable[][]> Note that this behavior is different from the corresponding method in the Java reflection API.
java-class-declared-classes &procedure; list of jclasses/#f java-class-declared-classes jclass
Returns all the classes declared by jclass, or #f if access to this information is prohibited.
java-class-declared-constructors &procedure; list of jconstructor/#f java-class-declared-constructors jclass
Returns all the constructors declared by jclass, or #f if access to this information is prohibited.
java-class-declared-methods &procedure; list of jmethods/#f java-class-declared-methods jclass
Returns all the methods declared by jclass, or #f if access to this information is prohibited.
java-class-declared-fields &procedure; list of jfields/#f java-class-declared-fields jclass
Returns all the fields declared by jclass, or #f if access to this information is prohibited.
java-class-precedence-list &procedure; list of jclasses java-class-precedence-list jclass
Returns the total order of jclass and all direct and indirect superclasses, as determined by the partial orders obtained from calling java-class-declared-superclasses. The class precedence list is important when comparing types using the type system's compare-types procedure, which is used by the generic procedure method selection algorithm (see compare-methods in ). Since generic Java methods and field accessors/mutators are implemented in terms of generic procedures they are all affected by the class precedence list.
Constructors
java-constructor? &procedure; #t/#f java-constructor? value
Determines whether value is a Java constructor.
java-constructor-name &procedure; symbol java-constructor-name jconstructor
Returns the name of jconstructor.
java-constructor-flags &procedure; list of symbols java-constructor-flags jconstructor
Returns the modifiers of jconstructor , such as public static final.
java-constructor-declaring-class &procedure; jclass java-constructor-declaring-class jconstructor
Returns the Java class in which jconstructor was declared.
java-constructor-parameter-types &procedure; list of jclasses java-constructor-parameter-types jconstructor
Returns the declared types of the parameters of jconstructor.
java-constructor-procedure &procedure; procedure java-constructor-procedure jconstructor
Returns a procedure that when called invokes the constructor with the passed arguments, returning the newly created objected.
java-constructor-method &procedure; method java-constructor-method jconstructor
Returns a method suitable for adding to generic procedures that, when called invokes the underlying Java constructor with the passed arguments. The resulting newly created object is returned.
Methods
java-method? &procedure; #t/#f java-method? value
Determines whether value is a Java method.
java-method-name &procedure; symbol java-method-name jmethod
Returns the name of jmethod.
java-method-flags &procedure; list of symbols java-method-flags jmethod
Returns the modifiers of jmethod, such as public static final.
java-method-declaring-class &procedure; jclass java-method-declaring-class jmethod
Returns the Java class in which jmethod was declared.
java-method-parameter-types &procedure; list of jclasses java-method-parameter-types jmethod
Returns the declared types of the parameters of jmethod.
java-method-procedure &procedure; procedure java-method-procedure jmethod
Returns a procedure that when called invokes the method with the passed arguments, returning the newly created objected.
java-method-method &procedure; method java-method-method jmethod
Returns a method suitable for adding to generic procedures that, when called invokes the underlying Java method on the object passed as the first argument, and with the remaining arguments passed as parameters. The result of the method invocation is returned. Static methods can be invoked by passing a typed null object as the first parameter to the generic procedure.
Fields
java-field? &procedure; #t/#f java-field? value
Determines whether value is a Java field.
java-field-name &procedure; symbol java-field-name jfield
Returns the name of jfield.
java-field-flags &procedure; list of symbols java-field-flags jfield
Returns the modifiers of jfield, such as public static final.
java-field-declaring-class &procedure; jclass java-field-declaring-class jfield
Returns the Java class in which jfield was declared.
java-field-type &procedure; jclass java-field-type jfield
Returns the declared type of jfield.
java-field-accessor-procedure &procedure; procedure java-field-accessor-procedure jfield java-field-modifier-procedure &procedure; procedure java-field-modifier-procedure jfield
Returns a procedure that when called returns or sets (respectively) the value of the field on the object specified by the first parameter to the invocation. Static fields can be accessed/modified by passing a null object.
java-field-accessor-method &procedure; method java-field-accessor-method jfield java-field-modifier-method &procedure; method java-field-modifier-method jfield
Returns a method suitable for adding to generic procedures that, when called returns/sets the value of the field on the object specified by the first argument to the generic procedure invocation. Static fields can be accessed/modified by passing a typed null object as the first parameter to the generic procedure.
Arrays
java-array-class &procedure; jclass java-array-class jclass dimensions
Returns a class representing the array type that has jclass as the component type and dimensions as the number of dimensions. For example, the following expressions are equivalent: (java-array-class <jint> 2) (java-class '|int[][]|) The list of direct superclasses returned by java-class-declared-superclasses for an array class is consistent with the widening conversion performed by Java, e.g. the direct superclasses of java.util.ArrayList[][] are: java.util.AbstractList[][] java.util.List[][] java.util.RandomAccess[][] java.lang.Cloneable[][] java.io.Serializable[][] This is different from what the Java reflection APIs return.
Proxies
java-proxy-class &procedure; jclass java-proxy-class jinterface
Creates a Java class that implements the specified interfaces. The class can be instantiated with an invocation handler, such as the one returned by java-proxy-dispatcher below, that delegates method invocation to Scheme code.
java-proxy-dispatcher &procedure; invocation-handler java-proxy-dispatcher alist
Creates an invocation handler suitable for use in the instantiation of a proxy (see java-proxy-class above). The keys in alist are Java method names and the values are Scheme procedures. When a method is invoked on a proxy, the procedure matching the method's name is invoked with the proxy object and the parameters of the method invocation as arguments. The result of the invocation is returned as the result of the method call. If alist does not contain a binding for the method name, an error is signalled.
sisc-1.16.6.orig/doc/lazycont.lyx0000644000175000017500000001570511445752462015321 0ustar amoeamoe#LyX 1.2 created this file. For more info see http://www.lyx.org/ \lyxformat 220 \textclass esub2acm \language english \inputencoding auto \fontscheme default \graphics default \paperfontsize default \spacing single \papersize Default \paperpackage a4 \use_geometry 0 \use_amsmath 0 \use_natbib 0 \use_numerical_citations 0 \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \quotes_times 2 \papercolumns 1 \papersides 1 \paperpagestyle default \layout Title Title Here \layout Author Scott G. Miller and Matthias Radestock \layout Abstract We discuss a mechanism for continuation capture in a heap-based Scheme interpret er which minimizes effort required by the interpreter for capturing the continuation, delaying the protection of call-frames until an operation in the interpreter threatens the isolation of the captured continuation. \layout Section* Introduction \layout Subsection* Continuations are Great \layout Standard A quick intro to continuations - what they are - why they are useful \layout Subsection* Continuations are Hard \layout Standard Key implementation issues (brief description of implementation issues and techniques for different types of continuations) - escape-only: easy - one-shot: harder - full: where the fun really begins \layout Standard This should set the scene, i.e. define the problem we are trying to address. \layout Subsection* Outline of Our Approach \layout Standard Setting: briefly describe the kind of system in which our technique is applicabl e Contrast: Briefly describe the naive approach Technique: briefly describe the key aspects of our technique \layout Section* \layout Subsection* Interpreter Architecture \layout Standard The \emph on SISC \emph default Scheme interpreter, on which the technique was developed, is a heap-based interpreter, that is, it uses the system heap rather than stack to manage control context. The decision to use a heap-based model was driven primarily by the Java Virtual Machine's lack of stack-manipulation operations. Without them, it is impossible to implement full continuations with control context managed by the JVM stack. \begin_inset Foot collapsed true \layout Standard Continuations could be implemented by performing a CPS transformation on Scheme source code and running that on a stack based system, however. \end_inset In addition, proper tail recursion comes naturally as a side-effect of this model, requiring no tail-recursion creating mechanisms like trampolining. \layout Standard The heap-based model consists of an engine with at least five registers and a datastructure called a Call Frame. The five registers contain all the execution state of a running Scheme program: \layout List \labelwidthstring 00.00.0000 \noun on acc \noun default The Accumulator register. This register holds the results of a previous expression for consumption by the next expression. \layout List \labelwidthstring 00.00.0000 \noun on nxp \noun default The Next Expression register. If the register is not empty, the \begin_inset Formula $\mu $ \end_inset -expression it contains is executed next. \layout List \labelwidthstring 00.00.0000 \noun on env \noun default The Lexical Environment register. This points to the topmost rib in a ribcage of lexical bindings. \layout List \labelwidthstring 00.00.0000 \noun on vlr \noun default The Value Rib register. This register contains the values of operands to a function application. \layout List \labelwidthstring 00.00.0000 \noun on stk \noun default The Stack register. This register points to the topmost call-frame. \layout Standard A Call Frame simply contains fields for each of the five registers except \noun on acc \noun default . \layout Standard A heap-based interpreter first simplifies a Scheme program (through syntax-expan sion) into several \emph on core forms \emph default : Applications, Lexical Variable References/Stores, Free Variable References/Bin dings/Stores, and the primitive special expressions: \noun on lambda, begin, if \noun default . It then translates the simplified Scheme program into an abstract syntax tree and then finally into an executable micro-expression ( \begin_inset Formula $\mu $ \end_inset -expression). \layout Standard To evaluate the \begin_inset Formula $\mu $ \end_inset -expression, it stores the \begin_inset Formula $\mu $ \end_inset -expression in the \noun on nxp, \noun default clears the other registers if necessary, and begins the following pseudocode loop: \layout Quote Loop: If \noun on nxp \noun default contains no \begin_inset Formula $\mu $ \end_inset -expression \layout Quote \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ If \noun on stk \noun default is non-empty \layout Quote \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \noun on stk \begin_inset Formula $\rightarrow $ \end_inset \noun default Registers \layout Quote \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ Loop \layout Quote \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ Else \layout Quote \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ Return \noun on acc \layout Quote \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ Else \layout Quote \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ Execute \noun on nxp \layout Quote \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ \SpecialChar ~ Loop \layout Standard - briefly describe enough about the SISC interpreter in order to understand our technique - Rationale behind a heap-based interpreter - try to generalize to other interpreters / languages - describe how the interpreter executes non-k code - representation of a k in SISC: it's basically a stack of call frames \layout Subsection* Continuation Capture \layout Standard - what we do when a continuation is captured - special callframe fields \layout Subsection* Continuation Invocation \layout Standard - what we do when a continuation is invoked \layout Section* Performance \layout Standard - best case, worst case, typical case scenarios - measurements of the above - comparison with other Schemes \layout Section* Related Work \layout Standard - mostly in other Schemes but for ICFP we need to look at others languages too \layout Section* Conclusion \layout Bibliography \bibitem {key-3} Dybvig, R. Kent, Three Implementation Models for Scheme \the_end sisc-1.16.6.orig/doc/s2j.txt0000644000175000017500000006753111445752462014163 0ustar amoeamoeScheme-to-Java-FFI ================== S2J allows Scheme code to instantiate Java classes, call methods on Java objects, access/modify fields of Java objects and implement Java interfaces that delegate to Scheme code. High Level API ============== Classes ------- Java classes are types in SISC's extensible type system. They are made accessible to Scheme code by one of the following procedures / special forms: JAVA-CLASS -> Returns the Java class of name , a symbol. can also be the name of a primitive type or an array type (i.e. having trailing pairs of brackets). DEFINE-JAVA-CLASS [] Binds to the Java class named by , or if no such parameter is supplied, by the mangled . DEFINE-JAVA-CLASSES [ | ( )] ... Creates bindings for several Java classes. This form expands into several DEFINE-JAVA-CLASS forms. Mangling of class names checks for the presence of angle brackets around the . If they are present they are stripped. All the identifiers between the dots are passed through field name mangling (see below). The character following the last dot is upcased. A slash ('/') is treated as a nested class indicator; it is replaced with '$' and the character following it is upcased. Trailing '*' characters are replaced with pairs of brackets ("[]"). Trailing brackets are preserved. In essence, the mangling allows classes to be identified more schemely, e.g. corresponds to the Java type java.io.ObjectInputStream.GetField[][] (note that GetField is a nested class). There are predicates for determining whether a Scheme value is a Java class or interface. All Java interfaces are also Java classes. JAVA-CLASS? => #t/#f Determines whether is a Java class. JAVA-INTERFACE? => #t/#f Determines whether is a Java interface. All interfaces are also Java classes. Methods ------- Java methods are made accessible to Scheme code as procedures that can invoke any method of a given name on any Java object. Method selection is performed based on the types of the arguments to the procedure call. Static Java methods can be invoked by passing a typed null object (see JAVA-NULL) as the first argument to the procedures. GENERIC-JAVA-METHOD => Returns a procedure that when invoked with a java object as the first argument and java values as the remaining arguments, invokes the best matching named method on the java object and returns the result. DEFINE-GENERIC-JAVA-METHOD [] Binds to the Java method named by , or if no such parameter is supplied, by the mangled . DEFINE-GENERIC-JAVA-METHODS [ | ( )] ... Creates bindings for several Java methods. This form expands into several DEFINE-GENERIC-JAVA-METHOD forms. Mangling of method names removes trailing '!' characters and replaces trailing '?' characters with a leading "is-". The result of the mangling is passed through field mangling (see below). In essence, the mangling allows methods to be identified more schemely, e.g. empty-list? corresponds to the Java method name isEmptyList. Fields ------ Fields are made accessible to Scheme code as procedures that can get/set any field of a given name on any Java object. If several fields of the same name are present in the object due to the object class's inheritance chain, the most specific field, i.e. the one bottommost in the inheritance hierarchy, is selected. Static fields can be accessed by passing a typed null object (see JAVA-NULL) as the first argument to the procedures. GENERIC-JAVA-FIELD-ACCESSOR GENERIC-JAVA-FIELD-MODIFIER Returns a procedure that when invoked with a java object as the first argument (and in case of JAVA-FIELD-MODIFIER a java value as the second argument) retrieves / sets the value of the field on the object. DEFINE-GENERIC-JAVA-FIELD-ACCESSOR [] DEFINE-GENERIC-JAVA-FIELD-MODIFIER [] Binds to the accessor/modifier for the Java field named by , or if no such parameter is supplied, by the mangled . DEFINE-GENERIC-JAVA-FIELD-ACCESSORS [ | ( )] ... DEFINE-GENERIC-JAVA-FIELD-MODIFIERS [ | ( )] ... Creates bindings for several Java field accessors/modifiers. This form expands into several DEFINE-GENERIC-JAVA-FIELD-{ACCESSOR/MODIFIER} forms. Mangling of field names upcases any character following a dash ('-') and removes all characters that are not legal as part of Java identifiers. In essence, the mangling allows fields to be identified more schemely. By convention field accessors should be named with a leading ':' followed by the field name and field modifiers should be named with a leading ':' followed by the field name followed by '!', e.g. :foo-bar, :foo-bar! Instances --------- Scheme code can instantiate Java classes with a call to the following procedure: JAVA-NEW ... -> Selects & calls a constructor of , returning the newly created object. Constructor selection is performed based on the types of the arguments. There is a predicate for determining whether a value is a Java object: JAVA-OBJECT? => #t/#f Determines whether is a Java object. Unlike in Java, null objects are typed. Typed null objects play a key role in invoking static methods an accessing/modifying static fields. JAVA-NULL -> Returns a Java null object of type . Typed null objects can be used to invoke static methods and access/modify static fields. Any invocation of a Java method, or access to a Java fields that returns a Java null does so typed based on the declared return/field type. For convenience, JNULL is bound to the typed null object obtained by calling JAVA-NULL on java.lang.Object. There is a predicate for determining whether a value is a Java null object: JAVA-NULL? => #t/#f Determines whether is a Java null. Nulls Java objects. Arrays ------ Scheme code can create Java arrays using the following procedure: JAVA-ARRAY-NEW => Creates an array of component type with dimensions . can be a number (for a single-dimensional array), or a vector/list of numbers (for multi-dimensional arrays). There is a predicate for determining whether a value is a Java array. All Java arrays are also Java objects. JAVA-ARRAY? => #t/#f Determines whether is an array. Elements of the array are accessed and modified with: JAVA-ARRAY-REF => Returns the element at index of . can be a number, for indexing into the first dimension of the array, or vector/list of numbers for multi-dimensional indexing. JAVA-ARRAY-SET! Sets the element at index of to . can be a number, for indexing into the first dimension of the array, or vector/list of numbers for multi-dimensional indexing. The length of a Java array is determined with: JAVA-ARRAY-LENGTH => Returns the length of the array. Scheme vectors and lists can be converted to Java array and vice versa: ->JARRAY => Creates a one-dimensional array of type and fills it with the values obtained from the Scheme vector or list. ->VECTOR => ->LIST => Creates a vector/list containing the elements of . Proxies ------- Scheme code cannot create sub-classes of existing Java classes. It is, however, possible to create classes implementing existing Java interfaces. These classes are called proxies. Calling a method on a proxy invokes a user-definable Scheme procedure, based on the name of the method, passing the proxy object and the parameters of the method invocation as arguments. The result of the invocation is returned as the result of the method call. DEFINE-JAVA-PROXY ( . ) ( ...) [(define ) | (define ( . ) . )] ... Creates a proxy generator procedure and binds it to . The proxy generator creates a proxy class that implements . When the generator is invoked, JAVA-PROXY-DISPATCHER is used to create a proxy invocation handler from the procedures defined in definition list. The result of this is then passed to the constructor of the proxy class. The newly created proxy instance is returned. The first kind of definition form defines to be the method handler for the java method named . undergoes method name mangling (see DEFINE-GENERIC-JAVA-METHOD). Note that is inside the lexical scope of the generator procedure, so are accessible inside it. The second kind of definition form is equivalent to the following first-type form: (define (lambda . )) If a method is invoked on a proxy for which no method handler exists and error is returned to the caller. Primitive Types and Conversions ------------------------------- For convenience, all the primitive Java types, i.e. void, boolean, double, float, long, int, short, byte, char, are predefined and bound to , e.g. . When calling Java methods, invoking Java constructors, accessing or modifying Java fields, no automatic conversion is performed between ordinary Scheme values and Java values. Instead explicit conversion of arguments and results is required. Conversion functions are provided for converting between primitive Java types and standard Scheme types. These functions are consistently named ->j and ->, e.g. ->jint, ->number. There are also conversion functions for Java strings. ->JSTRING => Converts the Scheme string or symbol to a Java string. ->SYMBOL => ->STRING => Converts to a Scheme symbol / string. Scheme values are not Java objects and hence cannot be passed as arguments in Java method or constructor invocations or when setting Java fields. However, all Scheme values are *internally* represented by instances of classes in the SISC runtime. S2J provides a mechanism to get hold of this internal representation as an S2J Java object. The converse operation is also supported - a Java instance obtained via a Java method or constructor invocation or field access in S2J can be turned into a Scheme value if it is an instance of an appropriate SISC runtime class. These two operations are called "wrapping" and "unwrapping" respectively because conceptually the scheme object is wrapped to make it appear like a Java object and the wrapper is removed in order to recover the original Scheme object. JAVA-WRAP => Returns the Java object that represents the Scheme in SISC's runtime. JAVA-UNWRAP => Returns the Scheme value represented by the . If is not an object representing a Scheme value in SISC's runtime and error is thrown. Wrapping and unwrapping allow Scheme values to be used in generic (i.e. not type-specific) Java operations, such as those of the Java collection API. It is also frequently used in connection with proxies when Scheme objects are passed back and forth through layers of Java to a Scheme-implemented proxy that manipulates them. Finally, wrapping and unwrapping permit SISC Scheme code to interface to the SISC runtime. Threading --------- In Java each object is a potential thread synchronization point. Therefore Scheme code needs to be able to synchronize on Java objects in order for it to interoperate properly with Java in a multi-threaded application. This is accomplished by the following procedure: JAVA-SYNCHRONIZED => Runs in a block synchronized on , returning the result returned by . This is the equivalent to: synchronized (obj) { .... } in Java. It is illegal for to invoke continuations that escape , or for code outside to invoke a continuation captured inside . Access Permissions ------------------ Invoking [DEFINE-]JAVA-CLASS[ES], JAVA-NEW or any of the procedures defined with [DEFINE]-GENERIC-JAVA-{METHOD,FIELD-ACCESSOR,FIELD-MODIFIER}[S] causes the Scheme-to-Java FFI to perform reflection on the named Java class(es), the class passed as the first argument, or the class corresponding to the type first argument passed to the other procedures, respectively. This process collects information about all the constructors, methods and fields of the class and it's superclasses/interfaces. The only class members processed during this automatic reflection are public ones declared in public classes. This almost exactly mimics the visibility rules in Java for code residing in packages other than the one the member is residing in. It is also in line with the default permissions granted to the Java reflection API. There is one rare case where this rule is more restrictive than Java's: public members of package-protected classes are not visible even when accessed via a public sub-class. Depending on the security settings, the Java reflection API is in fact capable of granting access to *any* members of *any* class. However, using this in the automatic reflection performed by s2j would constitute a significant departure from normal Java behaviour and result in unpredictable results to the user. For instance, undocumented private methods would be invoked in preference to documented public methods if the formers type signature provided a better match. Automatic reflection ignores security exceptions thrown by the Java reflection API, i.e. the class in question will appear to have no constructors, methods and fields. This is designed to cope with situations where the default security settings have been altered in a way that prevents access to members of some (or even all) classes. In some applications the reflection API permissions depend on the context of the invocation. For instance, in applets it is usually possible to access class member information as part of the initialisation but not after that. Since [DEFINE-]JAVA-CLASS[ES] triggers automatic reflection, it can be used to control when automatic reflection for specific classes takes place. Common Usage Summary -------------------- This section provides a summary of all the commonly used S2J features, correlating them with the corresponding Java code. Some of the following examples require FOLD from srfi-1 and CUT and CUTE from srfi-26, and COMPOSE from the misc module. Create bindings for classes, methods and fields: Java: n/a Scheme: (define-java-classes ) (define-generic-java-methods get-bar get-baz set-bar! set-baz!) (define-generic-java-field-accessors :bar :baz) (define-generic-java-field-modifiers :bar! :baz!) Instantiate class: Java: foo.BarBaz fooObj = new foo.BarBaz(a, b, c); Scheme: (define foo-obj (java-new a b c)) Invoke method on instance: Java: Object res = fooObj.barBaz(a, b, c) Scheme: (define res (bar-baz foo-obj a b c)) Access field: Java: Object res = fooObj.bar; Scheme: (define res (:bar foo-obj)) Modify field: Java: fooObj.bar = val; Scheme: (:bar! foo-obj val) Chained field access: Java: Object res = fooObj.bar.baz.boo Scheme: (define res (fold (cut <> <>) foo-obj (list :bar :baz :boo))) or (define res ((compose :boo :baz :bar) foo-obj)) NB: this works equally well for bean fields. Chained field modification: Java: fooObj.bar.baz.boo = moo; Scheme: (:boo! (fold (cut <> <>) foo-obj (list :bar :baz)) moo) or (:boo! ((compose :baz :bar) foo-obj) moo) NB: this works equally well for bean fields. Accessing several fields: Java: a = fooObj.bar; b = fooObj.baz; c = fooObj.boo; Scheme: (apply (lambda (a b c) ...) (map (cute <> foo-obj) (list :bar :baz :boo))) NB: this works equally well for bean fields. Modifying several fields: Java: fooObj.bar = a; fooObj.baz = b; fooObj.boo = c; Scheme: (for-each (cute <> foo-obj <>) (list :bar! :baz! :boo!) (list a b c)) NB: this works equally well for bean fields. Creating an array: Java: int[][] ar = new int[2][2]; Scheme: (define ar (java-array-new '(2 2))) Accessing an array element: Java: int res = ar[1][1]; Scheme: (define res (java-array-ref ar '(1 1))) Modifying an array element: Java: ar[1][1] = val; Scheme: (java-array-set! ar '(1 1) val) Calling a method on all elements of an array: Java: for(int i=0; i a b) (->list ar)) Implementing interfaces: Java: public class Foo implements Bar, Baz { private int x; private int y; public Foo(int x, int y) { this.x = x; this.y = y; } public int barMethod(int z) { return x+y+z; } public int bazMethod(int z) { return x+y-z; } } ... Foo fooObj = new Foo(1, 2); Scheme: (define-java-proxy (foo x y) ( ) (define (bar-method p z) (->jint (+ x y (->number z)))) (define (baz-method p z) (->jint (+ x y (- (->number z)))))) ... (define foo-obj (foo 1 2)) Reflection API ============== There are Scheme procedures covering the full spectrum of Java's class reflection capability. Normal use of S2J does not require knowledge of these procedures, just like normal use of Java does not require knowledge of the Java reflection API. Classes ------- JAVA-CLASS-NAME => Returns the name of . JAVA-CLASS-FLAGS => (list ) Returns the modifiers of , e.g. public static final; JAVA-CLASS-DECLARING-CLASS => Returns the Java class in which was declared, or null if it was declared at the top-level. JAVA-CLASS-DECLARED-SUPERCLASSES -> (list ) Returns the direct superclasses of . For ordinary classes this is the class' superclass followed by all its interfaces in the order they were specified in the class declaration. For primitive types and array types, the direct superclass(es) reflect the widening conversions performed by Java e.g. 's superclass is and 's superclasses are: ) Note that this behaviour is different from the corresponding method in the Java reflection API. JAVA-CLASS-DECLARED-CLASSES => (list )/#f Returns all the classes declared by , or #f if access to this information is prohibited. JAVA-CLASS-DECLARED-CONSTRUCTORS => (list )/#f Returns all the constructors declared by , or #f if access to this information is prohibited. JAVA-CLASS-DECLARED-METHODS => (list )/#f Returns all the methods declared by , or #f if access to this information is prohibited. JAVA-CLASS-DECLARED-FIELDS -> (list )/#f Returns all the fields declared by , or #f if access to this information is prohibited. JAVA-CLASS-PRECEDENCE-LIST -> (list ) Returns the total order of and all direct & indirect superclasses, as determined by the partial orders obtained from calling JAVA-CLASS-DECLARED-SUPERCLASSES. The ordering of classes returned by JAVA-CLASS-DECLARED-SUPERCLASSES is considered "weak" whereas the ordering of the class itself with respect to its direct superclasses is considered strong. The significance of this is that when computing the class precedence list weak orderings are re-arranged if that is the only way to obtain a total order. By contrast, strong orderings are never rearranged. The class precedence list is important when comparing types using the type system's COMPARE-TYPES procedure, which is used by the generic procedure method selection algorithm. See COMPARE-METHODS. Since generic Java methods and field accessors/mutators are implemented in terms of generic procedures they are all affected by the class precedence list. Constructors ------------ JAVA-CONSTRUCTOR? => #t/#f Determines whether is a Java constructor. JAVA-CONSTRUCTOR-NAME => Returns the name of . JAVA-CONSTRUCTOR-FLAGS => (list ) Returns the modifiers of , e.g. public static final; JAVA-CONSTRUCTOR-DECLARING-CLASS => Returns the Java class in which was declared. JAVA-CONSTRUCTOR-PARAMETER-TYPES => (list ) Returns the declared types of the parameters of . JAVA-CONSTRUCTOR-PROCEDURE => Returns a procedure that when called invokes the constructor with the passed arguments, returning the newly created object. JAVA-CONSTRUCTOR-METHOD => Returns a method suitable for adding to generic procedures that, when called invokes the underlying Java constructor with the passed arguments. The resulting newly created object is returned. Methods ------- JAVA-METHOD? => #t/#f Determines whether is a Java method. JAVA-METHOD-NAME => Returns the name of . JAVA-METHOD-FLAGS => (list ) Returns the modifiers of , e.g. public static final; JAVA-METHOD-DECLARING-CLASS => Returns the Java class in which was declared. JAVA-METHOD-PARAMETER-TYPES => (list ) Returns the declared types of the parameters of . JAVA-METHOD-RETURN-TYPE => Returns the declared return type of . JAVA-METHOD-PROCEDURE => Returns a procedure that when called invokes the method on the object passed as the first argument, with the remaining arguments passed as the parameters. The result of the method invocation is returned the result of the method invocation. Static methods can be invoked by passing a null object as the first parameter. JAVA-METHOD-METHOD => Returns a method suitable for adding to generic procedures that, when called invokes the underlying Java method on the object passed as the first argument, with the remaining arguments passed as parameters. The result of the method invocation is returned. Static methods can be invoked by passing a typed null object as the first parameter to the generic procedure. Fields ------ JAVA-FIELD? => #t/#f Determines whether is a Java field. JAVA-FIELD-NAME => Returns the name of . JAVA-FIELD-FLAGS => (list ) Returns the modifiers of , e.g. public static final; JAVA-FIELD-DECLARING-CLASS => Returns the Java class in which was declared. JAVA-FIELD-TYPE => Returns the declared type of . JAVA-FIELD-ACCESSOR-PROCEDURE => JAVA-FIELD-MODIFIER-PROCEDURE => Returns a procedure that when called returns/sets the value of the field on the object specified by the first parameter to the invocation. Static fields can be accessed/modified by passing a null object. JAVA-FIELD-ACCESSOR-METHOD => JAVA-FIELD-MODIFIER-METHOD => Returns a method suitable for adding to generic procedures that, when called returns/sets the value of the field on the object specified by the first argument to the generic procedure invocation. Static fields can be accessed/modified by passing a typed null object as the first parameter to the generic procedure. Arrays ------ JAVA-ARRAY-CLASS => Returns a class representing the array type that has as the component type and as the number of dimensions, e.g. (java-array-class 2) is the same as (java-class '|int[][]|) The list of direct superclasses returned by JAVA-CLASS-DECLARED-SUPERCLASSES for an array class is consistent with the widening conversions performed by Java, e.g. the direct superclasses of java.util.ArrayList[][] are java.util.AbstractList[][] java.util.List[][] java.util.RandomAccess[][] java.lang.Cloneable[][] java.io.Serializable[][] This is different from what the Java reflection APIs returns. Proxies ------- JAVA-PROXY-CLASS ... => Creates a Java class that implements the specified interfaces. The class can be instantiated with an invocation handler, such as the one returned by JAVA-PROXY-DISPATCHER below, that delegates method invocation to Scheme code. JAVA-PROXY-DISPATCHER => Creates an invocation handler suitable for use in the instantiation of a proxy (see JAVA-PROXY-CLASS). The keys in are Java method names and the values are Scheme procedures. When a method is invoked on a proxy, the procedure matching method's name is invoked with the proxy object and the parameters of the method invocation as arguments. The result of the invocation is returned as the result of the method call. If does not contain a binding for the method name, an error is returned. What's Changed? =============== The major changes in the Scheme-to-Java FFI since the previous version are as follows: * The code and module have been disentangled from that of the type system, object system and generic procedures. * The new extensible type system is used for all type-related operations. * Java objects are no longer procedures. [ATM they still are in order to ease the transition]. This is a more schemely approach but means that certain concise patterns for accessing fields no longer work. However, there are nearly as concise replacements for these patterns using standard functional programming techniques. See Common Usage above. * Java fields are accessed and modified via procedures obtained through GENERIC-JAVA-FIELD-{ACCESSOR,MODIFIER} and DEFINE-GENERIC-JAVA-FIELD-{ACCESSOR,MODIFIER}[S]. Static fields can be accessed/modified by calling the procedures on instances of the field's class or on typed null object obtained from JAVA-NULL. * Java methods are invoked via procedures obtained through GENERIC-JAVA-METHOD and DEFINE-GENERIC-JAVA-METHOD[S]. Static methods can be invoked by calling the procedures on instances of the method's class or with a typed null object obtained from JAVA-NULL. * Java arrays are accessed and modified via the new JAVA-ARRAY-{REF,SET!} procedures. * The class-precedence lists of primitive and array types is now consistent with Java's widening conversion. This is important for disambiguating method invocation and avoiding unnecessary conversions. * The new DEFINE-JAVA-CLASS[ES], DEFINE-GENERIC-JAVA-METHOD[S], and DEFINE-GENERIC-JAVA-FIELD-{ACCESSOR,MODIFIER}[S] forms provide a concise syntax for the creation of bindings with schemely names for classes, methods and field accessors/modifiers. * The generic procedures which implement method selection are no longer accessible. That is because they are an implementation detail that should not be exposed in the API and furthermore some of the generic procedure operations were returning misleading results due to the dynamic reflection of methods. * Mangling (i.e. turning schemely identifiers into Java identifiers) of field and method names has been improved and there is now also support for mangling class names. * Most of the Java reflection API is exported as Scheme functions. * The generic conversion procedure -> no longer exists since it relied on meta typing, which the new type system does not support. The specific conversion procedures should be used instead. sisc-1.16.6.orig/doc/SchemeHelloWorld.java0000644000175000017500000000145711445752462016762 0ustar amoeamoeimport sisc.interpreter.*; import java.io.IOException; /** * An example program demonstrating calling into SISC, assuming * the classpath and SISC_HOME point to the appropriate SISC jars * and the heap, respectively. */ public class SchemeHelloWorld { public static void main(String[] args) throws SchemeException { Context.execute(new SchemeCaller() { public Object execute(Interpreter r) throws SchemeException { try { return r.eval("(begin (display \"Hello, World!\") (newline))"); } catch (IOException e) { // Thrown if the given Scheme program cannot be parsed return null; } } }); } } sisc-1.16.6.orig/doc/man/0000755000175000017500000000000011445752462013463 5ustar amoeamoesisc-1.16.6.orig/doc/man/sisc.10000644000175000017500000000545011445752462014512 0ustar amoeamoe.\" dummy line .TH SISC 1 "June 2005" .UC 4 .SH NAME sisc \- Second Interpreter of Scheme Code .SH SYNOPSIS .B sisc [ .I option ... ] [ .I argument ... [ -- [ program-option ... ] ] .SH DESCRIPTION .I SISC, the Second Interpreter of Scheme Code, is an extensible Java based interpreter of the Scheme language as described in the .I Revised^5 Report on .I the Algorithmic Language Scheme and adds numerous extensions including Java integration. .SH STARTUP FILE AND EXPRESSION OPTIONS .TP .BI \-c \ name .TP .BI \--call-with-args \ name Calls the top-level procedure .I name with the remaining command-line arguments after the .I -- delimiter. .TP .BI \-e \ expr .TP .BI \--eval \ expr Evaluates the provided expression. .TP .BI \-x .TP .BI \--no-repl Instructs .I SISC to run the command line and then exit without entering the REPL. .TP .BI \-h \ heap-file .TP .BI \--heap \ heap-file Specifies that .I heap-file should be used as the initial heap image. .TP .BI \-p \ config-file .TP .BI \--properties \ config-file Specifies a Java property file that contains application properties. .TP .BI \-l \ [:] .TP .BI \--listen \ [:] Server Mode. Listen on / for REPL connections. .PP .SH COMMAND LINE BEHAVIOR The commandline is processed in the following manner. First, the entire command line is processed, noting the settings of each switch and accumulating all Scheme source files and arguments after the end of options sequence. Second, the heap file is loaded. Third, each Scheme source file is loaded in the order they occured on the command line. Errors are noted. Fourth, if present, the expression in an --eval switch is evaluated. Errors are noted. Fifth, if present, named function in a --call-with-args switch is applied to the arguments after the end of options sequence. Its return value is noted. Sixth, --no-repl was not specified, the REPL is invoked. Finally, if the REPL was run if its return value is an integer, that integer is returned as SISC's overall return code. If the REPL was not run, and any return code supporting step above was run, the most recent return code is returned. If no return code step was performed, but a success/failure step was performed, 1 is returned if any failures occured, 0 otherwise. .SH EXECUTABLE SCRIPTS SISC supports all the required SRFI-22 bootstraps, consult the body of SRFI-22 for more information about using it to write executable Scheme programs. .PD .SH MORE INFORMATION For further information on SISC, please read the .I SISC for Seasoned Schemers manual available at .PP .ce 1 http://sisc.sourceforge.net/manual/ .SH BUGS Submit bug reports to the SISC Users Mailing List. .SH AUTHOR .I SISC was created by Scott G. Miller (sgmiller@gmail.com) with significant contribution from Matthias Radestock (matthias@sorted.org). sisc-1.16.6.orig/doc/generic-procedures.txt0000644000175000017500000002530211445752462017240 0ustar amoeamoeGeneric Procedures ================== Generic procedures are procedures that select & execute methods based on the types of the arguments to the generic procedure invocation. Methods have a type signature, which generic procedures use for method selection, and contain a procedure which is invoked by generic procedures when the method has been selected for execution. Methods ------- Methods are records of type . MAKE-METHOD => Creates a new method containing procedure whose type signature is . If is #t then the procedure can take rest arguments. Generic procedures always invoke methods with a special "next:" argument as the first parameter, followed by all the arguments of the generic procedure invocation. For more details on the next: parameter see below. METHOD? => #t/#f Determines whether is a method. METHOD-PROCEDURE => Returns the procedure associated with METHOD-TYPES => Returns the type signature of METHOD-REST? => #t/#f Determines whether has a rest parameter. METHOD-ARITY => Determines the number of mandatory arguments to the method. Note that the special "next:" argument is not counted in this. METHOD= => #t/#f Determines whether two methods have identical signatures, i.e. have equal types (as determined by the TYPES= procedure) and rest parameter flag. METHOD-APPLICABLE? => #t/#f Determines whether is applicable to arguments of types . For this procedure to return #t the following conditions must be met: * If the method accepts rest arguments then must contain at least as many elements as the 's type signature. * If the method does not accepts rest arguments then must contain exactly as many elements as the 's type signature. * All the types in the method's signature must be supertypes of the corresponding types in . This comparison is performed using the TYPES<= procedure. COMPARE-METHODS => equal, more-specific, less-specific Determines the relationship of two methods by comparing their type signatures against each other and using the supplied for disambiguation. must be applicable (as determined by METHOD-APPLICABLE?) to both and . The result is computed by a triple-wise comparison on successive elements of the method signatures and , using the COMPARE-TYPES procedure: * If we run out of elements in both method signatures then - if both or neither method return rest arguments then we return 'equal - if takes rest arguments then we return 'less-specific - if takes rest arguments then we return 'more-specific * If we run out of elements in 's signature only then we return 'less-specific. * If we run out of elements in 's signature only then we return 'more-specific. * If COMPARE-TYPES returns 'equal we proceed to the next triple. * If COMPARE-TYPES returns 'less-specific we return 'less-specific. * If COMPARE-TYPES returns 'more-specific we return 'more-specific. Informally, the above performs a left-to-right match, returning the result of the type comparison at the point of the first discernible difference. METHOD ([(next: ?next)] ( ?arg) ... [. ?rest]) . ?body => Creates a method. This syntactic form is similar to the LAMBDA form, except that all parameters must be typed and that an optional leading special "next:" parameter can be present. Procedures ---------- Generic procedures are invoked like ordinary procedures. They contain a list of methods from which the method that is most applicable to the arguments is selected and invoked. MAKE-GENERIC-PROCEDURE [ ...] => Creates a generic procedure. If s are specified then their method lists are combined, in effect merging the generic procedures into one. The typical scenario for using method list merging is when several modules have defined generic functions (and procedures using these functions) that perform identical operations but on different data types. Method list merging allows the generic procedures to be combined, covering the combination of data types, and extended. Furthermore, the coverage of the dependent procedures is implicitly extended to the combined set of data types. GENERIC-PROCEDURE-METHODS => Returns the list of methods currently contained in . ADD-METHOD Adds to . Any existing method with the same signature as is removed. Method addition is thread-safe. ADD-METHODS Adds to . This is more efficient than calling ADD-METHOD on each individual method. APPLICABLE-METHODS => Returns all methods of that are applicable, as determined by METHOD-APPLICABLE?, to . The result is computed by pair-wise method comparison using COMPARE-METHODS. The applicable methods are ordered by their specificity. Syntax ------ DEFINE-GENERIC ?name [ ...] Creates a binding for ?name to a new generic procedure. This form is equivalent to DEFINE ?name (MAKE-GENERIC-PROCEDURE ...) DEFINE-GENERICS [?name | (?name ...)] ... Creates bindings for several new generic procedures. This form expands into several DEFINE-GENERIC forms. DEFINE-METHOD ( . ?signature) . ?body Creates a method and adds it to . This form is equivalent to ADD-METHOD (METHOD ?signature . ?body) DEFINE-METHODS (?signature . ?body) ... Creates several methods and adds them to . This form is equivalent to ADD-METHODS (LIST (METHOD ?signature . ?body) ...) "next:" method parameter ------------------------ The METHOD form and derived forms (e.g. DEFINE-METHOD and DEFINE-METHODS), permit the specification of a special first parameter to the method invocation. When a generic procedure invokes a method, this parameter is bound to a procedure that when called will invoke the "next best matching" method. This is the next method in the list of applicable methods returned by APPLICABLE-METHODS when it was called by the generic procedure upon invocation. If no "next best matching" method exists, i.e. the current method is the last in the list, then the next parameter is #f. This allows methods to invoke the next best matching method selectively depending on whether it is present. This is an important feature since the dynamic nature of method selection makes it impossible to determine at the time of writing the method whether there is going to be a next best matching method. The next best matching method must be invoked with arguments to which the current method is applicable. Examples -------- Method selection, rest arguments, next: parameter: (define-generic m) (define-methods m [((next: next) ( x) ( y) ( z) . rest) (cons 'a (if next (apply next x y z rest) '()))] [((next: next) ( x) ( y) ( z)) (cons 'b (if next (next x y z) '()))] [((next: next) ( x) ( y) . rest) (cons 'c (if next (apply next x y rest) '()))] [((next: next) ( x) ( y) ( z)) (cons 'd (if next (next x y z) '()))]) (m 1 1 1) ;=> '(d c b a) (m 1 1) ;=> '(c) (m 1 'x 2) ;=> '(b a) (m 1 1 'x) ;=> '(d c) (m 1 'x 'x) ;=> error Method list merging: (import* misc compose) (module foo (p-append p-reverse-append) (define (p-reverse-append . args) (apply p-append (reverse args))) (define-generic p-append) (define-methods p-append [(( x) . rest) (apply append x rest)] [(( x) . rest) (list->vector (apply append (vector->list x) (map vector->list rest)))])) (module bar (p-append p-repeat) (define (p-repeat n x) (let loop ([res '()] [n n]) (if (= n 0) (apply p-append res) (loop (cons x res) (- n 1))))) (define-generic p-append) (define-methods p-append [(( x) . rest) (apply string-append x rest)] [(( x) . rest) (string->symbol (apply string-append (symbol->string x) (map symbol->string rest)))])) (import* foo (p-append1 p-append) p-reverse-append) (import* bar (p-append2 p-append) p-repeat) (define-generic p-append p-append1 p-append2) (define-method (p-append ( x) . rest) (apply compose x rest)) (p-append '(a b)) ;=> '(a b) (p-append '(a b) '(c d) '(e f)) ;=> '(a b c d e f) (p-append '#(a b)) ;=> '#(a b) (p-append '#(a b) '#(c d) '#(e f)) ;=> '#(a b c d e f) (p-append "ab") ;=> "ab" (p-append "ab" "cd" "ef") ;=> "abcdef" (p-append 'ab) ;=> 'ab (p-append 'ab 'cd 'ef) ;=> 'abcdef ((p-append car cdr cdr cdr) '(1 2 3 4)) ;=> 4 (p-reverse-append "ab" "cd" "ef") ;=> "efcdab" (p-repeat 3 '(a b)) ;=> '(a b a b a b) ((p-reverse-append cdr cdr cdr car) '(1 2 3 4)) ;=> 4 ((p-repeat 3 cdr) '(1 2 3 4)) ;=> (4) What's Changed? --------------- The major changes in the generic procedure system since the previous version are as follows: * The code and module have been disentangled from that of the type system, object system and Java FFI. * There is a clear internal separation between code that deals with methods and code that deals with generic procedures. * The new extensible type system is used for all type-related operations. * There is a new METHOD form for creating methods. It's main purpose is to simplify the construction of derived syntax. * Methods now have a distinct type, . * The new ADD-METHOD procedure facilitates the adding of multiple methods to a generic procedure. This is more efficient than using individual calls to ADD-METHOD. * The new DEFINE-GENERICS form provides a concise syntax for the creation of bindings to multiple new generic procedures. * Generic procedures can be merged. This is useful in situations where several independently developed modules define generic procedures for identical purposes and an application needs to use and extend both. * Generic procedures can no longer be chained. Chaining makes it impossible to meaningfully and safely use the "next best matching method" invocation facility of generic procedures since it results in methods being incapable of discerning whether there *is* a next best matching method. * A "left-to-right" rule in the method selection logic simplifies the algorithm and results in elimination of ambiguity. See COMPARE-METHODS for details. * Improved error reporting. sisc-1.16.6.orig/doc/srfis.txt0000644000175000017500000001416711445752462014610 0ustar amoeamoeThis table indicates the current and planned support for SRFIs in SISC. 0 "Feature-based conditional expansion construct" implemented 1 "List Library" implemented 2 "AND-LET*" implemented 3 "List-Set Library" withdrawn 4 "Homogeneous numeric vector datatypes" won't implement 5 "A let form with signatures and rest arguments" implemented 6 "Basic String Ports" implemented 7 "Feature-based program configuration language" implemented 8 "receive: Binding to multiple values" implemented 9 "Defining Record Types" implemented 10 "Sharp-Comma External Form" won't implement 11 "Syntax for receiving multiple values" implemented 12 "Exception Handling" withdrawn 13 "String Library" implemented 14 "Character-Set Library" implemented 15 "Syntax for dynamic scoping" withdrawn 16 "Syntax for procedures of variable arity" implemented 17 "Generalized set!" won't implement 18 "Multithreading support" implemented 19 "Time Data Types and Procedures" implemented 20 "Simple object system" withdrawn 21 "Real-time multithreading support" won't implement 22 "Running Scheme Scripts on Unix" implemented 23 "Error reporting mechanism" implemented 24 "Define-syntax in local lexical scopes" withdrawn 25 "Multi-dimensional Array Primitives" implemented 26 "Notation for Specializing Parameters w/o Currying" implemented 27 "Sources of Random Bits" implemented 28 "Basic Format Strings" implemented 29 "Localization" implemented 30 "Nested Multi-line Comments" implemented 31 "A special form for recursive evaluation" implemented 32 "Sort Libraries" withdrawn 33 "Integer Bitwise-operation Library" withdrawn 34 "Exception Handling for Programs" implemented 35 "Conditions" implemented 36 "I/O Conditions" won't implement 37 "args-fold: a program argument processor" implemented 38 "External Rep for Data With Shared Structure" implemented 39 "Parameter objects" implemented 40 "A Library of Streams" implemented 41 nonexistent 42 "Eager Comprehensions" implemented 43 "Vector Library" implemented 44 "Collections" won't implement 45 "Primitives for iterative lazy algorithms" implemented 46 "Basic Syntax-rules Extensions" won't implement 47 "Array" won't implement 48 "Intermediate Format Strings" implemented 49 "Indentation-sensitive syntax" won't implement 50 "Mixing Scheme and C" withdrawn 51 "Handling rest list" implemented 52 "Permitting and Supporting Extended Character Sets" withdrawn 53 "Syntactic computations with computation-rules" withdrawn 54 "Formatting" implemented 55 "require-extension" implemented 56 "Binary I/O" withdrawn 57 "Records" won't implement 58 "Array Notation" won't implement 59 "Vicinity" implemented 60 "Integers as Bits" implemented 61 "A more general cond clause" implemented 62 "S-expression comments" implemented 63 "Homogeneous and Heterogeneous Arrays" won't implement 64 "A Scheme API for test suites" draft 65 "define-immutable" withdrawn 66 "Octet Vectors" implemented 67 "Compare Procedures" implemented 68 "Comprehensive I/O" withdrawn 69 "Basic hash tables" implemented 70 "Numbers" won't implement 71 "LET-syntax for multiple values" won't implement 72 "Simple hygienic macros" won't implement 73 "Exact Infinities" withdrawn 74 "Octet-Addressed Binary Blocks" won't implement 75 "R6RS Unicode data" draft 76 "R6RS Records" draft 77 "Preliminary Proposal for R6RS Arithmetic" draft 78 "Lightweight testing" implemented 79 "Primitive I/O" draft 80 "Stream I/O" draft 81 "Port I/O" draft 82 "Stream Ports" draft 83 "R6RS Library Syntax" draft 84 "Universal Identifiers" draft 85 "Recursive Equivalence Predicates" draft 86 "MU and NU simulating VALUES & CALL-WITH-VALUES" draft 87 "=> in case clauses" draft 88 "Keyword Objects" draft 89 "Optional parameters" draft 90 "Extensible hash table constructor" draft 91 "Extended ports" draft sisc-1.16.6.orig/doc/interned-values.txt0000644000175000017500000001342211445752462016560 0ustar amoeamoeInterned values are values which are associated, in a bijection, with an id, usually a globally unique symbol. Their main purpose is to avoid duplication of eq?-sensitive values on deserialisation. A typical example are user-defined types, such as record types and classes. Their duplication is usually undesirable. For example, it results in a deserialised record no longer inhabiting the same type as it did when it was being serialized. Non-generative types, which are built on top of interned values, solve this problem. 1) sisc.util.InternedValue This class serves two purposes. Firstly, it contains static members that maintain a bijective map between symbols and values. Secondly, instances of this class are used in Java serialisation as wrappers for interned values. Since the bijective map is static it is shared between app contexts and hence interned values can leak between apps. This is an unavoidable consequence of wanting to fit in with standard Java serialisation in, e.g., J2EE containers, which may happen in threads with no associated app context. In practice this shouldn't cause much of a problem. Firstly, many J2EE containers have separate class loaders for separate web apps etc. Secondly, the main purpose of interned values is to store globally unique types, for which there is little harm in sharing between apps. Access to the bijective map is thread-safe. The map is *not* weak - symbols and values of map entries will not be garbage collected. It would be desirable for map entries to be removed when they are no longer referenced. However, it is impossible to do so reliably, so the current set up is the only safe solution. 2) |intern| primitive changes in: sisc.modules.{Primitives,SimplePrimitives} depends on: 1 A new primitive (intern ) => maintains the bijective map. It looks up both and in the map and - if it finds neither, a new map entry is created, and the supplied values are returned - if it finds one of them, the values from the associated map entry are returned - if it finds both, and they match the supplied mapping then the supplied values are returned - otherwise, i.e. if it finds both but they do not match the supplied mapping, an error is raised 3) Java serialisation changes in: sisc.data.Value, sisc.ser.JavaDeserializer, sisc.util.InternedValue depends on: 1 Java serialisation of interned values is accomplished by implementing a writeReplace() method (which is part of the standard Java object output API) on Value. This checks whether the value is interned and if so returns an instance of InternedValue containing the value and associated symbol. This is then serialised by the writeExternal() method, which too is part of the standard Java object output API. Java deserialisation of interned values is accomplished by implementing a readResolve() and readExternal() methods that mirror the writeReplace() and writeExternal() methods above. writeReplace() deserialises the symbol, creates an empty value and then interns it, as if the |intern| primitive was called. Deserialisation is then performed on whatever value was the result of interning. Note that this means Java deserialisation will replace the *contents* of existing interned values. A small change to the JavaDeserializer is required in order to handle circular interned values, which may not have been fully deserialized and hence readResolve'd yet. 4) block and stream serialisation changes in: sisc.ser.SLL2{Serializer,Deserializer} depends on: 1 A new serialisation type is introduced for interned values. For every value to be serialised we check whether it is an interned value. If so we serialise the associated symbol followed by the value. On deserialisation we deserialise the symbol, create an empty value and intern it, just as if the |intern| primitive was called, obtaining whatever value results from that. We then deserialize into that value. Note that this means block and stream serialisation will replace the *contents* of existing interned values. 5) |type-safe-intern| function changes in: sisc.modules.misc, sisc.modules.std-modules depends on: 2 A helper function has been added to the misc module: (type-safe-intern ) => This calls the |intern| primitive. An error is raised if the given value has already been interned. If a different value is returned then is applied to it. An error is raised if that returns #f, and otherwise the value is returned. Typically this function is called with a freshly created, and not yet populated value, and the returned value is subsequently populated. Thus the contents of existing interned values may be replaced. 6) non-generative record types and classes changes in: sisc.modules.std-modules, sisc.modules.record.record, sisc.modules.oo.classes depends on: 5 define-nongenerative-record-type, define-nongenerative-struct, define-nongenerative-class are versions of the respective macros that take an additional guid parameter and produce non-generative types. make-record-type and make-class take an optional guid parameter. 7) non-generative core types changes in: sisc.modules.std-modules, sisc.modules.record.record, sisc.modules.oo.{classes,misc,slots}, sisc.modules.generic-procedures.{methods,procedures}, sisc.io.{generic-io-types,serial-io,string-io} depends on: 6, 4 All the existing core classes and record types are now non-generative. 8) non-generative library types changes in: sisc.modules.srfi.srfi-{14,18,19,25,35,37,40,45} depends on: 6, 4 All srfis that define structs or record types now define non-generative versions instead. As a result some of these srfis now no longer depend on srfi-9, since that only deals with generative record types. The sisc record module is imported instead. sisc-1.16.6.orig/doc/README.exprs0000644000175000017500000000672011445752462014735 0ustar amoeamoeExpressions ----------- Expressions and values form the atomic elements that the Interpreter mainloop evaluates to produce more values. SISC Expressions come in two forms. The first, "*Exp" are expressions that set up the interpreter to evaluate one or more expressions, and "*Eval" expressions that represent the post-processing of the evaluated expressions. AppExp: An AppExp sets up the interpreter for the evaluation of an application. This entails pushing an AppEval, the rator, and a FillRibExp onto the stack, then setting the next expression to the last rand. FillRibExp will in turn evaluate the remaining rands, placing the results into the value-rib register. After the rator is evaluated, the AppEval will be evaluated, which actually performs the application of the rator to the rands. AppEval: AppEval takes the procedure stored in the accumulator, and applies it to the values stored in the value rib. ApplyValuesContEval: ApplyValuesContEval is initialized with a procedure. When it is evaluated, it expects to find multiple values in the accumulator. It applies the procedure to the values in the accumulator, treating each value as a separate argument to the procedure. EvalExp: An EvalExp is a generic expression that will evaluate one expression, called the pre-expression, and push another, called the post-expression, onto the stack. The effect is that the post-expression gets evaluated with the results of the pre-expression in the accumulator. An EvalExp is usually paired with a *Eval expression as the post-expression. DefineEval: DefineEval sets or defines a toplevel binding it is constructed with to a value in the accumulator. FillRibExp: FillRibExp takes a rib-address, a next expression, and a value expression. It first stores the value in the accumulator into the value rib at its constructed rib address. Then it pushes the next expression onto the stack and sets the nxp register to the value expression. FreeReferenceExp: A FreeReferenceExp sets the accumulator to the result of looking up a symbol in a symbolic environment. If the variable is not bound, an error is raised. FreeSetEval: A FreeSetEval is initialized with a symbol. When evaluated, it expects a processed right-hand-side to be in the accumulator. It then sets the top-level binding of the left-hand-side to the value in the accumulator. IfEval: An IfEval expression expects the accumulator to contain the value resulting from the processing of a test expression. If the value in the accumulator is non-false, it sets the next-expression register to be the true-expression. Otherwise the false-expression is selected. LambdaExp: The LambdaExp is initialized with the formal parameters, body, and arity (fixed or infinite) of a procedure. When evaluated, it captures the lexical environment in a Closure and puts the new closure in the accumulator. LetrecExp: Behaves like AppExp, except that it creates a LexicalEnvironment that contains a number of uninitialized values that will be visible when evaluating its arguments, and that its last expression is LetrecEval rather than AppEval. LetrecEval: Sets the values of the bindings created by LetrecExp to the values present in the value rib. LexicalReferenceExp: The LexicalReferenceExp looks up a lexical reference in the current lexical environment, and sets the accumulator to the result. LexicalSetEval: The LexicalSetEval sets a lexical reference to the value stored in the accumulator.sisc-1.16.6.orig/doc/type-system.txt0000644000175000017500000001402311445752462015754 0ustar amoeamoeSISC's extensible type system ============================= SISC's extensible type system provides programmatic access to the type information of values and provides a core set of type testing and comparison procedures. The type system is extensible in two ways. Firstly any new native types are recognised automatically. Secondly, hooks are provided for Scheme-level extensions of the type-system. Core procedures & predicates ---------------------------- TYPE-OF => Returns the type of . There is no standard representation for types, leaving type extensions free to choose a representation that suits them most. The procedure is equipped with an extension hook, TYPE-OF-HOOK. See below for more details on hooks. The default implementation of TYPE-OF returns a type based on the Java type of the internal representation of . TYPE<= => #t/#f Returns #f if is a sub-type of . The predicate is equipped with an extension hook, TYPE<=-HOOK. See below for more details on hooks. The default implementation of TYPE<= determines sub-typing based on the inheritance relationship of the Java types representing native types. COMPARE-TYPES => equal, more-specific, less-specific Determines the relationship of two types with respect to a third. must be a sub-type of and . and are first compared using TYPE<=. If that comparison indicates that the types are disjoint (i.e. is not sub-type of , is not a sub-type of and the types are not equal) then additional information from is taken into account for the comparison. The predicate is equipped with an extension hook, COMPARE-TYPES-HOOK that is invoked in the case the comparison of with using TYPE<= finds the two types to be disjoint. See below for more details on hooks. The default implementation returns an error. Derived procedures and predicates --------------------------------- INSTANCE-OF? => #t/#f Determines whether is an instance of . This predicate obtains 's type using TYPE-OF and then compares it to using TYPE<=. TYPE= => #t/#f. Determines whether two types are equal by comparing them twice using TYPE<=. TYPES<= => #t/#f Determines whether all of are sub-types of by performing a pair-wise comparison using TYPE<= until a difference is found (in which ase #f is returned) or one (or both) of the lists has been exhausted (in which case #t is returned). INSTANCES-OF? => #t/#f Determines whether all of are instances of by performing a pair-wise test using INSTANCE-OF? until a test returns #f (in which case #f is returned) or one (or both) of the lists has been exhausted (in which case #t is returned). TYPES= => #t/#f Determines whether all of are equal to by performing a pair-wise comparison using TYPE= until a difference is found (in which case #f is returned) or one (or both) of the lists has been exhausted (in which case #t is returned). Hooks ----- Hooks are the main mechanism by which Scheme code can extend the default type system. The core type system procedures TYPE-OF, TYPE<= and COMPARE-TYPES all provide such hooks. Extension takes place by installing labelled procedures on the hook. The procedures are called with a "next" procedure as the first argument and all the arguments of the call to the hook-providing procedures as the remaining arguments. Example: (type-of-hook 'record (lambda (next o) (if (record? o) (record-type o) (next o)))) Installing a procedure with a label of an already installed procedure replaces the latter with the former. Typically the installed procedure first determines whether it is applicable, i.e. is capable of performing the requested comparison etc. If not it calls the "next" procedure, which invokes the next hook or, if no further hooks exist, the default implementation of the hooked procedure. Standard Types -------------- The type system pre-defines bindings for the native types corresponding to all the data types defined in R5RS. One notable exception is that pairs and null are combined into a type. We also define a type that is the base type of all SISC values, i.e. all SISC values are instances of and all types are sub-types of . The representations of other native types can be obtained using MAKE-TYPE => Constructs a type representing a built-in type. The must be a symbol and it must denote a Java class that is a sub-class of sisc.data.Value, the base of the SISC value type hierarchy. Examples -------- (import type-system) (type<= ) ;=> #t (type<= ) ;=> #f (instance-of? 1 ) ;=> #t (instance-of? 1 ) ;=> #t (instance-of? 1 ) ;=> #f (eq? (type-of 1) ) ;=> #t (import record) (define-struct foo (x)) (define-struct bar (x)) (define f (make-foo 1)) (define b (make-bar 1)) (instance-of? f foo) ;=> #t (instance-of? f ) ;=> #t (instance-of? f ) ;=> #t (instance-of? b foo) ;=> #f (type<= foo ) ;=> #t (type<= foo ) ;=> #t (type<= foo bar) ;=> #f What's Changed? --------------- The major changes in the type system since the previous version are as follows: * The code and module have been disentangled from that of generic procedures, the object system and Java FFI. * The type of a Scheme value is distinct from the type obtained by S2J for the Java object representing the value, i.e. the type system clearly distinguishes between Scheme values/types and Java values/types. * The type system is extensible at both the native (Java) and Scheme level. * There is no longer a built-in meta type. It is however easy to add using the new extension mechanism. * The canonical super type, i.e. the super type of everything, is no longer called but . There no longer is a canonical sub type . sisc-1.16.6.orig/doc/README.build0000644000175000017500000000264711445752462014677 0ustar amoeamoeBuilding SISC ------------- Building a binary SISC distribution requires a few tricky steps due to the manner in which SISC starts up. Instead of loading numerous scheme source files, syntactically expanding them, then compiling them to internal SISC expressions, this entire process is done once for what is considered the 'core' runtime, i.e. what is implicitly installed in the environment when the REPL prompt appears. The state of the interpreter (the heap) is saved into a heap file. Then, when SISC loads, it loads the pre-processed heap file into memory and presents the prompt. To build a SISC heap, change into the sisc/scheme-src directory, and execute the following command: java sisc.boot.GenerateHeap -out -files init.sce compat.sce psyntax.sce The interpreter will expand and compile the code, then write to the specified heap file. The standard SISC heap is generated by: java sisc.boot.GenerateHeap -out ../boot/sisc.heap init.sce compat.sce \ psyntax.sce init2.scm pp.scm repl.scm \ debug.scm The bare minumum required to build an R5RS compliant heap is init.sce, compat.sce, psyntax.sce, init2.scm. The other files loaded: repl.scm - The SISC REPL pp.scm - Pretty Printer debug.scm - Debugging (stack traces, tracing, breakpoints, etc) sisc-1.16.6.orig/README0000644000175000017500000000552111445752462013026 0ustar amoeamoeAbout SISC (Second Interpreter of Scheme Code) ---------------------------------------------- SISC is an extensible Java based interpreter of the algorithmic language Scheme. SISC uses modern interpretation techniques, and handily outperforms all existing JVM interpreters (often by more than an order of magnitude). In addition, SISC is a complete implementation of the language. The entire R5RS Scheme standard is supported, no exceptions. This includes a full number tower including complex number support, arbitrary precision integers and floating point numbers, as well as hygenic R5RS macros, proper tail recursion, and first-class continuations (not just the escaping continuations as in many limited Scheme systems). SISC also attempts to implement the standard as correctly as possible, while still providing exceptional performance. SISC also provides useful real-world extensions, such as networking, elegant exception handling, a scope-friendly module system, support for SLIB, numerous SRFIs, and an extensible type system with a Java foreign-function interface. Finally, native functionality can be added through the use of native libraries that may add new types, values, and functions to the language. These extensions can be packaged into scopable modules at the Scheme level as well. Installation ------------ Define SISC_HOME in your environment variables to point to the directory in which you installed the SISC distribution. Then, install "sisc" (Unix) or "sisc.bat" (Windows) in your path. If you are running on a Unix or Unix-like system, you may also wish to run the "install-srfi22.sh" script, which will set up SRFI-22 support for running Scheme programs directly from the shell. To run SISC, just type "sisc" or "sisc.bat", followed by any scheme source files you wish to load. Refer to the SISC Manual (which accompanies the full distribution and can be found on the SISC website) for the full command-line usage instructions. Bugs ---- If you encounter an unexpected error, please send an email to sisc-devel@lists.sourceforge.net, with the following information: 1. Build version 2. Steps to reproduce the error 3. A stack trace, (print-exception (get-last-exception)) If you're running the Lite build, you will not be able to perform step 3. Please obtain the full build and see if your error occurs there as well, then submit a report with the stack trace from the full build. Website ------- More information about SISC, including a paper on the implementation and the full SISC manual, can be found at the SISC website, http://sisc.sourceforge.net (C) 2000-2007 Scott G. Miller This software is distributed under a dual licensing scheme, with the GNU General Public License, v2, and the Mozilla Public License. The source code should be available from the same place you found this binary distribution. sisc-1.16.6.orig/sisc.bat0000644000175000017500000000055311445752462013577 0ustar amoeamoe@echo off if NOT "%SISC_HOME%" == "" GOTO NOSET set SISC_HOME=. :NOSET set EXTENSIONS= if NOT "%JAVA%" == "" GOTO RUN set JAVA=java :RUN %java% %JAVAOPT% -classpath "%SISC_HOME%/sisc-opt.jar;%SISC_HOME%/sisc.jar;%SISC_HOME%/sisc-lib.jar;%CLASSPATH%" -Dsisc.home=%SISC_HOME% sisc.REPL %EXTENSIONS% -h %SISC_HOME%\sisc.shp %1 %2 %3 %4 %5 %6 %7 %8 %9 sisc-1.16.6.orig/maven.xml0000644000175000017500000000171211445752462013774 0ustar amoeamoe sisc-1.16.6.orig/.project0000644000175000017500000000057411445752462013620 0ustar amoeamoe SISC org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature sisc-1.16.6.orig/src/0000755000175000017500000000000011445752462012732 5ustar amoeamoesisc-1.16.6.orig/src/Manifest0000644000175000017500000000002611445752462014421 0ustar amoeamoeMain-Class: sisc.REPL sisc-1.16.6.orig/src/sisc/0000755000175000017500000000000011445752462013673 5ustar amoeamoesisc-1.16.6.orig/src/sisc/exprs/0000755000175000017500000000000011445752462015034 5ustar amoeamoesisc-1.16.6.orig/src/sisc/exprs/LetrecExp.java0000644000175000017500000000657111445752462017603 0ustar amoeamoepackage sisc.exprs; import sisc.data.*; import sisc.env.LexicalUtils; import sisc.interpreter.*; import sisc.ser.*; import java.io.IOException; public class LetrecExp extends AppExp { int lcount, localIndices[], lexicalIndices[]; public LetrecExp(Expression exp, Expression rands[], Expression nxp, int[] localIndices, int[] lexicalIndices, boolean allImmediate) { super(exp, rands, nxp, allImmediate); this.localIndices=localIndices; this.lexicalIndices=lexicalIndices; lcount=localIndices.length+lexicalIndices.length; } public void eval(Interpreter r) throws ContinuationException { r.env=LexicalUtils.fixLexicals(r, lcount, localIndices, lexicalIndices); r.lcl=r.createValues(rands.length); for (int i=rands.length-1; i>=0; i--) r.lcl[i]=new Box(VOID); super.eval(r); } public Value express() { Pair lccps=LexicalUtils.intArrayToList(localIndices); Pair lxcps=LexicalUtils.intArrayToList(lexicalIndices); Pair args=EMPTYLIST; for (int i=rands.length-1; i>=0; i--) { args=new Pair(((rands[i]==null) ? VOID : rands[i].express()), args); } return list(sym("letrec"), list(lccps, lxcps), args, exp.express(), nxp.express()); } public LetrecExp() {} public void serialize(Serializer s) throws IOException { super.serialize(s); LexicalUtils.writeIntArray(s,localIndices); LexicalUtils.writeIntArray(s,lexicalIndices); } public void deserialize(Deserializer s) throws IOException { super.deserialize(s); localIndices=LexicalUtils.readIntArray(s); lexicalIndices=LexicalUtils.readIntArray(s); lcount=((localIndices==null ? 0 : localIndices.length) + (lexicalIndices==null ? 0 : lexicalIndices.length)); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/AnnotatedExpr.java0000644000175000017500000000707111445752462020460 0ustar amoeamoepackage sisc.exprs; import java.io.*; import sisc.data.*; import sisc.exprs.fp.OptimismUnwarrantedException; import sisc.exprs.fp.OptimisticHost; import sisc.exprs.fp.Utils; import sisc.interpreter.*; import sisc.io.ValueWriter; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; public class AnnotatedExpr extends Value implements OptimisticHost { public Expression expr; public Value annotation, stripped=FALSE; public AnnotatedExpr(Expression expr, Value annotation) { this.expr=expr; this.annotation=annotation; } public void setHosts() { Utils.linkOptimistic(this, expr, 0); } public final void eval(Interpreter r) throws ContinuationException { expr.eval(r); } public final Value getValue(Interpreter r) throws ContinuationException { do { try { return expr.getValue(r); } catch (OptimismUnwarrantedException uwe) { } } while (true); } public Value express() { return list(sym("annotated"), annotation, expr.express()); } public AnnotatedExpr() {} public void serialize(Serializer s) throws IOException { s.writeExpression(expr); s.writeExpression(annotation); s.writeExpression(stripped); } public void display(ValueWriter w) throws IOException { w.append("#@(").append(annotation).append(" . "); if (expr instanceof Value) w.append(((Value)expr)); else w.append(expr.express()); w.append(')'); } public void deserialize(Deserializer s) throws IOException { expr=s.readExpression(); annotation=(Value)s.readExpression(); stripped=(Value)s.readExpression(); } public boolean visit(ExpressionVisitor v) { return v.visit(expr) && v.visit(annotation) && v.visit(stripped); } /* (non-Javadoc) * @see sisc.exprs.OptimisticHost#alter(int, sisc.data.Expression) */ public synchronized void alter(Interpreter r, int uexpPosition, Expression replaceWith) { expr=replaceWith; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/FreeSetEval.java0000644000175000017500000000571011445752462020047 0ustar amoeamoepackage sisc.exprs; import java.io.*; import sisc.data.*; import sisc.interpreter.*; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.env.SymbolicEnvironment; import sisc.util.ExpressionVisitor; import sisc.util.FreeReference; import sisc.util.UndefinedVarException; public class FreeSetEval extends Expression { private FreeReference ref; public FreeSetEval(Symbol sym, SymbolicEnvironment senv) { ref = new FreeReference(sym, senv); } public void eval(Interpreter r) throws ContinuationException { setValue(r, r.acc); r.acc=VOID; r.nxp=null; } public void setValue(Interpreter r, Value v) throws ContinuationException { try { ref.setValue(v); } catch (UndefinedVarException e) { error(r, liMessage(SISCB,"undefinedvar", e.var)); } } public void serialize(Serializer s) throws IOException { ref.serialize(s); } public Value express() { return new Pair(sym("ref!"), ref.express()); } public void deserialize(Deserializer s) throws IOException { ref.deserialize(s); } public FreeSetEval() { ref = new FreeReference(); } public boolean equals(Object o) { if (!(o instanceof FreeSetEval)) return false; FreeSetEval e = (FreeSetEval)o; return ref.equals(e.ref); } public int hashCode() { return ref.hashCode(); } public boolean visit(ExpressionVisitor v) { return ref.visit(v); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/ApplyValuesContEval.java0000644000175000017500000000623611445752462021607 0ustar amoeamoepackage sisc.exprs; import java.io.*; import sisc.data.*; import sisc.interpreter.*; import sisc.io.ValueWriter; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; public class ApplyValuesContEval extends Expression { public Procedure consumer; public ApplyValuesContEval(Procedure c) { consumer=c; } private final static Expression AVCE_APPEVAL = annotatedAppEval("eval"); private static Expression annotatedAppEval(String fn) { return annotatedAppEval(ApplyValuesContEval.class, fn); } public void eval(Interpreter r) throws ContinuationException { if (r.acc instanceof Values) { final Value[] vlr = ((Values)r.acc).values; final int len = vlr.length; Value[] newvlr; if (len == 0) { newvlr = ZV; } else { newvlr = r.createValues(len); System.arraycopy(vlr, 0, newvlr, 0, len); } r.newVLR(newvlr); } else { r.newVLR(1); r.vlr[0]=r.acc; } r.nxp=AVCE_APPEVAL; r.acc=consumer; } public void display(ValueWriter w) throws IOException { w.append("#<").append(liMessage(SISCB, "systemcontinuation")).append('>'); } public Value express() { return list(sym("values"), consumer.express()); } public void serialize(Serializer s) throws IOException { s.writeExpression(consumer); } public ApplyValuesContEval() {} public void deserialize(Deserializer s) throws IOException { consumer=(Procedure)s.readExpression(); } public boolean visit(ExpressionVisitor v) { return v.visit(consumer); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/LetrecEval.java0000644000175000017500000000576711445752462017744 0ustar amoeamoepackage sisc.exprs; import java.io.*; import sisc.data.*; import sisc.interpreter.*; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; import sisc.exprs.fp.OptimismUnwarrantedException; import sisc.exprs.fp.OptimisticHost; import sisc.exprs.fp.Utils; public class LetrecEval extends Expression implements OptimisticHost { public Expression body; public LetrecEval(Expression body) { this.body=body; } public void setHosts() { Utils.linkOptimistic(this, body, 0); } public void eval(Interpreter r) throws ContinuationException { for (int i=r.vlr.length-1; i>=0; i--) { ((Box)r.lcl[i]).val=r.vlr[i]; } boolean retry; do { try { r.next(body); retry = false; } catch (OptimismUnwarrantedException uwe) { retry = true; } } while (retry); } public Value express() { return list(sym("letrec-eval"), body.express()); } public LetrecEval() {} public void serialize(Serializer s) throws IOException { s.writeExpression(body); } public void deserialize(Deserializer s) throws IOException { body=s.readExpression(); } public boolean visit(ExpressionVisitor v) { return v.visit(body); } /* (non-Javadoc) * @see sisc.exprs.OptimisticHost#alter(int, sisc.data.Expression) */ public synchronized void alter(Interpreter r, int uexpPosition, Expression replaceWith) { body=replaceWith; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/FillRibExp.java0000644000175000017500000001037611445752462017706 0ustar amoeamoepackage sisc.exprs; import java.io.*; import sisc.data.*; import sisc.exprs.fp.OptimismUnwarrantedException; import sisc.exprs.fp.OptimisticExpression; import sisc.exprs.fp.OptimisticHost; import sisc.exprs.fp.Utils; import sisc.interpreter.*; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; public class FillRibExp extends Expression implements OptimisticHost { static final int POS_EXP=0, POS_NXP=1; public Expression exp, nxp; public int pos; public boolean lastAndRatorImmediate; public FillRibExp(Expression exp, int pos, Expression nxp, boolean lari) { this.exp=exp; this.pos=pos; this.nxp=nxp; lastAndRatorImmediate=lari; } public void setHosts() { /* 'nxp' must not be an OptimisticExpression if it can end up on the stack and hence be evaluated outside the context of the eval method here. */ if (!lastAndRatorImmediate || exp instanceof OptimisticExpression) { Utils.assertNonOptimistic(nxp); } Utils.linkOptimistic(this, exp, POS_EXP); Utils.linkOptimistic(this, nxp, POS_NXP); } public void eval(Interpreter r) throws ContinuationException { r.setVLR(pos, r.acc); boolean retry; do { try { if (lastAndRatorImmediate) { r.acc=exp.getValue(r); r.next(nxp); } else { r.push(nxp); r.next(exp); } retry = false; } catch (OptimismUnwarrantedException uwe) { retry = true; } } while (retry); } public Value express() { return list(sym("arg"), Quantity.valueOf(pos), exp.express(), nxp.express()); } public void serialize(Serializer s) throws IOException { s.writeExpression(exp); s.writeInt(pos); s.writeExpression(nxp); s.writeBoolean(lastAndRatorImmediate); } public FillRibExp() {} public void deserialize(Deserializer s) throws IOException { exp=s.readExpression(); pos=s.readInt(); nxp=s.readExpression(); lastAndRatorImmediate=s.readBoolean(); } public boolean visit(ExpressionVisitor v) { return v.visit(exp) && v.visit(nxp); } public synchronized void alter(Interpreter r, int uexpPosition, Expression replaceWith) { switch(uexpPosition) { case POS_NXP: nxp=replaceWith; break; case POS_EXP: exp=replaceWith; if (lastAndRatorImmediate && !(replaceWith instanceof Immediate)) { lastAndRatorImmediate=false; } break; } } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/FreeReferenceExp.java0000644000175000017500000000635611445752462021066 0ustar amoeamoepackage sisc.exprs; import sisc.data.*; import java.io.*; import sisc.interpreter.*; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.env.SymbolicEnvironment; import sisc.util.ExpressionVisitor; import sisc.util.FreeReference; import sisc.util.UndefinedVarException; public class FreeReferenceExp extends Expression implements Immediate { private FreeReference ref; public FreeReferenceExp(FreeReference ref) { this.ref = ref; } public FreeReferenceExp(Symbol sym, SymbolicEnvironment senv) { this(new FreeReference(sym, senv)); } public Symbol getSym() { return ref.getName(); } public void eval(Interpreter r) throws ContinuationException { r.acc = getValue(r); r.nxp = null; } public Value getValue(Interpreter r) throws ContinuationException { try { return ref.getValue(); } catch (UndefinedVarException e) { error(r, liMessage(SISCB,"undefinedvar", e.var)); return null; //won't get here } } public void serialize(Serializer s) throws IOException { ref.serialize(s); } public Value express() { return new Pair(sym("ref"), ref.express()); } public void deserialize(Deserializer s) throws IOException { ref.deserialize(s); } public FreeReferenceExp() { ref = new FreeReference(); } public boolean equals(Object o) { if (!(o instanceof FreeReferenceExp)) return false; FreeReferenceExp e = (FreeReferenceExp)o; return ref.equals(e.ref); } public int hashCode() { return ref.hashCode(); } public boolean visit(ExpressionVisitor v) { return ref.visit(v); } public FreeReference getReference() { return ref; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/EvalExp.java0000644000175000017500000001063111445752462017244 0ustar amoeamoepackage sisc.exprs; import sisc.data.*; import sisc.exprs.fp.OptimismUnwarrantedException; import sisc.exprs.fp.OptimisticExpression; import sisc.exprs.fp.OptimisticHost; import sisc.exprs.fp.Utils; import java.io.*; import sisc.interpreter.*; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; public class EvalExp extends Expression implements OptimisticHost { public static final int POS_PRE=0, POS_POST=1; public Expression pre, post; public boolean preImmediate; public EvalExp(Expression pre, Expression post, boolean preImmediate) { this.pre=pre; this.post=post; this.preImmediate=preImmediate; } public void setHosts() { /* 'post' must not be an OptimisticExpression if 'pre' is non-immediate or an OptimisticExpression. It could end up on the stack and hence be evaluated outside the context of the eval method here. */ if (!preImmediate || pre instanceof OptimisticExpression) { Utils.assertNonOptimistic(post); } Utils.linkOptimistic(this, pre, POS_PRE); Utils.linkOptimistic(this, post, POS_POST); } public void eval(Interpreter r) throws ContinuationException { boolean retry; do { try { if (preImmediate) { r.acc = pre.getValue(r); r.next(post); } else { r.push(post); r.next(pre); } retry = false; } catch (OptimismUnwarrantedException uwe) { retry = true; } } while (retry); } private Value expressHelper() { return new Pair(pre.express(), ((post instanceof EvalExp) ? ((EvalExp)post).expressHelper() : list(post.express()))); } public Value express() { return new Pair(sym("begin"), expressHelper()); } public void serialize(Serializer s) throws IOException { s.writeExpression(pre); s.writeExpression(post); s.writeBoolean(preImmediate); } public EvalExp() {} public void deserialize(Deserializer s) throws IOException { pre=s.readExpression(); post=s.readExpression(); preImmediate=s.readBoolean(); } public boolean visit(ExpressionVisitor v) { return v.visit(pre) && v.visit(post); } /* (non-Javadoc) * @see sisc.exprs.OptimisticHost#alter(int, sisc.data.Expression) */ public synchronized void alter(Interpreter r, int uexpPosition, Expression replaceWith) { switch(uexpPosition) { case POS_PRE: pre=replaceWith; if (preImmediate && !(replaceWith instanceof Immediate)) { preImmediate=false; } break; case POS_POST: post=replaceWith; break; } } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/LocalReferenceExp.java0000644000175000017500000000503111445752462021224 0ustar amoeamoepackage sisc.exprs; import java.io.*; import sisc.data.*; import sisc.interpreter.*; import sisc.ser.Serializer; import sisc.ser.Deserializer; public class LocalReferenceExp extends Expression implements Immediate { public int idx; public LocalReferenceExp(int idx) { this.idx=idx; } public void eval(Interpreter r) throws ContinuationException { r.acc=r.lcl[idx]; r.nxp=null; //r.lc++; } public final Value getValue(Interpreter r) throws ContinuationException { //r.lc++; return r.lcl[idx]; } public Value express() { return list(sym("lcl"), Quantity.valueOf(idx)); } public void serialize(Serializer s) throws IOException { s.writeInt(idx); } public LocalReferenceExp() {} public void deserialize(Deserializer s) throws IOException { idx=s.readInt(); } public boolean equals(Object o) { if (!(o instanceof LocalReferenceExp)) return false; return idx==((LocalReferenceExp)o).idx; } public int hashCode() { return idx | 0xea000000; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/AppEval.java0000644000175000017500000000623211445752462017232 0ustar amoeamoepackage sisc.exprs; import sisc.data.*; import sisc.interpreter.*; import sisc.ser.*; import java.io.IOException; public class AppEval extends Expression { public AppEval() {} public final void eval(Interpreter r) throws ContinuationException { r.trace(this); /* To allow break of execution (turadg) */ if (permitInterrupts && r.tctx.interrupt) { /* We bring the stack into a state s.t. when it is captured by error() below, and later resumed, it will continue execution exactly where we left off. We push the current AppEval, and the acc. When the error k is invoked, the pushed acc will self-evaluate, thus placing itself back in the acc. The following pop brings back the AppEval, thus getting us exactly back to the point where execution was interrupted. */ r.push(this); r.push(r.acc); r.tctx.interrupt = false; error(r, liMessage(SISCB, "evaluationinterrupted")); } r.acc.apply(r); } public Value express() { return list(sym("appl")); } public boolean equals(Object o) { if (!(o instanceof AppEval)) return false; AppEval other=(AppEval)o; return (annotations!=null ? annotations.equals(other.annotations) : other.annotations == null); } public int hashCode() { return 0x37895f61 ^ (annotations == null ? 0 : annotations.hashCode()); } public void serialize(Serializer s) throws IOException { } public void deserialize(Deserializer s) throws IOException { } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/fp/0000755000175000017500000000000011445752462015441 5ustar amoeamoesisc-1.16.6.orig/src/sisc/exprs/fp/OptimisticExpression.java0000644000175000017500000000367011445752462022516 0ustar amoeamoepackage sisc.exprs.fp; /** * @author scgmille * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public interface OptimisticExpression { /** * Called to set up backward references to the hosts * * @param host * @param uexpPosition */ public void setHost(OptimisticHost host, int uexpPosition); /** * Called to clear the safe expressions * */ public void dropSafe(); } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/fp/FixedAppExp_2.java0000644000175000017500000000560411445752462020707 0ustar amoeamoepackage sisc.exprs.fp; import java.io.*; import sisc.data.*; import sisc.interpreter.*; import sisc.nativefun.FixableProcedure; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; import sisc.util.FreeReference; public class FixedAppExp_2 extends FixedAppExp_1 { public Immediate op1; public FixedAppExp_2(Immediate op0, Immediate op1, FreeReference ref) { super(op0, ref); this.op1=op1; } public void setHosts() { super.setHosts(); Utils.linkOptimistic(this, (Expression)op1, 1); } public Expression[] getOperands() { return new Expression[] {(Expression)op0, (Expression)op1}; } public Value doGetValue(FixableProcedure proc, Interpreter r) throws ContinuationException { return proc.apply(op0.getValue(r), op1.getValue(r)); } public Value express() { return list(sym("fapp"), ref.express(), ((Expression)op0).express(), ((Expression)op1).express()); } public void serialize(Serializer s) throws IOException { super.serialize(s); s.writeExpression((Expression)op1); } public FixedAppExp_2() {} public void deserialize(Deserializer s) throws IOException { super.deserialize(s); op1=(Immediate)s.readExpression(); } public boolean visit(ExpressionVisitor v) { return super.visit(v) && v.visit((Expression)op1); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/fp/OptimisticHost.java0000644000175000017500000000435111445752462021271 0ustar amoeamoepackage sisc.exprs.fp; import sisc.data.Expression; import sisc.interpreter.Interpreter; /** * An Optimistic uExp Host Expression provides a callback for * child uExps to call if they need to revert to safer * expressions. * * @author scgmille * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public interface OptimisticHost { /** * Instructs the host to replace the uExp referenced at the * given (Expression dependent) position, with the given * Expression. * * @param uexpPosition Expression dependent uExp index * @param replaceWith Expression to revert to */ public void alter(Interpreter r, int uexpPosition, Expression replaceWith); public void setHosts(); } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/fp/FixedAppExp_0.java0000644000175000017500000001210411445752462020676 0ustar amoeamoepackage sisc.exprs.fp; import java.io.*; import sisc.data.*; import sisc.interpreter.*; import sisc.exprs.AppExp; import sisc.exprs.FreeReferenceExp; import sisc.nativefun.FixableProcedure; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; import sisc.util.FreeReference; import sisc.util.UndefinedVarException; import sisc.compiler.Compiler; import sisc.compiler.CompilerConstants; public class FixedAppExp_0 extends Expression implements Immediate, OptimisticExpression { transient FixableProcedure proc; public FreeReference ref; public OptimisticHost host; public int uexpPosition; public FixedAppExp_0(FreeReference ref) { this.ref=ref; } public void setHost(OptimisticHost host, int uexpPos) { this.host=host; uexpPosition=uexpPos; } public void eval(Interpreter r) throws ContinuationException { r.acc=getValue(r); r.nxp=null; } public Value doGetValue(FixableProcedure proc, Interpreter r) throws ContinuationException { return proc.apply(); } public Value getValue(Interpreter r) throws ContinuationException { try { Expression e = ref.getValue(); if (e != proc) { //If the definition has changed (or has never been //seen before) check if its still fixable. If not, //revert to the safe expression if (e instanceof FixableProcedure) { proc = (FixableProcedure)e; } else { revert(r); } } return doGetValue(proc, r); } catch (UndefinedVarException e) { forceRevert(r); } catch (OptimismUnwarrantedException e) { throw e; } catch (RuntimeException e) { forceRevert(r); } // Should be unreachable; return null; } public Expression[] getOperands() { return ZV; } public final void forceRevert(Interpreter r) { revert(r, getOperands(), CompilerConstants.REALTAIL); } public final void revert(Interpreter r) { revert(r, getOperands()); } public final void revert(Interpreter r, Expression[] rands) { revert(r, rands, 0); } public final void revert(Interpreter r, Expression[] rands, int flags) { if (host == null) { Procedure.throwPrimException(liMessage(SISCB, "nosafeexpr")); } try { AppExp safeExpr=(AppExp)Compiler.application(r, new FreeReferenceExp(ref), rands, flags, getAnnotations(), r.getCtx().symenv); if (safeExpr instanceof OptimisticExpression) { ((OptimisticExpression)safeExpr).setHost(host, uexpPosition); } host.alter(r, uexpPosition, safeExpr); throw new OptimismUnwarrantedException(); } catch (ContinuationException ce) { Procedure.throwPrimException(ce.getMessage()); } } public Value express() { return list(sym("fapp"), ref.express()); } public void serialize(Serializer s) throws IOException { ref.serialize(s); s.writeExpression((Expression)host); s.writeInt(uexpPosition); } public FixedAppExp_0() { ref=new FreeReference(); } public void deserialize(Deserializer s) throws IOException { ref.deserialize(s); host=(OptimisticHost)s.readExpression(); uexpPosition=s.readInt(); } public boolean visit(ExpressionVisitor v) { return ref.visit(v) && v.visit((Expression)host); } public void dropSafe() { host=null; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/fp/OptimismUnwarrantedException.java0000644000175000017500000000326111445752462024201 0ustar amoeamoepackage sisc.exprs.fp; /** * @author scgmille * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class OptimismUnwarrantedException extends RuntimeException { } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/fp/FixedAppExp_1.java0000644000175000017500000000612511445752462020705 0ustar amoeamoepackage sisc.exprs.fp; import java.io.*; import sisc.data.*; import sisc.interpreter.*; import sisc.nativefun.FixableProcedure; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; import sisc.util.FreeReference; public class FixedAppExp_1 extends FixedAppExp_0 implements OptimisticHost { public Immediate op0; public FixedAppExp_1(Immediate op0, FreeReference ref) { super(ref); this.op0=op0; } public void setHosts() { Utils.linkOptimistic(this, (Expression)op0, 0); } public Expression[] getOperands() { return new Expression[] {(Expression)op0}; } /* (non-Javadoc) * @see sisc.exprs.fp.OptimisticHost#alter(int, sisc.data.Expression) */ public void alter(Interpreter r, int uexpPosition, Expression replaceWith) { Expression[] rands = getOperands(); rands[uexpPosition] = replaceWith; revert(r, rands); } public Value doGetValue(FixableProcedure proc, Interpreter r) throws ContinuationException { return proc.apply(op0.getValue(r)); } public Value express() { return list(sym("fapp"), ref.express(), ((Expression)op0).express()); } public void serialize(Serializer s) throws IOException { super.serialize(s); s.writeExpression((Expression)op0); } public FixedAppExp_1() {} public void deserialize(Deserializer s) throws IOException { super.deserialize(s); op0=(Immediate)s.readExpression(); } public boolean visit(ExpressionVisitor v) { return super.visit(v) && v.visit((Expression)op0); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/fp/Utils.java0000644000175000017500000000375211445752462017413 0ustar amoeamoepackage sisc.exprs.fp; import sisc.data.Expression; import sisc.util.Util; public class Utils { public static void linkOptimistic(OptimisticHost host, Expression exp, int uexpPos) { if (exp != null && exp instanceof OptimisticExpression) { ((OptimisticExpression)exp).setHost(host, uexpPos); } } public static void assertNonOptimistic(Expression exp) { if (exp != null && exp instanceof OptimisticExpression) { throw new RuntimeException(Util.liMessage(Util.SISCB, "illegaloptimism")); } } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/fp/FixedAppExp_3.java0000644000175000017500000000601611445752462020706 0ustar amoeamoepackage sisc.exprs.fp; import java.io.*; import sisc.data.*; import sisc.interpreter.*; import sisc.nativefun.FixableProcedure; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; import sisc.util.FreeReference; public class FixedAppExp_3 extends FixedAppExp_2 { public Immediate op2; public FixedAppExp_3(Immediate op0, Immediate op1, Immediate op2, FreeReference ref) { super(op0, op1, ref); this.op2=op2; } public void setHosts() { super.setHosts(); Utils.linkOptimistic(this, (Expression)op2, 2); } public Expression[] getOperands() { return new Expression[] {(Expression)op0, (Expression)op1, (Expression)op2}; } public Value doGetValue(FixableProcedure proc, Interpreter r) throws ContinuationException { return proc.apply(op0.getValue(r), op1.getValue(r), op2.getValue(r)); } public Value express() { return list(sym("fapp"), ref.express(), ((Expression)op0).express(), ((Expression)op1).express(), ((Expression)op2).express()); } public void serialize(Serializer s) throws IOException { super.serialize(s); s.writeExpression((Expression)op2); } public FixedAppExp_3() {} public void deserialize(Deserializer s) throws IOException { super.deserialize(s); op2=(Immediate)s.readExpression(); } public boolean visit(ExpressionVisitor v) { return super.visit(v) && v.visit((Expression)op2); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/IfEval.java0000644000175000017500000000656311445752462017057 0ustar amoeamoepackage sisc.exprs; import java.io.*; import sisc.data.*; import sisc.interpreter.*; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; import sisc.exprs.fp.OptimismUnwarrantedException; import sisc.exprs.fp.OptimisticHost; import sisc.exprs.fp.Utils; public class IfEval extends Expression implements OptimisticHost { private static final int POS_CONSEQ=0, POS_ALTERN=1; public Expression conseq, altern; public IfEval(Expression conseq, Expression altern) { this.conseq=conseq; this.altern=altern; } public void setHosts() { Utils.linkOptimistic(this, conseq, POS_CONSEQ); Utils.linkOptimistic(this, altern, POS_ALTERN); } public void eval(Interpreter r) throws ContinuationException { boolean retry; do { try { r.next(truth(r.acc) ? conseq : altern); retry = false; } catch (OptimismUnwarrantedException uwe) { retry = true; } } while (retry); } public Value express() { return list(sym("if"), conseq.express(), altern.express()); } public void serialize(Serializer s) throws IOException { s.writeExpression(conseq); s.writeExpression(altern); } public IfEval() {} public void deserialize(Deserializer s) throws IOException { conseq=s.readExpression(); altern=s.readExpression(); } public boolean visit(ExpressionVisitor v) { return v.visit(conseq) && v.visit(altern); } /* (non-Javadoc) * @see sisc.exprs.OptimisticHost#alter(int, sisc.data.Expression) */ public synchronized void alter(Interpreter r, int uexpPosition, Expression replaceWith) { switch(uexpPosition) { case POS_CONSEQ: conseq = replaceWith; break; case POS_ALTERN: altern = replaceWith; break; } } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/LambdaExp.java0000644000175000017500000000761111445752462017541 0ustar amoeamoepackage sisc.exprs; import java.io.*; import sisc.data.*; import sisc.env.LexicalUtils; import sisc.interpreter.*; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; public class LambdaExp extends Expression implements Immediate { public boolean infiniteArity; public int fcount, lcount, localIndices[], lexicalIndices[], boxes[]; public Expression body; public LambdaExp(int s, Expression body, boolean arity, int[] localids, int[] lexids, int[] boxes) { infiniteArity=arity; fcount=s; this.body=body; localIndices=localids; lexicalIndices=lexids; this.boxes=boxes; lcount=localids.length+lexids.length; } public void eval(Interpreter r) throws ContinuationException { r.acc=getValue(r); r.nxp=null; } public Value getValue(Interpreter r) throws ContinuationException { return new Closure(infiniteArity, fcount, body, LexicalUtils.fixLexicals(r, lcount, localIndices, lexicalIndices), boxes); } public Value express() { Pair lccps = LexicalUtils.intArrayToList(localIndices); Pair lxcps = LexicalUtils.intArrayToList(lexicalIndices); Pair boxs = LexicalUtils.intArrayToList(boxes); return list(sym("lambda"), new Pair(truth(infiniteArity), new Pair(Quantity.valueOf(fcount), boxs)), list(lccps, lxcps), body.express()); } public void serialize(Serializer s) throws IOException { s.writeBoolean(infiniteArity); s.writeInt(fcount); LexicalUtils.writeIntArray(s,localIndices); LexicalUtils.writeIntArray(s,lexicalIndices); LexicalUtils.writeIntArray(s,boxes); s.writeExpression(body); } public LambdaExp() {} public void deserialize(Deserializer s) throws IOException { infiniteArity=s.readBoolean(); fcount=s.readInt(); localIndices=LexicalUtils.readIntArray(s); lexicalIndices=LexicalUtils.readIntArray(s); lcount=((localIndices==null ? 0 : localIndices.length) + (lexicalIndices==null ? 0 : lexicalIndices.length)); boxes=LexicalUtils.readIntArray(s); body=s.readExpression(); } public boolean visit(ExpressionVisitor v) { return v.visit(body); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/exprs/AppExp.java0000644000175000017500000001405611445752462017102 0ustar amoeamoepackage sisc.exprs; import java.io.*; import sisc.data.*; import sisc.exprs.fp.OptimismUnwarrantedException; import sisc.exprs.fp.OptimisticExpression; import sisc.exprs.fp.OptimisticHost; import sisc.exprs.fp.Utils; import sisc.interpreter.*; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; import sisc.compiler.Compiler; public class AppExp extends Expression implements OptimisticHost { public static final int POS_EXP=-1, POS_NXP=-2; public Expression exp, rands[], nxp; public boolean allImmediate; protected int l; public AppExp(Expression exp, Expression rands[], Expression nxp, boolean allImmediate) { this.exp=exp; this.rands=rands; l=rands.length; this.nxp = nxp; this.allImmediate=allImmediate; } public void setHosts() { /* 'nxp' must not be an OptimisticExpression if we have non-immediate or OptimisticExpression operands. It could end up on the stack and hence be evaluated outside the context of the eval method here. */ if (!allImmediate || haveOptimisticRands()) { Utils.assertNonOptimistic(nxp); } Utils.linkOptimistic(this, exp, POS_EXP); Utils.linkOptimistic(this, nxp, POS_NXP); for (int i=0; i=0; i--) { r.vlr[i] = rands[i].getValue(r); } r.next(nxp); } else { // Load the immediates from right to left Expression ex; for (int i = l-1; i>=0; i--) { ex=rands[i]; if (ex != null) r.vlr[i] = ex.getValue(r); } r.push(nxp); r.next(exp); } retry = false; } catch (OptimismUnwarrantedException uwe) { retry = true; } } while (retry); } public Value express() { Pair args=EMPTYLIST; for (int i=rands.length-1; i>=0; i--) { args=new Pair(((rands[i]==null) ? VOID : rands[i].express()), args); } return list(sym("app"), args, exp.express(), nxp.express()); } public void serialize(Serializer s) throws IOException { s.writeExpression(exp); s.writeInt(l); for (int i=0; i '~') || in(c, unprintable_characters)); } static final char STRING_CONST='"', COMMENT =';', LIST_OPEN_ALT ='[', LIST_CLOSE_ALT =']', LIST_OPEN ='(', LIST_CLOSE =')', SHARP ='#', QUOTE ='\'', BACKQUOTE ='`', UNQUOTE =',', UNQUOTE_SPLICING ='@', DOT ='.', PIPE ='|'; public static final char[] special = new char[] {'\t', '\n', '\r', ' ', '"', '(', ')', ';', '[', ']'}, sharp_special = new char[] {'\t', '\n', ' ', '"', '#', '(', ')', '=', '[', ']'}, number_prefixes = new char[] {'+','-','.'}, hex_number_prefixes = new char[] {'+','-','.','A','B','C','D','E','F','a','b','c','d','e','f'}, reserved = new char[] {'[', ']', '{', '|', '}'}, special_and_reserved = new char[] {'\t', '\n', '\r', ' ', '"', '(', ')', ';', '[', ']', '{', '|', '}'}, special_initials = new char[] {'!','$','%','&','*','/',':','<','=','>','?','^','_','~'}, special_subsequents = new char[] {'+','-','.','@'}, protected_literal_barrier = new char[] {'|'}, unprintable_characters = new char[] {}; public boolean strictR5RS = Defaults.STRICT_R5RS; public String sval; public Quantity nval; public Pair prval; public int readIgnoringWhitespace(PushbackReader is) throws IOException { char c=0; do { c=(char)readChar(is); } while (Character.isWhitespace(c)); return c; } public int nextToken(PushbackReader is, int radix) throws IOException { int nt=_nextToken(is, radix); return nt; } public int _nextToken(PushbackReader is, int radix) throws IOException { synchronized(is) { int c=readIgnoringWhitespace(is); switch (c) { case LIST_OPEN: case LIST_OPEN_ALT: return TT_PAIR; case LIST_CLOSE: case LIST_CLOSE_ALT: return TT_ENDPAIR; case PIPE: return TT_PIPE; case QUOTE: return TT_QUOTE; case SHARP: return TT_SHARP; case STRING_CONST: sval=readToEndOfString(is); return TT_STRING; case COMMENT: while (readChar(is,false,false,false)!='\n') {} return nextToken(is, radix); case BACKQUOTE: return TT_BACKQUOTE; case UNQUOTE: int sc=readChar(is); if (sc==UNQUOTE_SPLICING) return TT_UNQUOTE_SPLICING; else is.unread(sc); return TT_UNQUOTE; default: is.unread(c); String v=readToBreak(is, special, true, false); if (c=='\\') v="\\"+v; Object result=v; if (numberStart(v.charAt(0), radix)) result=readNum(v, radix); if (result instanceof String) { sval=(String)result; if (sval.length()==1 && sval.charAt(0)==DOT) return TT_DOT; return TT_SYMBOL; } else { nval=(Quantity)result; return TT_NUMBER; } } } } static Object readNum(String v, int radix) { try { Quantity q=Quantity.valueOf(v, radix); return q; } catch (NumberFormatException n) { return v; } } public int readChar(PushbackReader is) throws IOException { return readChar(is, true, false, true); } public int readPureChar(PushbackReader is) throws IOException { return readChar(is, true, false, false); } public int readChar(PushbackReader is, boolean handleEscapes, boolean invertEscaped, boolean respectReserved) throws IOException { int c=is.read(); if (c==-1) throw new EOFException(); if (strictR5RS && respectReserved && in((char)c, reserved)) throw new IOException(Util.liMessage(Util.SISCB, "reservedchar", new String(new char[] { ((char)c)}))); if (!handleEscapes || c!='\\') return c; int rv=CharUtil.escapeSequenceToChar(is); return (invertEscaped ? -rv : rv); } public String readToEndOfString(PushbackReader is) throws IOException { StringBuffer b=new StringBuffer(); do { int x=readPureChar(is); if (x=='"') break; b.append((char)x); } while(true); return b.toString(); } public String readToBreak(PushbackReader is, char[] stops, boolean handleEscapes, boolean ignoreEscapedBreaks) throws IOException { StringBuffer b=new StringBuffer(); char c; try { do { int x=readChar(is, handleEscapes, true, true); boolean escaped=(x < 0); if (escaped) //Escaped character c=(char)-x; else c=(char)x; if (in(c, stops) && !(ignoreEscapedBreaks && escaped)) break; b.append(c); } while (true); is.unread(c); } catch (EOFException e) { } return b.toString(); } public static boolean numberStart(char c, int radix) { return Character.isDigit(c) || in(c, (radix == 16 ? hex_number_prefixes : number_prefixes)); } public static boolean in(char c, char[] set) { for (int i=set.length-1; i>-1; i--) if (c>set[i]) return false; else if (c==set[i]) return true; return false; } public static boolean contains(String c, char[] set) { for (int i=0; i= 0); } catch (EOFException e) { System.err.println(Util.warn("eofbeforeeoc")); throw e; } } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/reader/CharUtil.java0000644000175000017500000001255511445752462017523 0ustar amoeamoepackage sisc.reader; import java.io.*; import sisc.util.Util; import java.util.Hashtable; import sisc.data.SchemeCharacter; public abstract class CharUtil { private static final Hashtable humanReadables=new Hashtable(8); private static void register(char c, String name) { SchemeCharacter sc=new SchemeCharacter(c); humanReadables.put(sc, name); humanReadables.put(name, sc); } static { register(' ', "space"); register('\u0008', "backspace"); register('\u007f', "rubout"); register('\u000c', "page"); register('\t', "tab"); register('\n', "newline"); register('\r', "return"); register((char)0, "nul"); } /** * Converts a human readable character name into the SchemeCharacter it represents. * * @param namedCharConstant The human readable name of the character, e.g. "tab" * @return The SchemeCharacter named, or null if no such character exists */ public static SchemeCharacter namedConstToChar(String namedCharConstant) { return (SchemeCharacter)humanReadables.get(namedCharConstant); } /** * Retreives the human readable character name of the given SchemeCharacter * * @param c The SchemeCharacter to attempt to convert * @return The SchemeCharacter The human readable name of the character, e.g. "tab", or * null if no human readable name exists */ public static String charToNamedConst(SchemeCharacter c) { return (String)humanReadables.get(c); } /** * Converts an escaped character to its real equivalent * * @param c The character following the escape char ('\') * @return The real character represented by the escaped input */ public static int escapedToChar(char c) { //escaping rules are those defined by Java, except we don't //handle octal escapes. switch (c) { case '"': return c | 0x80000000; case 'b': return '\b'; case 't': return '\t'; case 'n': return '\n'; case 'f': return '\f'; case 'r': return '\r'; default: return c; } } public static int escapeSequenceToChar(PushbackReader is) throws IOException { int c=is.read(); if (c=='u') { char[] hexChars=new char[4]; for (int i=0; i '~') return "u"+charToHex(c); else return null; } } public static String charToEscaped(char c) { String escapedChar=charToEscapedIfNecessary(c); if (escapedChar==null) return new String(new char[] {c}); else return escapedChar; } public static char octToChar(String oct) { return (char)Integer.parseInt(oct, 8); } public static char hexToChar(String hex) { return (char)Integer.parseInt(hex, 16); } public static String charToOct(char c) { return Util.justify(Integer.toOctalString(c),3,'0'); } public static String charToHex(char c) { return Util.justify(Integer.toHexString(c),4,'0'); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/reader/Parser.java0000644000175000017500000005332011445752462017237 0ustar amoeamoepackage sisc.reader; import java.io.*; import java.util.*; import sisc.data.*; import sisc.util.Util; import sisc.exprs.AnnotatedExpr; import sisc.util.Defaults; import sisc.compiler.*; /** * Receives tokens from the Lexer and parses them into valid * s-expressions. */ public class Parser extends Util implements Tokens { /* Strict R5RS Syntax Helper Functions */ public static boolean isPeculiarIdentifier(String s) { return (s.equals("+") || s.equals("-") || s.equals("...")); } public static final int PRODUCE_IMMUTABLES =0x1, PRODUCE_ANNOTATIONS=0x2, STRICT_R5RS =0x4, CASE_SENSITIVE =0x8, READING_VECTOR =0x10, PERMISSIVE_PARSING =0x20; public boolean annotate = Defaults.EMIT_ANNOTATIONS; public Lexer lexer; static final Object DOT= new Object() { public String toString() { return "."; } }; static final Object ENDPAIR= new Object() { public String toString() { return ")"; } }; static final Symbol SYNTAX=Symbol.get("syntax"), ANNOTATION=Symbol.get("make-annotation"); static final HashMap chars=new HashMap (8); static { chars.put("space", new SchemeCharacter(' ')); chars.put("backspace", new SchemeCharacter('\u0008')); chars.put("rubout", new SchemeCharacter('\u007f')); chars.put("page", new SchemeCharacter('\u000c')); chars.put("tab", new SchemeCharacter('\t')); chars.put("return", new SchemeCharacter('\r')); chars.put("newline", new SchemeCharacter('\n')); chars.put("nul", new SchemeCharacter((char)0)); } public Parser(Lexer l) { this.lexer=l; } void warn(String messageClass, PushbackReader is) { if (is instanceof SourceReader) { SourceReader sp=(SourceReader)is; System.err.println(warn(messageClass, sp.sourceFile, sp.line, sp.column)); } else { System.err.println(warn(messageClass)); } } public final Value nextExpression(PushbackReader is) throws IOException { return nextExpression(is, PRODUCE_IMMUTABLES, EMPTYLIST); } public final Value nextExpression(PushbackReader is, int flags, Pair anns) throws IOException { return nextExpression(is, 10, flags, anns); } public final Value nextExpression(PushbackReader is, int radix, int flags) throws IOException { return nextExpression(is, radix, flags, EMPTYLIST); } /** * Reads an s-expression from the given input port. * * @param is PushbackReader from which to read * @param radix Specifies the radix of any numbers that are read * @param flags Specifies attributes for the returned values (PRODUCE_IMMUTABLES, PRODUCE_ANNOTATIONS, STRICT_R5RS) * @param anns additional annotations * @return the read expression * @exception IOException if an error occurs */ public Value nextExpression(PushbackReader is, int radix, int flags, Pair anns) throws IOException { Object n=VOID; try { n=_nextExpression(is, new HashMap (), null, radix, flags, anns); return (Value)n; } catch (ClassCastException ce) { if (n==ENDPAIR) { potentialError(flags, "orphanedparen", is); return nextExpression(is, radix, flags, anns); } else if (n==DOT) throw new IOException(liMessage(SISCB, "unexpecteddot")); } return (Value)n; } protected final Value nextExpression(PushbackReader is, HashMap state, int flags, Pair anns) throws IOException { return (Value)_nextExpression(is, state, null, flags, anns); } protected void potentialError(int flags, String message, PushbackReader is) throws IOException { if (permissiveParsing(flags)) if (is==null) System.err.println(warn(message)); else warn(message, is); else throw new IOException(liMessage(SISCB, message)); } protected void potentialError(int flags, String message, String arg, PushbackReader is) throws IOException { if (permissiveParsing(flags)) if (is==null) System.err.println(warn(message, arg)); else System.err.println(warn(liMessage(SISCB, message, arg))); else throw new IOException(liMessage(SISCB, message, arg)); } private Value lastValue(HashMap state, Object l) { return (Value)(l instanceof Integer ? state.get(l) : l); } protected Object _nextExpression(PushbackReader is, HashMap state, Integer def, int flags, Pair anns) throws IOException { return _nextExpression(is, state, def, 10, flags, anns); } protected Quantity numberCheck(Object o, PushbackReader is, int flags) throws IOException { try { return (Quantity)o; } catch (ClassCastException cce) { potentialError(flags, "badtokennotnumber", is); return Quantity.ZERO; } } protected Object listSpecial(Symbol car, PushbackReader is, HashMap state, Integer def, int flags, Pair anns) throws IOException { boolean produceImmutables = produceImmutables(flags); Pair t = (produceImmutables ? new ImmutablePair(EMPTYLIST, EMPTYLIST, false) : new Pair(EMPTYLIST, EMPTYLIST)); Pair p = (produceImmutables ? new ImmutablePair(car, t) : new Pair(car, t)); if (def!=null) state.put(def, p); t.setCar(nextExpression(is, state, flags, anns)); if (produceImmutables) { ((ImmutablePair)t).makeImmutable(); } return p; } protected Object _nextExpression(PushbackReader is, HashMap state, Integer def, int radix, int flags, Pair anns) throws IOException { int line=-1, col=-1; String file=null; int token=lexer.nextToken(is, radix); Object o; switch (token) { case TT_EOF: return EOF; case TT_DOT: o=DOT; break; case TT_UNQUOTE: o=listSpecial(UNQUOTE, is, state, def, flags, anns); break; case TT_UNQUOTE_SPLICING: o=listSpecial(UNQUOTE_SPLICING, is, state, def, flags, anns); break; case TT_QUOTE: o=listSpecial(QUOTESYM, is, state, def, flags&(~PRODUCE_ANNOTATIONS), anns); break; case TT_BACKQUOTE: o=listSpecial(BACKQUOTE, is, state, def, flags, anns); break; case TT_NUMBER: o=lexer.nval; break; case TT_STRING: o=new ImmutableString(lexer.sval); break; case TT_PAIR: //Annotation support if (is instanceof SourceReader) { SourceReader sip=(SourceReader)is; line=sip.line; col=sip.column-1; file=sip.sourceFile; } if (annotate && produceAnnotations(flags) && line>=0) { AnnotatedExpr aexp = new AnnotatedExpr(null, sourceAnnotations(file, line, col, anns)); if (def != null) { state.put(def, aexp); def = null; } aexp.expr=readList(is, state, def, flags, anns); return aexp; } else { return readList(is, state, def, flags, anns); } case TT_ENDPAIR: o=ENDPAIR; break; case TT_PIPE: Symbol sym=Symbol.intern(lexer.readToBreak(is, Lexer.protected_literal_barrier, true, true)); // Discard the closing PIPE lexer.readChar(is); return sym; case TT_SYMBOL: if (lexer.strictR5RS && !isPeculiarIdentifier(lexer.sval) && lexer.sval.length() >= 1 && !(Character.isLetter(lexer.sval.charAt(0)) || Lexer.in(lexer.sval.charAt(0), Lexer.special_initials))) potentialError(flags, "invalididentifier", lexer.sval, is); o=Symbol.get(lexer.sval, caseSensitive(flags)); break; case TT_SHARP: int c=is.read(); char dc=Character.toLowerCase((char)c); //Which type of sharp do we have? switch (dc) { case 't': o=TRUE; break; case 'f': o=FALSE; break; //SISC supports s-expression commenting case ';': nextExpression(is); o=_nextExpression(is, state, def, flags, anns); break; case '\\': c=is.read(); if (Lexer.in((char)c, Lexer.special)) { o=new SchemeCharacter((char)c); break; } is.unread(c); String cn=lexer.readToBreak(is, Lexer.special, false, false); String cnl=cn.toLowerCase(); Object cs=CharUtil.namedConstToChar(cnl); try { if (cs!=null) { o=cs; } else if (cn.length()==1) { o=new SchemeCharacter(cn.charAt(0)); } else if (cn.charAt(0)=='u') { o=new SchemeCharacter(CharUtil.hexToChar(cnl.substring(1))); } else { o=new SchemeCharacter(CharUtil.octToChar(cnl)); } } catch (NumberFormatException nfe) { potentialError(flags, "invalidcharconst", is); o=new SchemeCharacter('\u0000'); } break; case 'b': o=numberCheck(_nextExpression(is, state, null, 2, flags, anns), is, flags); break; case 'o': o=numberCheck(_nextExpression(is, state, null, 8, flags, anns), is, flags); break; case 'x': o=numberCheck(_nextExpression(is, state, null, 16, flags, anns), is, flags); break; case 'd': o=numberCheck(_nextExpression(is, state, null, flags, anns), is, flags); break; case '&': o=new Box(); if (def!=null) state.put(def, o); ((Box)o).val=(Value)_nextExpression(is, state, null, flags, anns); break; case 'i': o=numberCheck(_nextExpression(is, state, null, radix, flags, anns), is, flags).toInexact(); break; case 'e': o=numberCheck(_nextExpression(is, state, null, radix, flags, anns), is, flags).toExact(); break; case '!': String bv=lexer.readToBreak(is, Lexer.special, false, false); if (bv.equals("eof")) o=EOF; else if (bv.equals("void")) o=VOID; else if (bv.equals("+inf")) o=Quantity.POSITIVE_INFINITY; else if (bv.equals("-inf")) o=Quantity.NEGATIVE_INFINITY; else if (bv.equals("nan")) o=Quantity.NaN; else { potentialError(flags, "invalidsharpc", bv, is); o=VOID; } break; case '%': // Syntactic tokens bv=lexer.readToBreak(is, Lexer.special, false, false).toLowerCase(); Syntax s=(Syntax)CompilerConstants.SYNTACTIC_TOKENS.get(bv); if (s==null) { potentialError(flags, "invalidsyntoken", bv, is); s=(Syntax)CompilerConstants.SYNTACTIC_TOKENS.get("unknown"); } o=s; break; case '\'': o=listSpecial(SYNTAX, is, state, def, flags, anns); break; case '@': //Annotation Pair p=(Pair)nextExpression(is, state, flags, anns); o=new AnnotatedExpr(p.cdr(), p.car()); break; case '|': //PushbackReader is, HashMap state, Integer def, int radix, int flags //Nested multiline comment lexer.skipMultilineComment(is); return _nextExpression(is, state, def, radix, flags, anns); default: Value[] v=null; is.unread(c); if (Character.isDigit((char)c)) { Integer ref= new Integer(Integer .parseInt(lexer .readToBreak(is, Lexer .sharp_special, false, false))); c=is.read(); if (c=='=') { o=_nextExpression(is, state, ref, flags, anns); break; } else if (c=='#') { o=state.get(ref); break; } else { is.unread(c); v=new Value[ref.intValue()]; } } SchemeVector iv; if (produceImmutables(flags)) iv=new ImmutableVector(); else iv=new SchemeVector(); o=iv; if (def!=null) state.put(def, iv); def=null; Object expr=_nextExpression(is, state, def, flags | READING_VECTOR, anns); if (expr instanceof AnnotatedExpr) { o=new AnnotatedExpr(iv, ((AnnotatedExpr)expr).annotation); expr=((AnnotatedExpr)expr).expr; } if (expr==null && v==null) { iv.vals = ZV; break; } else if (expr instanceof Pair) { if (v==null) v=new Value[length((Pair)expr)]; else if (v.length < length((Pair)expr)) { warn("veclengthtooshort", is); v=new Value[length((Pair)expr)]; } } else if (expr!=null) throw new IOException(liMessage(SISCB,"invalidsharp", expr.toString())); p=(Pair)expr; Object lastObject=Quantity.ZERO; for (int i=0; i * AppContext ctx = ... * Interpreter r=Context.enter(ctx); * r.eval(someProcedure, new Value[] { ... some arguments ... }); * Context.exit(); * * Preferrably, one should use the SchemeCaller supported visitor pattern * to allow Context to handle the management of the Interpreter Context, * as follows: *
 *   Object returnValue=Context.execute(ctx, mySchemeCaller);
 * 
* The provided SchemeCaller instance's execute method is invoked with * an Interpreter which is automatically obtained and then returned when * the call completes. The return value of the SchemeCaller's execute * method is returned from the Context method. * * @see SchemeCaller * @see AppContext * @see Interpreter */ public abstract class Context extends Util { //"appname" -> AppContext private static Map apps = Collections.synchronizedMap(new HashMap()); //Thread -> Context private static ThreadLocal currentThreadContext = new ThreadLocal() { protected Object initialValue() { return new ThreadContext(); } }; private static volatile AppContext defaultAppContext; /*********** application table maintenance ***********/ /** * @deprecated */ public static void register(String appName, AppContext ctx) { apps.put(appName,ctx); } /** * @deprecated */ public static void unregister(String appName) { apps.remove(appName); } /** * @deprecated */ public static AppContext lookup(String appName) { return (AppContext)apps.get(appName); } /*********** thread context lookup ***********/ public static ThreadContext lookupThreadContext() { return (ThreadContext)currentThreadContext.get(); } /*********** main interface ***********/ /** * Fetches the current Interpreter, if this is an internal call (that is, * a call from Java to Scheme in the contex of a Scheme->Java call). * * @return the current Interpreter, or null if this is not an * internal call. */ public static Interpreter currentInterpreter() { ThreadContext tctx = lookupThreadContext(); return tctx.currentInterpreter(); } /** * Fetches the nearest enclosing Interpreter that operates on a * given AppContext, if this is an internal call (that is, a call * from Java to Scheme in the contex of a Scheme->Java call). * * @param ctx the AppContext * @return the nearest enclosing Interpreter operating on the * given ctx, or null if no such Interpreter exists. */ public static Interpreter currentInterpreter(AppContext ctx) { ThreadContext tctx = lookupThreadContext(); return tctx.currentInterpreter(ctx); } /** * Sets the default AppContext, which is used sparingly whenever * a call originates from uncontrolled Java source that involves * the Scheme environment. For example, Java serialization initiated * by a web application server. * * @param ctx the AppContext to make the default. */ public synchronized static void setDefaultAppContext(AppContext ctx) { defaultAppContext = ctx; } /** * Returns the currently set default AppContext, or creates * a new AppContext with default values if non was already set, * and attempts to initialize it with the default heap. * */ public synchronized static AppContext getDefaultAppContext() { if (defaultAppContext == null) { setDefaultAppContext(new AppContext()); try { defaultAppContext.addDefaultHeap(); } catch (IOException e) { throw new RuntimeException(Util.liMessage(Util.SISCB, "errorloadingheap")); } } return defaultAppContext; } /** * Returns the AppContext of any current interpreter in an * internal call, or the default AppContext if no current * interpreter is present. */ public static AppContext currentAppContext() { Interpreter r = currentInterpreter(); return (r == null ? getDefaultAppContext() : r.getCtx()); } /** * Returns an Interpreter that shares the AppContext and * DynamicEnvironment with the current Interpreter. If there is no * current Interpreter present, an Interpreter bound to the * default AppContext is returned instead. * * This method provides the usual mechanism for obtaining an * Interpreter for calling from Java to Scheme. * * @see Interpreter */ public static Interpreter enter() { Interpreter r = currentInterpreter(); return enter(r == null ? new DynamicEnvironment(getDefaultAppContext()) : r.dynenv); } /** * Returns an Interpreter bound to the given AppContext with same * DynamicEnvironment as the nearest enclosing Interpreter in the * same thread that is bound to the same AppContext. If no such * Interpreter exists then a new DynamicEnvironment is created, * bound to the AppContext. * * @param ctx The AppContext * @return The newly created Interpreter */ public static Interpreter enter(AppContext ctx) { Interpreter r = currentInterpreter(ctx); return enter(r == null ? new DynamicEnvironment(ctx) : r.dynenv); } /** * Returns an Interpreter bound to the given DynamicEnvironment. * * @param dynenv The DynamicEnvironment * @return The newly created Interpreter */ public static Interpreter enter(DynamicEnvironment dynenv) { dynenv.bind(); //set thread's context class loader ClassLoader currentClassLoader = Util.currentClassLoader(); ClassLoader newClassLoader = determineClassLoader(currentClassLoader, dynenv.getClassLoader()); Thread currentThread = Thread.currentThread(); try { currentThread.setContextClassLoader(newClassLoader); } catch (java.security.AccessControlException e) { } ThreadContext tctx = lookupThreadContext(); tctx.setHostThread(dynenv, currentThread); Interpreter res = createInterpreter(tctx, dynenv); tctx.pushState(new ThreadContext.State(res, currentClassLoader)); return res; } private static ClassLoader determineClassLoader(ClassLoader currentCL, ClassLoader newCL) { try { for (ClassLoader cl = newCL; cl != null; cl = cl.getParent()) { if (currentCL == cl) return newCL; } } catch (java.security.AccessControlException e) { } return currentCL; } /** * * @deprecated use {@link #enter(AppContext)} instead */ public static Interpreter enter(String appName) { return enter(lookup(appName)); } /** * Exits the current context, releasing the current Interpreter. */ public static void exit() { ThreadContext tctx = lookupThreadContext(); ThreadContext.State s = tctx.popState(); Interpreter r = s.interpreter; returnInterpreter(r); //restore thread's context class loader try { Thread.currentThread().setContextClassLoader(s.classLoader); } catch(java.security.AccessControlException e) { } } /** * Calls caller with an Interpreter that shares the AppContext and * DynamicEnvironment with the current Interpreter. If there is no * current Interpreter present, an Interpreter bound to the * default AppContext is created instead. * * This method provides the usual mechanism for managed calls from * Java to Scheme. * * @param caller The SchemeCaller to invoke * @return the result of invoking the SchemeCaller */ public static Object execute(SchemeCaller caller) throws SchemeException { Interpreter r = currentInterpreter(); return execute((r == null ? new DynamicEnvironment(getDefaultAppContext()) : r.dynenv), caller); } /** * Calls caller with an Interpreter bound to the given AppContext * with same DynamicEnvironment as the nearest enclosing * Interpreter in the same thread that is bound to the same * AppContext. If no such Interpreter exists then a new * DynamicEnvironment is returned, bound to the AppContext. * * @param ctx The AppContext * @param caller The SchemeCaller to invoke. * @return the result of invoking the SchemeCaller */ public static Object execute(AppContext ctx, SchemeCaller caller) throws SchemeException { Interpreter r = currentInterpreter(ctx); return execute((r == null ? new DynamicEnvironment(ctx) : r.dynenv), caller); } /** * Obtains an Interpreter bound to the given DynamicEnvironment * and invokes caller.execute(Interpreter) with that Interper. * Once execute returns, the Interpreter is freed, and the return * value of caller.execute() is returned from this method. * * NB: It is critical that the Interpreter reference provided * during the call is used only in the thread which calls this * method. New threads should obtain a different Interpreter via * this or enter() calls. * * @param dynenv The DynamicEnvironment. * @param caller The SchemeCaller to invoke. * @return the result of invoking the SchemeCaller */ public static Object execute(DynamicEnvironment dynenv, SchemeCaller caller) throws SchemeException { Interpreter r=Context.enter(dynenv); //Hold this reference. Necessary because ThreadContext //references hostThread only weakly, which is in turn //necessary so that when threads terminate their associated //SISC resources are garbage collected. In this case, //however, we want to guarantee that during the lifetime of //the call, the SchemeThread wrapper object remains available Object t=r.tctx.hostThread.get(); try { return caller.execute(r); } finally { if (r!=null) Context.exit(); } } /** * @deprecated use {@link #execute(AppContext, SchemeCaller)} instead */ public static Object execute(String appName, SchemeCaller caller) { //Since this is deprecated, we'll catch the exception to preserve //backwards compatibility through one release. try { return execute(lookup(appName), caller); } catch (SchemeException se) { System.err.println(warn("SchemeException caught from execute:" + se.getMessage())); return null; } } /*********** resource maintenance ***********/ /** * We could use a pool of interpreters. However, * a) interpreter creation is quite cheap, and * b) pool maintenance would require thread synchronization */ private static Interpreter createInterpreter(ThreadContext tctx, DynamicEnvironment dynenv) { return new Interpreter(tctx, dynenv); } private static void returnInterpreter(Interpreter r) { } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/interpreter/SchemeCaller.java0000644000175000017500000000423411445752462021433 0ustar amoeamoepackage sisc.interpreter; /** * Defines a visitor interface for performing Java -> Scheme calls * in an 'atomic' fashion, where details of acquiring and releasing * the Interpreter context are done behind the scenes. * * @see Context */ public interface SchemeCaller { /** * The execute callback function is called by Context * with a fresh Interpreter context which is valid only * during the call to execute. * * @param r An Interpreter context * @return Any arbitrary return value, which will * be returned out of the call to Context.execute() * @see sisc.interpreter.Context#execute(AppContext, SchemeCaller) */ public Object execute(Interpreter r) throws SchemeException; } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/interpreter/SchemeException.java0000644000175000017500000000641411445752462022171 0ustar amoeamoepackage sisc.interpreter; import java.io.PrintStream; import java.io.PrintWriter; import sisc.util.Util; import sisc.data.Value; import sisc.data.Symbol; import sisc.data.Pair; import sisc.data.Procedure; import sisc.data.SchemeString; import sisc.interpreter.Context; import sisc.interpreter.SchemeCaller; import sisc.interpreter.Interpreter; public class SchemeException extends Exception { public Pair m; public Procedure e, f; public SchemeException(Pair message, Procedure exception_k, Procedure parent_fk) { m=message; e=exception_k; f=parent_fk; } /** * @return the Scheme message Pair as String */ public String getMessage() { return m.toString(); } /** * @return the bare Scheme message text */ public String getMessageText() { return ((Pair)m.car()).cdr().toString(); } private String schemeStackTrace() { try { SchemeString res = (SchemeString)Context.execute(new SchemeCaller() { public Object execute(Interpreter r) throws SchemeException { Procedure converter = (Procedure)r.lookup(Symbol.get("error->string"), Util.TOPLEVEL); return r.eval(converter, new Value[]{m,e}); } }); return "Scheme exception:\n" + res.asString(); } catch (Exception e) { return ""; } } public void printStackTrace(PrintStream s) { super.printStackTrace(s); s.print(schemeStackTrace()); } public void printStackTrace(PrintWriter s) { super.printStackTrace(s); s.print(schemeStackTrace()); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/interpreter/ContinuationException.java0000644000175000017500000000314611445752462023436 0ustar amoeamoepackage sisc.interpreter; public class ContinuationException extends Exception { public CallFrame k; public ContinuationException(CallFrame k) { this.k=k; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/interpreter/Interpreter.java0000644000175000017500000005321711445752462021414 0ustar amoeamoepackage sisc.interpreter; import java.io.*; import sisc.compiler.Compiler; import sisc.data.*; import sisc.env.*; import sisc.ser.Deserializer; import sisc.ser.Serializer; import sisc.util.Util; /** * The SISC engine. *

* Interpreter is the SISC engine. It contains the engine registers, * and the main loop responsible for repeatedly executing the * nxp register and maintaining the stack. Interpreter also * localizes all thread-specific information. Interpreters must only * execute in the thread which created them. Furthermore, nested calls * from Java into Scheme must be carried out in fresh interpreter * instances; thus at any point in time a thread contains a stack of * interpreters, the top of which is the interpreter currently in use. *

*

* Additionally, it is the interface from Java code for evaluating * Scheme code or calling Scheme procedures. *

* @see Context */ public class Interpreter extends Util { private final static Expression EVAL_APPEVAL = annotatedAppEval("eval"); private final static Expression CONTINUATION_APPEVAL = annotatedAppEval("continuation"); private static Expression annotatedAppEval(String fn) { return annotatedAppEval(Interpreter.class, fn); } public static class ThrowSchemeException extends Expression { public void eval(Interpreter r) throws ContinuationException, SchemeRuntimeException { r.nxp=null; Values v=(Values)r.acc; throw new SchemeRuntimeException(pair(v.values[0]), proc(v.values[1]), v.values.length>2 ? proc(v.values[2]) : //If we are at the top of the //stack, use a default fk (r.fk == null ? top_fk : r.fk)); } public Value express() { return list(Symbol.get("TSException")); } public void serialize(Serializer s) throws IOException {} public void deserialize(Deserializer s) throws IOException {} } //the compiler is stateless; if that ever changes it would need to //be moved to the dynenv public static Compiler compiler = new Compiler(); public ThreadContext tctx; public DynamicEnvironment dynenv; //FLAGS private boolean saveVLR; //prevent recycling of VLR after procedure //invocation //Interpreter specific temporaries public Value[][] IAI=new Value[][] {new Value[1], new Value[2], new Value[3]}; //ACCOUNTING REGISTERS private boolean vlk; //vlk, when true, indicates the //frame was captured. //ACTIVITY REGISTERS public Value acc; //Accumulator public Expression nxp; //Next Expression public Value[] vlr, //Value Rib lcl, //Local Variables env; //Lexical Variables private CallFrame stk; //Continuation (Stack) public CallFrame fk; //Failure Continuation public SymbolicEnvironment tpl; //Top-level environment private StackTracer tracer; //for stack tracking //Scheme->Java exception conversion FK static CallFrame top_fk = new CallFrame(new ThrowSchemeException(), null, false, null, null, null, null, null, null); static { top_fk.vlk = true; // This creates a loop in the stack, which will be a problem for // any code checking for null as the bottom of the stack. However, // the only code in SISC which does this is CallFrame.capture(), which // will also break when vlk=true. top_fk.fk=top_fk; } public Interpreter(ThreadContext tctx, DynamicEnvironment dynenv) { fk=top_fk; this.tctx = tctx; this.dynenv = dynenv; tpl=getCtx().toplevel_env; } public AppContext getCtx() { return dynenv.ctx; } public Symbol getSymbol(String v) { return Symbol.get(v, dynenv.caseSensitive); } public Expression compile(Value v) throws ContinuationException { return compile(v, getCtx().toplevel_env); } public Expression compile(Value v, SymbolicEnvironment env) throws ContinuationException { return compiler.compile(this, v, env); } public Value interpret(Expression e) throws SchemeException { SymbolicEnvironment tpl=getCtx().toplevel_env; stk=createFrame(null, null, false, null, null, tpl, top_fk, null, null); tracer = makeStackTracer(); nxp=e; this.tpl=tpl; interpret(); return acc; } protected void interpret() throws SchemeException { try { do { try { do { while (nxp==null) pop(stk); nxp.eval(this); } while (true); } catch (ContinuationException ce) { pop(ce.k); } } while (true); } catch (NullPointerException done) { if (nxp!=null) { try { error(this, null, done.getMessage(), done); } catch (ContinuationException ce) { pop(ce.k); interpret(); } } } catch (SchemeRuntimeException rte) { throw rte.promote(); } } public final void next(Expression nextExpr) throws ContinuationException { nxp=nextExpr; nextExpr.eval(this); } public final void newVLR(int size) { newVLR(createValues(size)); } public final void newVLR(Value[] vlr) { if (vlk) { tracer = copyStackTracer(); vlk=false; } this.vlr=vlr; } public final void pop(CallFrame c) { nxp=c.nxp; vlr=c.vlr; lcl=c.lcl; env=c.env; tpl=c.tpl; fk=c.fk; stk=c.parent; vlk=c.vlk; tracer=c.tracer; returnFrame(c); } public final StackTracer makeStackTracer() { int depth=dynenv.getMaxStackTraceDepthAsInt(); return (depth == 0 ? null : new StackTracer(depth)); } private final StackTracer copyStackTracer() { return (tracer == null ? null : tracer.copy()); } private final void makeSafe() { /* The frame which contains the current vlr has been captured by a continuation. As a result, several, possibly concurrent, evaluations may reach it. In order to prevent these evaluations from stepping on eachother's toes (i.e. modify the same vlr), we copy the vlr before writing to it. The copy does not need to be marked as captured since it is private to the current computation. */ Value[] newvlr = createValues(vlr.length); System.arraycopy(vlr, 0, newvlr, 0, vlr.length); vlr = newvlr; vlk = false; tracer = copyStackTracer(); } public final void setVLR(int pos, Value v) { if (vlk) makeSafe(); vlr[pos]=v; } private final CallFrame createEmptyFrame(Expression e, CallFrame p, StackTracer t) { return createFrame(e, null, false, null, null, null, top_fk, p, t); } private final CallFrame createNearlyEmptyFrame(Expression e, CallFrame p, StackTracer t) { return createFrame(e, null, false, null, null, tpl, fk, p, t); } public final void pushExpr(Expression e) { stk = createNearlyEmptyFrame(e, stk, tracer); tracer = makeStackTracer(); } public final void setFailureContinuation(Expression e) { fk = createNearlyEmptyFrame(e, stk, copyStackTracer()); } private final Procedure createContinuation(CallFrame p) { //In order to produce accurate stack traces for ks we insert a //dummy frame with a copy of the current frame's stack trace. //The CONTINUATION_APPEVAL nxp of the dummy frame is only //there in order to avoid a harmless, but ugly, null nxp. //It is never evaluated. if (tracer == null) return p; else return new ApplyParentFrame(createEmptyFrame(CONTINUATION_APPEVAL, p, tracer.copy())); } public final Procedure captureContinuation() { return createContinuation(stk.capture(this)); } public final Procedure captureEscapingContinuation() { //Even though we're not capturing for long term preservation, we must protect this individual //call frame from being recycled, mostly for error handling. stk.vlk=true; return createContinuation(stk); } public void trace(Expression e) { if (tracer != null) { if (vlk) { if (vlr == null) vlr = ZV; //rare, but can happen makeSafe(); } tracer.add(e); } } public void error(Pair error) throws ContinuationException { Procedure k = new ApplyParentFrame(createEmptyFrame(nxp, stk.capture(this), copyStackTracer())); acc = new Values(new Value[] { error, k }); throw new ContinuationException(fk); } /** * Parses and evaluates s-expression(s) from an input port * * @param port input port * @return The value of the last evaluated s-expression * @exception IOException Raised if the port does not * contain a parseable s-expression * @exception SchemeException Raised if the evaluation of * an expression results in an error */ public Value evalInput(PushbackReader port) throws IOException, SchemeException { Value rv=VOID; do { try { rv=eval(dynenv.parser.nextExpression(port)); } catch (EOFException e) { return rv; } } while (true); } /** * Parses and evaluates s-expression(s) * * @param expr s-expressions(s) * @return The value of the last evaluated s-expression * @exception IOException Raised if the given string does not * contain a parseable s-expression * @exception SchemeException Raised if the evaluation of * an expression results in an error */ public Value eval(String expr) throws IOException, SchemeException { return evalInput(new PushbackReader(new BufferedReader(new StringReader(expr)))); } /** * Evaluates a Scheme value as code. This is equivalent to * (eval v) in Scheme. * * @param v A Scheme Value * @return The resulting value * @exception SchemeException Raised if the evaluation of the * expression results in an error */ public Value eval(Value v) throws SchemeException { return eval(v, getCtx().toplevel_env); } /** * Evaluates a Scheme value as code. This is equivalent to * (eval v e) in Scheme. * * @param v A Scheme Value * @param env The environment in which to evaluate the value * @return The resulting value * @exception SchemeException Raised if the evaluation of the * expression results in an error */ public Value eval(Value v, SymbolicEnvironment env) throws SchemeException { return eval((Procedure)lookup(EVAL, REPORT), new Value[] {v, env.asValue()}); } /** * Applies the given procedure to the given values * * @param p A procedure * @param args Arguments to call the procedure with * @return The result returned by the procedure * @exception SchemeException Raised if applying the * procedure results in an error */ public Value eval(Procedure p, Value[] args) throws SchemeException { acc = p; vlr = args; return interpret(EVAL_APPEVAL); } /** * Loads zero or more Scheme source files or compiled libraries. * * @param files An array of Strings naming files to load. * @return true on success, false if any source file produced * an error. */ public boolean loadSourceFiles(String[] files) { boolean returnStatus = true; Procedure load = (Procedure)lookup(Symbol.get("load"), Util.TOPLEVEL); for (int i=0; i= FRAMEPOOLMAX) return; //Clear some fields to avoid hanging onto otherwise //garbage collectable data for too long f.clear(); f.parent=frameFreeList; frameFreeList = f; frameFreeListSize++; } protected Value dv1[], dv2[], dv3[], dv4[]; public final Value[] createValues(int size) { Value[] rv; switch(size) { case 0: return ZV; case 1: if (dv1 != null) { rv=dv1; dv1=null; return rv; } break; case 2: if (dv2 != null) { rv=dv2; dv2=null; return rv; } break; case 3: if (dv3 != null) { rv=dv3; dv3=null; return rv; } break; case 4: if (dv4 != null) { rv=dv4; dv4=null; return rv; } break; } return new Value[size]; } public final void returnVLR() { if (saveVLR) { saveVLR = false; } else { if (!vlk) returnValues(vlr); vlr=null; } } public final void setupTailCall(Expression e, Value vlr0) { saveVLR = true; nxp = e; if (vlk) { newVLR(1); } else { if (vlr.length != 1) { returnValues(vlr); newVLR(1); } } vlr[0] = vlr0; } public final void setupTailCall(Expression e, Value[] newvlr) { saveVLR = true; nxp = e; if (!vlk) { returnValues(vlr); } vlr = newvlr; } public final void returnValues(Value[] v) { switch(v.length) { case 4: v[3]=v[2]=v[1]=v[0]=null; dv4=v; break; case 3: v[2]=v[1]=v[0]=null; dv3=v; break; case 2: v[1]=v[0]=null; dv2=v; break; case 1: v[0]=null; dv1=v; break; } } /** * Returns a Value[] prepared as a value rib * for a procedure with a fixed argument count. * This may or may not clone the VLR depending on * whether it is safe to not do so. */ public Value[] vlrToArgs() { Value[] vals; if (vlk) { vals=createValues(vlr.length); System.arraycopy(vlr, 0, vals, 0, vals.length); } else { vals=vlr; } return vals; } /** * Returns a Value[] prepared as a value rib for a * for procedure expecting rest args in the last * rib position. This may or may not clone the VLR * depending on whether it is safe to not do so. * * @param fcount The number of arguments to prepare * including the rest variable */ public Value[] vlrToRestArgs(int fcount) { Value[] vals; int sm1=fcount - 1; int vl=vlr.length; if (vl < fcount || vlk) { /** * We must copy the vlr if its locked, * otherwise we may side-effect a captured vlr by * creating the rest argument. * * @see Closure.matchArgs */ vals=createValues(fcount); System.arraycopy(vlr, 0, vals, 0, sm1); vals[sm1]=valArrayToList(vlr, sm1, vl-sm1); returnVLR(); //NB: this checks vlk first } else { vals=vlr; vals[sm1]=valArrayToList(vlr, sm1, vl-sm1); } return vals; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/interpreter/ApplyParentFrame.java0000644000175000017500000000454111445752462022317 0ustar amoeamoepackage sisc.interpreter; import java.io.*; import sisc.data.*; import sisc.io.ValueWriter; import sisc.ser.Serializer; import sisc.ser.Deserializer; import sisc.util.ExpressionVisitor; public class ApplyParentFrame extends Procedure { public CallFrame c; public ApplyParentFrame() {} public ApplyParentFrame(CallFrame cf) { this.c=cf; } public void apply(Interpreter r) throws ContinuationException { c.parent.apply(r); } public void display(ValueWriter w) throws IOException { displayNamedOpaque(w, liMessage(SISCB, "continuation")); } public Value express() { return list(sym("cont"), c); } public void serialize(Serializer s) throws IOException { s.writeExpression(c); } public void deserialize(Deserializer s) throws IOException { c=(CallFrame)s.readExpression(); } public boolean visit(ExpressionVisitor v) { return v.visit(c); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/interpreter/CallFrame.java0000644000175000017500000001340011445752462020725 0ustar amoeamoepackage sisc.interpreter; import java.io.*; import sisc.data.*; import sisc.env.SymbolicEnvironment; import sisc.io.ValueWriter; import sisc.util.ExpressionVisitor; import sisc.ser.Serializer; import sisc.ser.Deserializer; public class CallFrame extends Procedure { public Expression nxp; public Value[] vlr, lcl, env; public boolean vlk; //indicates that this frame has //been captured by a continuation public CallFrame fk, parent; public SymbolicEnvironment tpl; //The currently active top-level environment public StackTracer tracer; public CallFrame(Expression n, Value[] v, boolean vk, Value[] l, Value[] e, SymbolicEnvironment t, CallFrame f, CallFrame p, StackTracer tr) { /* We really just want to call init(n,v,vk,l,e,t,f,p) here but that seems lose us 2% on gabriel benchmarks, at least on Sun's 1.5.0_05-b05 JVM on Linx 2.6.8-1-686-smp. */ nxp=n; vlr=v; vlk=vk; lcl=l; env=e; tpl=t; fk=f; parent=p; tracer=tr; } public final void init(Expression n, Value[] v, boolean vk, Value[] l, Value[] e, SymbolicEnvironment t, CallFrame f, CallFrame p, StackTracer tr) { nxp=n; vlr=v; vlk=vk; lcl=l; env=e; tpl=t; fk=f; parent=p; tracer=tr; } public final void clear() { vlr=lcl=env=null; fk=parent=null; tpl=null; tracer=null; } public final CallFrame capture(Interpreter r) { // Set the captured flags all the way to the root. for (CallFrame w=this; w!=null && !w.vlk; w=w.parent) { w.vlk=true; } return this; } public void display(ValueWriter w) throws IOException { displayNamedOpaque(w, "continuation"); } public static boolean visitValueArray(ExpressionVisitor v, Value[] va) { if (va==null) return true; for (int i=0; ithe token used by most Java to Scheme operations. *

* Typically, an AppContext is created using the default constructor, * then initialized with a heap using utility methods in {@link sisc.REPL}. * **/ public class AppContext extends Util { public SymbolicEnvironment symenv; public SymbolicEnvironment toplevel_env; private LibraryManager libraries; private Properties props; /** * Create a new, AppContext with default values, * the recommended constructor for normal usage. * */ public AppContext() { this(new Properties()); } /** * Create a new AppContext, providing a set of properties explicitly. * * @param props Properties which govern the * underlying Scheme environment. */ public AppContext(Properties props) { this.props = props; libraries=new LibraryManager(this); } /** * Create a new AppContext, providing a custom global environment. * * @param symenv the global environment */ public AppContext(SymbolicEnvironment symenv) { this(); this.symenv = symenv; try { toplevel_env=lookupContextEnv(TOPLEVEL); } catch (ArrayIndexOutOfBoundsException ue) { toplevel_env=symenv; symenv.define(TOPLEVEL, toplevel_env.asValue()); } } public Expression getExpression(Symbol name) { try { return libraries.getExpression(name); } catch(java.io.IOException e) { return null; } } // Heapfile loading/saving public void loadEnv(SeekableDataInputStream i) throws IOException, ClassNotFoundException { Library s=Library.load(this, i); libraries.addLibrary(s); SymbolicEnvironment lsymenv=(SymbolicEnvironment)s.getExpression(SYMENV); try { symenv=lsymenv; try { toplevel_env=lookupContextEnv(TOPLEVEL); } catch (ArrayIndexOutOfBoundsException e) { e.printStackTrace(); throw new IOException("Heap did not contain toplevel environment!"); } } catch (Exception e) { e.printStackTrace(); throw new IOException(e.getMessage()); } } public void saveEnv(OutputStream o, LibraryBuilder lb) throws IOException { lb.add(SYMENV, symenv.asValue()); lb.add(TOPLEVEL, toplevel_env.asValue()); lb.buildLibrary("sisc", o); } public SymbolicEnvironment lookupContextEnv(Symbol s) { SymbolicEnvironment senv = (SymbolicEnvironment)symenv.lookup(s); if (senv == null) throw new ArrayIndexOutOfBoundsException(); return senv; } public void defineContextEnv(Symbol s, SymbolicEnvironment env) { symenv.define(s, env.asValue()); } public String getProperty(String name) { String res = props.getProperty(name); if (res != null) return res; try { res = System.getProperty(name); } catch (SecurityException e) {} return res; } public String getProperty(String name, String def) { String res = getProperty(name); return (res == null) ? def : res; } public Expression resolveBinding(LibraryBinding lb) throws IOException { return libraries.resolveBinding(lb); } public LibraryBinding lookupBinding(Expression e) throws IOException { return libraries.lookupBinding(e); } /** * Given a SeekableInputStream which * is attached to a SISC heap file, loads the heap into this * AppContext and initializes it. Returns true on success, * false otherwise. */ public boolean addHeap(SeekableInputStream in) throws ClassNotFoundException { try { loadEnv(new SeekableDataInputStream(in)); } catch (IOException e) { System.err.println("\n"+Util.liMessage(Util.SISCB, "errorloadingheap")); e.printStackTrace(); return false; } Interpreter r=Context.enter(this); try { try { File[] roots=File.listRoots(); SchemeString[] rootss=new SchemeString[roots.length]; for (int i=0; i"sisc.shp". * * @param heapLocation The URL for the heap file. When * this is null it defaults to the value of the * sisc.heap system property and, if that is not present, * "sisc.shp" */ public static URL findHeap(URL heapLocation) { if (heapLocation==null) { try { heapLocation = Util.makeURL(System.getProperty("sisc.heap")); } catch (SecurityException se) {} if (heapLocation == null) { heapLocation = Util.makeURL("sisc.shp"); } } if (mightExist(heapLocation)) return heapLocation; Class anchor=null; try { anchor=Class.forName("sisc.boot.HeapAnchor"); } catch (ClassNotFoundException cnf) {} if (anchor==null) anchor=AppContext.class; heapLocation = anchor.getResource("/sisc/boot/sisc.shp"); if (mightExist(heapLocation)) return heapLocation; return null; } private static boolean mightExist(URL u) { if (u == null) return false; if (u.getProtocol().equals("file")) { try { return new File(u.getPath()).exists(); } catch (AccessControlException ace) { // Running as an applet. need to actually open the file to try this out: try { u.openStream().close(); return true; } catch (Exception e) { //Oops, guess not return false; } } } else return true; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/interpreter/StackTracer.java0000644000175000017500000002147011445752462021313 0ustar amoeamoepackage sisc.interpreter; import sisc.data.*; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Iterator; import sisc.ser.Deserializer; import sisc.ser.Serializer; import sisc.util.ExpressionVisitee; import sisc.util.ExpressionVisitor; import sisc.util.Util; public class StackTracer implements Cloneable, ExpressionVisitee { private static Symbol UNKNOWN = Symbol.get("?"); private int maxDepth = 16; private List stack = new ArrayList(); private List toAdd = new ArrayList(); private boolean overflown = false; private static class Wrapper { public Expression expr; public Wrapper(Expression expr) { this.expr = expr; } public int hashCode() { return System.identityHashCode(expr); } public boolean equals(Object o) { return (o instanceof Wrapper) && ((Wrapper)o).expr == expr; } } private static class Repetition implements Cloneable { public int count; public List exprs; public Repetition(int count, List exprs) { this.count = count; this.exprs = exprs; } public boolean equals(Object o) { if (!(o instanceof Repetition)) return false; Repetition rp = (Repetition)o; return rp.count == count && rp.exprs.equals(exprs); } public Object clone() throws CloneNotSupportedException { return new Repetition(count, exprs); } public Repetition copy() { try { return (Repetition)clone(); } catch (CloneNotSupportedException e) { return this; } } } public StackTracer(int maxDepth) { this.maxDepth = maxDepth; } // No arg constructor for serialization/deserialization public StackTracer() { } private static boolean addTailToPreceedingRepetition(List l) { /* (... (n x_0 ... x_m) x_0 ... x_m) --> (... (n+1 x_0 ... x_m)) */ int sz = l.size(); for (int i = sz-2; i >= 0; i--) { Object o = l.get(i); if (!(o instanceof Repetition)) continue; Repetition rp = (Repetition)o; List sl = l.subList(i+1, sz); if (rp.exprs.equals(sl)) { rp.count++; sl.clear(); return true; } } return false; } private static boolean createRepetitionFromTail(List l) { /* (... x_0 ... x_m x_0 ... x_m) --> (... (2 x_0 ... x_m)) */ int sz = l.size(); for (int i = sz-1; i >= (sz+1)/2; i--) { List sl = l.subList(i, sz); if (sl.equals(l.subList(2*i-sz, i))) { Repetition rp = new Repetition(2, new ArrayList(sl)); l.subList(2*i-sz, sz).clear(); l.add(rp); return true; } } return false; } private static void compact(List l) { /* This algorithm was kindly donated by Paul Crowley */ while(addTailToPreceedingRepetition(l) || createRepetitionFromTail(l)); } private void addAll() { for (Iterator i = toAdd.iterator(); i.hasNext(); ) { Expression e = (Expression)i.next(); stack.add(new Wrapper(e)); compact(stack); } toAdd.clear(); } public void add(Expression expr) { toAdd.add(expr); //TODO: we should look at the *deep* size of stack here if (toAdd.size() + stack.size() > maxDepth) { addAll(); if (stack.size() > maxDepth) { stack.subList(0, maxDepth/2).clear(); overflown = true; } } } public void clear() { stack.clear(); toAdd.clear(); overflown = false; } public Object clone() throws CloneNotSupportedException { StackTracer res = new StackTracer(maxDepth); res.toAdd.addAll(toAdd); //it's sufficient to create copies of top-level Repetitions, //since these are the only objects that can get modified. for (Iterator i = stack.iterator(); i.hasNext(); ) { Object o = i.next(); res.stack.add((o instanceof Repetition) ? ((Repetition)o).copy() : o); } res.overflown = overflown; return res; } public StackTracer copy() { try { return (StackTracer)clone(); } catch (CloneNotSupportedException e) { return this; } } private static Value deepListToValue(List l) { Pair res = Util.EMPTYLIST; for (Iterator i = l.iterator(); i.hasNext(); ) { Object o = i.next(); if (o instanceof Repetition) { Repetition rp = (Repetition)o; res = new Pair(new Pair(Quantity.valueOf(rp.count), deepListToValue(rp.exprs)), res); } else { res = new Pair(new ExpressionValue(((Wrapper)o).expr), res); } } return res; } public Value toValue() { addAll(); return new Pair(Util.truth(overflown), deepListToValue(stack)); } public void serialize(Serializer s) throws IOException { s.writeInt(maxDepth); s.writeBoolean(overflown); writeList(s, toAdd); writeList(s, stack); } private static final int WRAPPER=0, REPETITION=1, EXPR=2; private static void writeList(Serializer s, List ls) throws IOException { s.writeInt(ls.size()); for (int i=0; i0) datout.write(buffer, 0, rc); } datout.flush(); System.err.println(classes.size()+" classes"); System.err.println(offsets.length+" entry points"); return null; } /*---Serialization first pass functions---*/ public boolean visit(ExpressionVisitee e) { if (e!=null) { serQueue.addFirst(e); if (includeAEs && e instanceof SymbolicEnvironment) { SymbolicEnvironment se=(SymbolicEnvironment)e; if (se.getName()==null) add(se.asValue()); else add(se.getName(),se.asValue()); } } return true; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/BerEncoding.java0000644000175000017500000000547211445752462017516 0ustar amoeamoepackage sisc.ser; import java.io.*; /** * Class for efficient integer representation. A BER encoded integer * is represented as a variable length sequence of bytes, in network-byte * order, with 7 bits of data, and the topmost bit representing a "continue" * flag. If set, another byte follows. This allows numbers in the range * 0-127 to be represented with one byte, 128-16384 in two bytes, etc. */ public abstract class BerEncoding { static final int BER_MASK=0x7f, BER_CONT=0x80; public static void writeBer(long v, DataOutput dos) throws IOException { byte[] b=new byte[10]; int p=9; while (v!=0) { b[p--]=(byte)((v & BER_MASK) | BER_CONT); v>>>=7; } b[9]&=BER_MASK; if (p==9) p=8; dos.write(b, p+1, b.length-(p+1)); } public static long readBerLong(DataInput in) throws IOException { int b=in.readUnsignedByte(); long val=b & BER_MASK; while ((b & BER_CONT) != 0) { b=in.readUnsignedByte(); val=(val<<7) + (b & BER_MASK); } return val; } /*---helper functions---*/ public static short readBerShort(DataInput dis) throws IOException { return (short)BlockDeserializer.readBer(dis); } public static int readBer(DataInput dis) throws IOException { return (int)readBerLong(dis); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/NestedObjectInputStream.java0000644000175000017500000000411311445752462022073 0ustar amoeamoepackage sisc.ser; import java.io.*; import sisc.util.Util; public class NestedObjectInputStream extends ObjectInputStream { private Deserializer d; private ClassLoader cl; NestedObjectInputStream(InputStream out) throws IOException { super(out); cl = Util.currentClassLoader(); } public Deserializer getDeserializerInstance() { return d; } public void setDeserializerInstance(Deserializer d) { this.d = d; } protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { return Class.forName(desc.getName(), true, cl); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/DeserializerImpl.java0000644000175000017500000001203011445752462020567 0ustar amoeamoepackage sisc.ser; import java.io.IOException; import java.io.ObjectInput; import java.math.BigDecimal; import java.math.BigInteger; import sisc.data.Expression; import sisc.data.Value; import sisc.interpreter.AppContext; public abstract class DeserializerImpl extends BerEncoding implements Deserializer { protected AppContext ctx; protected ObjectInput datin; protected DeserializerImpl(AppContext ctx, ObjectInput in) { this.ctx = ctx; datin = in; } public Expression resolveLibraryBinding(LibraryBinding lb) throws IOException { return ctx.resolveBinding(lb); } public BigInteger readBigInteger() throws IOException { byte[] buffer=new byte[readInt()]; readFully(buffer); return new BigInteger(buffer); } public BigDecimal readBigDecimal() throws IOException { byte[] buffer=new byte[readInt()]; int scale=readInt(); readFully(buffer); return new BigDecimal(new BigInteger(buffer), scale); } public int readUnsignedByte() throws IOException { return readByte() & 0xff; } public int readUnsignedShort() throws IOException { return readShort() & 0xffff; } public boolean readBoolean() throws IOException { return datin.readBoolean(); } public byte readByte() throws IOException { return (byte)readBer(datin); } public char readChar() throws IOException { return datin.readChar(); } public double readDouble() throws IOException { return Double.longBitsToDouble(readLong()); } public float readFloat() throws IOException { return Float.intBitsToFloat(readInt()); } public int readInt() throws IOException { return readBer(datin); } public long readLong() throws IOException { return readBerLong(datin); } public short readShort() throws IOException { return readBerShort(datin); } public String readUTF() throws IOException { return datin.readUTF(); } public void readFully(byte[] b) throws IOException { datin.readFully(b); } public void readFully(byte[] b, int offset, int len) throws IOException { datin.readFully(b, offset, len); } public int skipBytes(int bc) throws IOException { return datin.skipBytes(bc); } public int read(byte[] b) throws IOException { return datin.read(b); } public int read(byte[] b, int off, int len) throws IOException { return datin.read(b, off, len); } public int read() throws IOException { return datin.read(); } public String readLine() throws IOException { return datin.readLine(); } public Object readObject() throws IOException, ClassNotFoundException { return datin.readObject(); } public long skip(long n) throws IOException { return datin.skip(n); } public int available() throws IOException { return datin.available(); } public void close() throws IOException { datin.close(); } public Value[] readValueArray() throws IOException { int l=readInt(); Value[] v=new Value[l]; readExpressionArray(v); return v; } public Expression[] readExpressionArray() throws IOException { int l=readInt(); Expression[] v=new Expression[l]; readExpressionArray(v); return v; } void readExpressionArray(Expression[] target) throws IOException { for (int i=0; i0) { sc-=datin.skipBytes(sc); } return e; } } protected Expression fetchShared(int oid) throws IOException { try { Expression e=alreadyReadObjects[oid]; if (e==null) { long currentPos=((Seekable)datin).getFilePointer(); ((Seekable)datin).seek(base + offsets[oid]); e=deser(); ((Seekable)datin).seek(currentPos); } return e; } catch (ArrayIndexOutOfBoundsException aib) { throw new FileNotFoundException(Util.liMessage(Util.SISCB, "invalidentrypoint", new Object[] {new Integer(oid)})); } } public Library getLibrary() { return baseLib; } public void setLibrary(Library lib) { this.baseLib = lib; } public Class readClass() throws IOException { return (Class)classPool.get(new Integer(readInt())); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/LibraryManager.java0000644000175000017500000001212211445752462020224 0ustar amoeamoepackage sisc.ser; import java.net.URL; import java.net.MalformedURLException; import java.io.*; import java.util.*; import sisc.util.Util; import sisc.data.Expression; import sisc.data.Symbol; import sisc.interpreter.AppContext; public class LibraryManager extends Util { class LoadableLibrary { URL path; Library handle; public LoadableLibrary(URL path) { this.path=path; } public LoadableLibrary(Library l) { this.handle=l; } public void open() throws IOException { if (handle==null) { SeekableDataInputStream sis; if (path.getProtocol().equals("file")) { sis=new SeekableDataInputStream( new BufferedRandomAccessInputStream( new File(new File(path.getPath()), path.getFile()).getCanonicalPath(), "r", 8, 2048)); } else { sis=new SeekableDataInputStream(new MemoryRandomAccessInputStream(path.openStream())); } try { handle=Library.load(ctx, sis); } catch (ClassNotFoundException cnf) { cnf.printStackTrace(); } } } public Library getLibrary() throws IOException { open(); return handle; } } protected Map loadedLibraries; AppContext ctx; public LibraryManager(AppContext ctx) { this.ctx=ctx; loadedLibraries=new HashMap(); } public Expression getExpression(Symbol name) throws IOException { for (Iterator i=loadedLibraries.values().iterator(); i.hasNext();) { LoadableLibrary ll=(LoadableLibrary)i.next(); try { return ll.getLibrary().getLocalExpression(name); } catch (FileNotFoundException fnf) { } } throw new FileNotFoundException(liMessage(SISCB, "namedlibbindingnotanywhere", name.toString())); } /** * Returns the reference to a binding in the active libraries, or null * if the provided expression isn't an entry point in any library. */ public LibraryBinding lookupBinding(Expression e) throws IOException { for (Iterator i=loadedLibraries.entrySet().iterator(); i.hasNext();) { Map.Entry entry=(Map.Entry)i.next(); String name=(String)entry.getKey(); LoadableLibrary ll=(LoadableLibrary)entry.getValue(); int eid=ll.getLibrary().reverseLookup(e); if (eid>-1) { return new LibraryBinding(name, eid); } } return null; } public void addLibrary(Library l) { loadedLibraries.put(l.getName(), new LoadableLibrary(l)); } public void addLibrary(String name, URL l) { loadedLibraries.put(name, new LoadableLibrary(l)); } public boolean loadLibrary(String name) { //Should eventually utilize a load path try { URL u=new URL(name); addLibrary(name, u); return true; } catch (MalformedURLException mfu) { mfu.printStackTrace(); } return false; } /** * Returns an expression from an external library */ public Expression resolveBinding(LibraryBinding lb) throws IOException { LoadableLibrary ll=(LoadableLibrary)loadedLibraries.get(lb.name); return ll.getLibrary().getExpression(lb.epid); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/Library.java0000644000175000017500000001206211445752462016734 0ustar amoeamoepackage sisc.ser; import java.util.*; import java.io.*; import java.net.URL; import sisc.data.*; import sisc.interpreter.AppContext; import sisc.util.Util; import sisc.interpreter.Context; public class Library extends Util { static final String LIBRARY_VERSION="SLL4"; protected String name; protected BlockDeserializer lib; protected Map names; public static Library load(AppContext ctx, URL u) throws IOException, ClassNotFoundException { if (u.getProtocol().equalsIgnoreCase("file")) { String path=u.getPath(); return load(ctx, new SeekableDataInputStream(new BufferedRandomAccessInputStream(path, "r"))); } else { return load(ctx, new SeekableDataInputStream(new MemoryRandomAccessInputStream(u.openStream()))); } } public static Library load(AppContext ctx, SeekableDataInputStream di) throws IOException, ClassNotFoundException { String libver=di.readUTF(); if (!libver.equals(LIBRARY_VERSION)) throw new IOException(liMessage(SISCB, "unsuplib")); String libname=di.readUTF(); int classCount=BerEncoding.readBer(di); Map classes=new HashMap(classCount); for (int i=0; i=0; i--) { if (lib.alreadyReadObjects[i]==e) { return i; } } return -1; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/Serializer.java0000644000175000017500000000415511445752462017445 0ustar amoeamoepackage sisc.ser; import java.io.ObjectOutput; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import sisc.data.Expression; import sisc.env.SymbolicEnvironment; public interface Serializer extends ObjectOutput { void writeBigDecimal(BigDecimal d) throws IOException; void writeBigInteger(BigInteger i) throws IOException; void writeExpression(Expression e) throws IOException; void writeExpressionArray(Expression[] vlr) throws IOException; void writeInitializedExpression(Expression e) throws IOException; void writeSymbolicEnvironment(SymbolicEnvironment e) throws IOException; void writeClass(Class c) throws IOException; } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/StreamSerializer.java0000644000175000017500000000572211445752462020622 0ustar amoeamoepackage sisc.ser; import java.util.*; import java.io.*; import sisc.data.Expression; import sisc.interpreter.AppContext; public class StreamSerializer extends SLL2Serializer { private Map entryPoints, classes; private int nextEp, nextClassIdx; private StreamSerializer(AppContext ctx, NestedObjectOutputStream out) throws IOException { super(ctx, out); out.setSerializerInstance(this); this.classes=new HashMap(); this.entryPoints=new HashMap(); } public StreamSerializer(AppContext ctx, OutputStream out) throws IOException { this(ctx, new NestedObjectOutputStream(out)); } protected void writeExpression(Expression e, boolean flush) throws IOException { int posi=nextEp; Integer epIndex=(Integer)entryPoints.get(e); if (epIndex != null) { writeSeenEntryPoint(epIndex.intValue()); } else { entryPoints.put(e, new Integer(nextEp)); writeNewEntryPointMarker(nextEp, e); nextEp++; writeExpression(e, posi, -1, flush); } } public void writeClass(Class c) throws IOException { Integer classIdx=(Integer)classes.get(c); if (classIdx == null) { classes.put(c, new Integer(nextClassIdx)); writeInt(nextClassIdx); nextClassIdx++; writeUTF(c.getName()); } else { writeInt(classIdx.intValue()); } } protected void serializeEnd(int posi, int sizeStartOffset) { } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/Seekable.java0000644000175000017500000000313211445752462017041 0ustar amoeamoepackage sisc.ser; import java.io.IOException; public interface Seekable { void seek(long pos) throws IOException; long getFilePointer() throws IOException; } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/MemoryRandomAccessInputStream.java0000644000175000017500000000531211445752462023257 0ustar amoeamoepackage sisc.ser; import java.io.*; public class MemoryRandomAccessInputStream extends SeekableInputStream { protected byte[] data; protected int filePointer; public MemoryRandomAccessInputStream(InputStream in) throws IOException { ByteArrayOutputStream bos=new ByteArrayOutputStream(); int rc=0; byte[] buffer=new byte[65536]; while (-1!=(rc=in.read(buffer))) { if (rc>0) bos.write(buffer, 0, rc); } bos.flush(); data=bos.toByteArray(); } public void seek(long pos) throws IOException { filePointer=(int)pos; } public long getFilePointer() throws IOException { return filePointer; } public int read() throws IOException { if (filePointer==data.length) return -1; return data[filePointer++] & 0xff; } public int read(byte[] b, int off, int len) throws IOException { int rc=Math.min(len, data.length - filePointer); if (rc==0 && len>0) return -1; System.arraycopy(data, filePointer, b, off, rc); filePointer+=rc; return rc; } public int skipBytes(int bc) throws IOException { int rc=Math.min(bc, data.length - filePointer); filePointer+=rc; return rc; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/SLL2Serializer.java0000644000175000017500000001420611445752462020100 0ustar amoeamoepackage sisc.ser; import java.io.*; import java.util.*; import sisc.data.Expression; import sisc.data.Singleton; import sisc.data.Value; import sisc.interpreter.AppContext; import sisc.util.InternedValue; public abstract class SLL2Serializer extends SerializerImpl { private static class SerJobEnd { public int posi; public int sizeStartOffset; public SerJobEnd(int posi, int sizeStartOffset) { this.posi=posi; this.sizeStartOffset=sizeStartOffset; } } private LinkedList serQueue; protected SLL2Serializer(AppContext ctx, ObjectOutput out) throws IOException { super(ctx, out); serQueue=new LinkedList(); } /** * Required call which actually writes out the bytes of an expression * * @param e * @param flush * @throws IOException */ protected abstract void writeExpression(Expression e, boolean flush) throws IOException; protected abstract void serializeEnd(int posi, int sizeStartOffset); public void writeExpression(Expression e) throws IOException { writeExpressionHelper(e, false); } public void writeInitializedExpression(Expression e) throws IOException { writeExpressionHelper(e, true); } /** * Serializes expressions. We distinguish betweeen six types of * expressions: * Type 0: normal expression * Type 1: null * Type 2: first encounter of entry point / shared expression * Type 3: interned value * Type 4: entry point into other library * Type 16+n: reference to entry point / shared expression n * * @param e the expression to serialize * @param flush force complete, immediate serialisation * @exception IOException if an error occurs */ private void writeExpressionHelper(Expression e, boolean flush) throws IOException { if (e == null) { writeInt(1); return; } writeExpression(e, flush); } public void serialize(Expression e) throws IOException { int start=serQueue.size(); writeExpression(e); serLoop(start); } protected boolean writeExpression(Expression e, int pos, int offset, boolean flush) throws IOException { SerJobEnd job = new SerJobEnd(pos, offset); boolean contiguous; if (e instanceof Singleton) { contiguous = writeExpressionSerialization(e, job, flush); } else { LibraryBinding lb = lookupLibraryBinding(e); contiguous = (lb==null) ? writeExpressionSerialization(e, job, flush) : writeLibraryReference(lb, job, flush); } return contiguous; } private void serLoop(int start) throws IOException { while (serQueue.size()>start) { Object o=serQueue.removeFirst(); if (o instanceof Expression) { serializeDetails((Expression)o); } else if (o instanceof SerJobEnd) { SerJobEnd job = (SerJobEnd)o; serializeEnd(job.posi, job.sizeStartOffset); } } } private void serializeDetails(Expression e) throws IOException { e.serialize(this); e.serializeAnnotations(this); } public void close() throws IOException { flush(); super.close(); } public void flush() throws IOException { serLoop(0); super.flush(); } protected void writeSeenEntryPoint(int posi) throws IOException { writeInt(posi+16); } protected void writeNewEntryPointMarker(int posi, Expression e) throws IOException { writeInt(2); writeInt(posi); } private boolean writeExpressionSerialization(Expression e, SerJobEnd end, boolean flush) throws IOException { if (e instanceof Value) { InternedValue iv = InternedValue.lookupByValue((Value)e); if (iv == null) { writeInt(0); } else { writeInt(3); writeInitializedExpression(iv.getName()); } } else { writeInt(0); } writeClass(e.getClass()); if (e instanceof Singleton) { e.serialize(this); return true; } else { int start=serQueue.size(); serQueue.addFirst(end); serQueue.addFirst(e); if (flush) serLoop(start); return false; } } private boolean writeLibraryReference(LibraryBinding lb, SerJobEnd end, boolean flush) throws IOException { writeInt(4); writeUTF(lb.name); writeInt(lb.epid); return true; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/SLL2Deserializer.java0000644000175000017500000001217411445752462020413 0ustar amoeamoepackage sisc.ser; import java.util.*; import java.io.*; import sisc.data.*; import sisc.env.SymbolicEnvironment; import sisc.interpreter.AppContext; import sisc.util.InternedValue; public abstract class SLL2Deserializer extends DeserializerImpl { private LinkedList deserQueue; protected SLL2Deserializer(AppContext ctx, ObjectInput input) throws IOException { super(ctx, input); deserQueue=new LinkedList(); } public Expression readExpression() throws IOException { return readExpression(false, -1); } public Expression readInitializedExpression() throws IOException { return readExpression(true, -1); } protected abstract void recordReadObject(int definingOid, Expression e); protected abstract Expression skipReadObject(boolean flush, int definingOid) throws IOException; private Expression deserializeDetails(boolean flush, int definingOid, Expression e) throws IOException { if (e instanceof Singleton) { e.deserialize(this); e = ((Singleton)e).singletonValue(); recordReadObject(definingOid, e); } else { recordReadObject(definingOid, e); int start=deserQueue.size(); deserQueue.addFirst(e); if (flush) deserLoop(start); } return e; } protected Expression readExpression(boolean flush, int definingOid) throws IOException { int type=readInt(); switch(type) { case 2: //shared expressions definingOid=readInt(); return skipReadObject(flush, definingOid); case 3: //interned value Symbol name = (Symbol)readInitializedExpression(); Class clazz = readClass(); Expression e = InternedValue.deserResolve(name, clazz); return deserializeDetails(flush, definingOid, e); case 0: //ordinary expressions clazz=readClass(); try { e = (Expression)clazz.newInstance(); } catch (InstantiationException ie) { ie.printStackTrace(); throw new IOException(ie.getMessage()); } catch (IllegalAccessException iae) { iae.printStackTrace(); throw new IOException(iae.getMessage()); } return deserializeDetails(flush, definingOid, e); case 1: //null return null; case 4: String libName=readUTF(); int epid=readInt(); e = resolveLibraryBinding(new LibraryBinding(libName, epid)); recordReadObject(definingOid, e); return e; default: //expression references return fetchShared(type-16); } } public Expression deser() throws IOException { int start=deserQueue.size(); Expression e=readExpression(); deserLoop(start); return e; } private void deserLoop(int start) throws IOException { while (deserQueue.size()>start) { Object o=deserQueue.removeFirst(); initializeExpression((Expression)o); } } private void initializeExpression(Expression e) throws IOException { e.deserialize(this); e.deserializeAnnotations(this); } abstract protected Expression fetchShared(int oid) throws IOException; public SymbolicEnvironment readSymbolicEnvironment() throws IOException { Expression e=readExpression(); if (e instanceof Symbol) e=ctx.getExpression((Symbol)e); return (SymbolicEnvironment)e; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/SerializerImpl.java0000644000175000017500000001106411445752462020264 0ustar amoeamoepackage sisc.ser; import java.io.IOException; import java.io.ObjectOutput; import java.math.BigDecimal; import java.math.BigInteger; import sisc.data.Expression; import sisc.env.SymbolicEnvironment; import sisc.interpreter.AppContext; public abstract class SerializerImpl extends BerEncoding implements Serializer { protected AppContext ctx; protected ObjectOutput datout; protected SerializerImpl(AppContext ctx, ObjectOutput out) { this.ctx = ctx; datout = out; } public LibraryBinding lookupLibraryBinding(Expression e) throws IOException { return ctx.lookupBinding(e); } public void writeBigDecimal(BigDecimal d) throws IOException { int scale=d.scale(); byte[] buffer=d.unscaledValue().toByteArray(); writeInt(buffer.length); writeInt(scale); write(buffer); } public void writeBigInteger(BigInteger i) throws IOException { byte[] buffer=i.toByteArray(); writeInt(buffer.length); write(buffer); } public void writeExpressionArray(Expression[] v) throws IOException { if (v==null) writeInt(0); else { writeInt(v.length); for (int i=0; i-1) { raf.seek(offset[bufferNumber]+dirtyRange[bufferNumber][0]); raf.write(buffer[bufferNumber], dirtyRange[bufferNumber][0], dirtyRange[bufferNumber][1]-dirtyRange[bufferNumber][0]); dirtyRange[bufferNumber][0]=-1; dirtyRange[bufferNumber][0]=0; } } public void flush() throws IOException { for (int i=0; i-1) { flush(i); } } } /** * Set an existing buffer as the active buffer and set the * buffer pointer */ protected void activate(int bufferNumber, int off) { if (bufferNumber!=0) { int[] dirtyRangeTmp=dirtyRange[bufferNumber]; byte[] bufferTmp=buffer[bufferNumber]; long offsetTmp=offset[bufferNumber]; int eofAtTmp=eofAt[bufferNumber]; for (int i=bufferNumber; i>0; i--) { dirtyRange[i]=dirtyRange[i-1]; buffer[i]=buffer[i-1]; offset[i]=offset[i-1]; eofAt[i]=eofAt[i-1]; } buffer[0]=bufferTmp; offset[0]=offsetTmp; eofAt[0]=eofAtTmp; dirtyRange[0]=dirtyRangeTmp; } bufferPtr=off; } protected void load(long pos) throws IOException { //Where do we really want to be? If we can 'cozy up' to //an existing buffer, we'll probably save ourselves some reads //in the future //System.err.println("seekTo:"+pos); long backReach=pos-bufferSize; long forwardReach=pos; long seekPos=pos; for (int i=stackDepth-2; i>=0; i--) { if (offset[i]!=-1 && backReach>offset[i] && backReach<(offset[i]+bufferSize)) { //System.err.println("Br"); //There is a buffer that is going to run into us, //lets seek there seekPos=offset[i]+bufferSize; break; } } for (int i=stackDepth-2; i>=0; i--) { if (offset[i]!=-1 && forwardReach>=offset[i] && forwardReach<(offset[i]+bufferSize)) { //System.err.println("Fr"); //There is a buffer that we'll run into, lets //make sure that happens //lets seek there seekPos=offset[i]-bufferSize; break; } } //System.err.println(pos+":"+seekPos); flush(stackDepth-1); int[] dirtyRangeTmp=dirtyRange[stackDepth - 1]; byte[] bufferTmp=buffer[stackDepth - 1]; for (int i=stackDepth-1; i>0; i--) { dirtyRange[i]=dirtyRange[i-1]; buffer[i]=buffer[i-1]; offset[i]=offset[i-1]; eofAt[i]=eofAt[i-1]; } dirtyRange[0]=dirtyRangeTmp; buffer[0]=bufferTmp; dirtyRange[0][0]=-1; dirtyRange[0][1]=0; offset[0]=-1; raf.seek(seekPos); advance(); bufferPtr=(int)(pos-seekPos); } protected final void advance() throws IOException { flush(0); long cp=raf.getFilePointer(); if (offset[0]==-1) offset[0]=cp; else { offset[0]+=bufferSize; if (cp!=offset[0]) { raf.seek(offset[0]); } } int br=0; int rv=raf.read(buffer[0], 0, bufferSize); while (rv>-1 && br= offset[i] && pos < (offset[i]+bufferSize)) { activate(i, (int)(pos-offset[i])); return; } } //None of the buffers can handle this position, get the new one. load(pos); } protected final void advancePointer(int n) throws IOException { bufferPtr+=n; if (bufferPtr >= bufferSize) advance(); } protected final void advancePointerWrite(int n) throws IOException { if (dirtyRange[0][0]==-1) dirtyRange[0][0]=bufferPtr; bufferPtr+=n; dirtyRange[0][1]+=n; if (bufferPtr >= bufferSize) advance(); } //---------------// public void close() throws IOException { flush(); raf.close(); } public int read() throws IOException { if (bufferPtr == eofAt[0]) return -1; int rv=buffer[0][bufferPtr] & 0xff; advancePointer(1); return rv; } public int read(byte[] b, int off, int len) throws IOException { int bc=Math.min(len, Math.min(bufferSize-bufferPtr, (eofAt[0] == -1 ? bufferSize : eofAt[0]-bufferPtr))); if (bc==0 && len!=0) return -1; System.arraycopy(buffer[0], bufferPtr, b, off, bc); advancePointer(bc); return bc; } public int read(byte[] b) throws IOException { return read(b, 0, b.length); } public int skipBytes(int n) throws IOException { int bc=bufferSize - bufferPtr; advancePointer(bc); return bc; } public void write(int b) throws IOException { buffer[0][bufferPtr]=(byte)b; advancePointerWrite(1); } public void write(byte[] b, int off, int len) throws IOException { do { int bc=Math.min(len, bufferSize - bufferPtr); len-=bc; System.arraycopy(b, off, buffer[0], bufferPtr, bc); advancePointerWrite(bc); } while (len>0); } public void write(byte[] b) throws IOException { write(b, 0, b.length); } public long getFilePointer() throws IOException { return offset[0]+bufferPtr; } public void seek(long pos) throws IOException { acquire(pos); } //Test public static void main(String[] args) throws IOException { BufferedRandomAccessInputStream is=new BufferedRandomAccessInputStream(args[0], "r",4); int rv; do { rv=is.read(); if (is.getFilePointer()==10) is.seek(13); if (is.getFilePointer()==18) is.seek(12); } while (rv!=-1); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/Deserializer.java0000644000175000017500000000421111445752462017747 0ustar amoeamoepackage sisc.ser; import java.io.ObjectInput; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import sisc.data.Expression; import sisc.data.Value; import sisc.env.SymbolicEnvironment; public interface Deserializer extends ObjectInput { BigInteger readBigInteger() throws IOException; BigDecimal readBigDecimal() throws IOException; Expression readExpression() throws IOException; Expression[] readExpressionArray() throws IOException; Value[] readValueArray() throws IOException; Expression readInitializedExpression() throws IOException; SymbolicEnvironment readSymbolicEnvironment() throws IOException; Class readClass() throws IOException; } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/StreamDeserializer.java0000644000175000017500000000735511445752462021137 0ustar amoeamoepackage sisc.ser; import sisc.util.Util; import java.util.*; import java.io.*; import sisc.data.*; import sisc.interpreter.AppContext; public class StreamDeserializer extends SLL2Deserializer { private Map classPool, alreadyReadObjects; private StreamDeserializer(AppContext ctx, NestedObjectInputStream input) throws IOException { super(ctx, input); input.setDeserializerInstance(this); classPool=new HashMap(); alreadyReadObjects=new HashMap(); } public StreamDeserializer(AppContext ctx, InputStream input) throws IOException { this(ctx, new NestedObjectInputStream(input)); } protected void recordReadObject(int definingOid, Expression e) { if (definingOid!=-1) { Integer epIdx=new Integer(definingOid); if (alreadyReadObjects.get(epIdx)==null) alreadyReadObjects.put(epIdx, e); } } protected Expression skipReadObject(boolean flush, int definingOid) throws IOException { Integer epIdx=new Integer(definingOid); Expression e = (Expression)alreadyReadObjects.get(epIdx); if (e == null) { return readExpression(flush, definingOid); } else { //we should never really get here readExpression(flush, definingOid); return e; } } protected Expression fetchShared(int oid) throws IOException { try { Expression e=(Expression)alreadyReadObjects.get(new Integer(oid)); if (e==null) { throw new IOException(Util.liMessage(Util.SISCB, "undefedepinstream")); } return e; } catch (ArrayIndexOutOfBoundsException aib) { throw new FileNotFoundException(Util.liMessage(Util.SISCB, "invalidentrypoint", new Object[] {new Integer(oid)})); } } public Class readClass() throws IOException { int cid=readInt(); Integer i=new Integer(cid); Class c=(Class)classPool.get(i); if (c==null) { try { c=Class.forName(readUTF(), true, Util.currentClassLoader()); classPool.put(i, c); } catch (ClassNotFoundException cnf) { throw new IOException(cnf.toString()); } } return c; } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/SeekableDataInputStream.java0000644000175000017500000000406211445752462022032 0ustar amoeamoepackage sisc.ser; import java.io.*; import sisc.util.Util; public class SeekableDataInputStream extends DataInputStream implements SeekableDataInput, ObjectInput { protected Seekable sis; public SeekableDataInputStream(SeekableInputStream s) { super(s); sis=s; } public void seek(long pos) throws IOException { sis.seek(pos); } public long getFilePointer() throws IOException { return sis.getFilePointer(); } public Object readObject() throws IOException, ClassNotFoundException { throw new IOException(Util.liMessage(Util.SISCB, "cannotdeserialize")); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/JavaSerializer.java0000644000175000017500000000547211445752462020252 0ustar amoeamoepackage sisc.ser; import java.io.*; import sisc.data.Expression; import sisc.data.Singleton; import sisc.interpreter.Context; import sisc.interpreter.AppContext; public class JavaSerializer extends SerializerImpl { private JavaSerializer(AppContext ctx, ObjectOutput o) throws IOException { super(ctx, o); if (ctx == null) { System.err.println("AppContext is null!!!"); } } public static Serializer create(ObjectOutput o) throws IOException { return (o instanceof NestedObjectOutputStream) ? ((NestedObjectOutputStream)o).getSerializerInstance() : new JavaSerializer(Context.currentAppContext(), o); } public void writeExpression(Expression e) throws IOException { if (e == null || e instanceof Singleton) { writeBoolean(false); writeObject(e); } else { LibraryBinding lb = lookupLibraryBinding(e); if (lb == null) { writeBoolean(false); writeObject(e); } else { writeBoolean(true); writeUTF(lb.name); writeInt(lb.epid); } } } public void writeInitializedExpression(Expression e) throws IOException { writeExpression(e); } public void writeClass(Class c) throws IOException { writeObject(c); } } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/SeekableInputStream.java0000644000175000017500000000307011445752462021236 0ustar amoeamoepackage sisc.ser; import java.io.InputStream; public abstract class SeekableInputStream extends InputStream implements Seekable { } /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Second Interpreter of Scheme Code (SISC). * * The Initial Developer of the Original Code is Scott G. Miller. * Portions created by Scott G. Miller are Copyright (C) 2000-2007 * Scott G. Miller. All Rights Reserved. * * Contributor(s): * Matthias Radestock * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ sisc-1.16.6.orig/src/sisc/ser/LibraryAE.java0000644000175000017500000001706711445752462017154 0ustar amoeamoepackage sisc.ser; import java.io.IOException; import java.util.*; import sisc.data.*; import sisc.env.MemorySymEnv; import sisc.env.SymbolicEnvironment; import sisc.util.ExpressionVisitor; /** * An SymEnv backed by a random-access library. It can operate in two * modes: * 1) "observe" - keep track of bindings from which to later create a * library * 2) "retrieve" - access bindings in a library */ public class LibraryAE extends MemorySymEnv { static class LibraryBinding { public Library lib; public int entryPoint; public LibraryBinding(Library lib, int ep) { this.lib=lib; entryPoint=ep; } } protected LibraryBuilder lb; protected Library base; protected Map addressMap; protected Set bindWatch; protected int parentIdx=-1; /** * Operate in "observe" mode. * * @param name the name of the SymEnv * @param lb the library serializer */ public LibraryAE(Symbol name, LibraryBuilder lb) { super(name); this.lb=lb; bindWatch=new HashSet(); } /** * Operate in "observe" mode. * * @param parent the name of the parent SymEnv * @param lb the library serializer */ public LibraryAE(SymbolicEnvironment parent, LibraryBuilder lb) { this.parent=parent; this.lb=lb; bindWatch=new HashSet(); } /** * Operate in "retrieve" mode. * * @param base the library from which to retrieve bindings */ public LibraryAE(Library base) { this.base=base; addressMap=new HashMap(); } public SymbolicEnvironment getParent() { if (parent == null && parentIdx > -1) loadParent(); return parent; } public void addSymbolicBindings(Library lib, Pair s) { for (;s!=EMPTYLIST; s=(Pair)s.cdr()) { Symbol nsym=(Symbol)s.car(); addBinding(lib, nsym, lib.getEntryPoint(nsym)); } } public void addBinding(Library lib, Symbol sym, int ep) { addressMap.put(sym, new LibraryBinding(lib, ep)); } public void undefine(Symbol s) { if (bindWatch != null) bindWatch.remove(s); super.undefine(s); } private void loadParent() { if (parent == null || parentIdx > -1) { try { parent=(SymbolicEnvironment)base.getExpression(parentIdx); } catch (IOException e) { e.printStackTrace(); } } } public int getLoc(Symbol s) { synchronized(symbolMap) { //already loaded? Integer i = (Integer)symbolMap.get(s); if (i!=null) return i.intValue(); //present in this AE? if (addressMap != null) { LibraryBinding b=(LibraryBinding)addressMap.get(s); if (b!=null) { try { return store(s, (Value)b.lib.getExpression(b.entryPoint)); } catch (IOException e) { e.printStackTrace(); } } loadParent(); } //try parent if (parent == null) return -1; Value v = parent.lookup(s); if (v == null) return -1; return store(s, v); } } /** * Catch all occurences of sets and note them for when we serialize * * @param s the key being set * @param v the value associated with the key * @return index of binding */ public int store(Symbol s, Value v) { if (bindWatch != null) bindWatch.add(s); return super.store(s, v); } public LibraryAE() {} public void deserialize(Deserializer d) throws IOException { setName((Symbol)d.readExpression()); base=((LibraryDeserializer)d).getLibrary(); int size=d.readInt(); addressMap=new HashMap(size); for (int i=0; i (lambda #t formals (lexicals ...) body) ;; (letrec bindings body) => (letrec #t bindings (lexicals ...) body) ;; (define _analyze! (let () (import misc) (define PROGRAM 0) (define APPLICATION 1) (define _LAMBDA 2) (define _IF 3) (define _BEGIN 4) (define _QUOTE 5) (define SET 6) (define _DEFINE 7) (define MAKEANNOTATION 8) (define _LETREC 9) (define UNKNOWN -1) (define (union ls1 ls2) (let loop ([ls1 ls1] [tail #f] [acc '()]) (cond [(null? ls1) (if tail (begin (set-cdr! tail ls2) acc) ls2)] [(memq (car ls1) ls2) (loop (cdr ls1) tail acc)] [else (let ([cc (cons (car ls1) acc)]) (loop (cdr ls1) (or tail cc) cc))]))) (define (difference ls1 ls2) (let loop ([ls1 ls1] [acc '()]) (cond [(null? ls1) acc] [(memq (car ls1) ls2) (loop (cdr ls1) acc)] [else (loop (cdr ls1) (cons (car ls1) acc))]))) (define (intersection ls1 ls2) (let loop ([ls1 ls1] [acc '()]) (cond [(null? ls1) acc] [(memq (car ls1) ls2) (loop (cdr ls1) (cons (car ls1) acc))] [else (loop (cdr ls1) acc)]))) (define (in ls1 ls2) (reverse (intersection ls1 ls2))) (define-simple-syntax (arecord-refs arec) (vector-ref arec 0)) (define-simple-syntax (arecord-sets arec) (vector-ref arec 1)) (define-simple-syntax (arecord-frees arec) (vector-ref arec 2)) (define-simple-syntax (arecord-value arec) (vector-ref arec 3)) (define (inc-cdr! v) (set-cdr! v (+ 1 (cdr v)))) (define-simple-syntax (inc! vcount var) (cond [(assq var (cdr vcount)) => inc-cdr!] [else (set-cdr! vcount (cons (cons var 1) (cdr vcount)))])) (define-simple-syntax (inc-refs! arec var) (inc! (arecord-refs arec) var)) (define-simple-syntax (inc-sets! arec var) (inc! (arecord-sets arec) var)) (define (arecord-add-free! arec newfree) (let ([afrees (arecord-frees arec)]) (unless (memq newfree (cdr afrees)) (set-cdr! afrees (cons newfree (cdr afrees)))))) (define (arecord-union-frees! arec newfrees) (set-cdr! (arecord-frees arec) (union (cdr (arecord-frees arec)) newfrees))) (define-syntax int-case (syntax-rules (else) ((_ val (else expr ...)) (begin expr ...)) ((_ val (const expr ...) tail ...) (if (= val const) (begin expr ...) (int-case val tail ...))))) (define (_cdr>0 v) (if (> (cdr v) 0) (cdr v) #f)) (define (non-zero? vcount var) (cond [(assq var (cdr vcount)) => _cdr>0] [else #f])) (define (->proper-list elem) (cond [(null? elem) '()] [(pair? elem) (cons (car elem) (->proper-list (cdr elem)))] [else (list elem)])) (define (make-arecord v) (vector (list '*refs*) (list '*sets*) (list '*frees*) v)) (define (build-refs vals) (cond [(null? vals) '()] [(zero? (cdar vals)) (build-refs (cdr vals))] [else (cons (car vals) (build-refs (cdr vals)))])) (define analyze! (lambda (v arec env lxs) (cond [(symbol? v) (inc-refs! arec v) (unless (memq v lxs) (arecord-add-free! arec v)) (list v)] [(pair? v) (analyze-app! v arec env lxs)] [else '()]))) (define analyze-app! (lambda (v arec env lxs) (let ([oper (car v)] [v (cdr v)] [exp-type (_expression-type env (car v))]) (int-case exp-type (_QUOTE '()) (PROGRAM (map-car (car v))) (_LAMBDA (let* ([analyzed (eq? (car v) #t)] [v (if analyzed (cdr v) v)] [locals (->proper-list (car v))] [v (if analyzed (cdr v) v)] [refs (analyze! (cadr v) arec env (union locals lxs))] [locally-frees (difference refs locals)] [frees (difference locally-frees lxs)] [lexicals (in lxs refs)]) (arecord-union-frees! arec (difference locally-frees lxs)) (unless analyzed (set-cdr! v (cons (car v) (cons lexicals (cdr v)))) (set-car! v #t)) locally-frees)) (_LETREC (let* ([analyzed (eq? (car v) #t)] [v (if analyzed (cdr v) v)] [letrec-remainder v] [locals (map (lambda (binding) (inc-sets! arec (car binding)) (car binding)) (car v))] [newlxs (union locals lxs)] [refs (let loop ([bindings (car v)] [refs '()]) (if (null? bindings) refs (loop (cdr bindings) (union (analyze! (cadar bindings) arec env newlxs) refs))))] [v ((if analyzed cddr cdr) v)] [refs (union (analyze! (car v) arec env newlxs) refs)] [locally-frees (difference refs locals)] [lexicals (in lxs refs)]) (arecord-union-frees! arec (difference locally-frees lxs)) (unless analyzed (set-cdr! letrec-remainder (cons (car letrec-remainder) (cons lexicals (cdr letrec-remainder)))) (set-car! letrec-remainder #t)) locally-frees)) (SET (let ([s (car v)]) (when (symbol? s) (inc-refs! arec s) (inc-sets! arec s)) (cons s (analyze! (cadr v) arec env lxs)))) (_DEFINE (analyze! (cadr v) arec env lxs)) (MAKEANNOTATION (analyze! (car v) arec env lxs)) (else (let loop ([v v] [rv (if (= exp-type APPLICATION) (analyze! oper arec env lxs) '())]) (if (or (null? v) (not (pair? v))) rv (loop (cdr v) (union (analyze! (car v) arec env lxs) rv))))))))) (lambda (v env) (let ([arec (make-arecord v)]) (analyze! v arec env '()) `(#%program ,(build-refs (cdr (arecord-refs arec))) ,(build-refs (cdr (arecord-sets arec))) ,(cdr (arecord-frees arec)) ,(arecord-value arec)))))) ;; ;; The contents of this file are subject to the Mozilla Public ;; License Version 1.1 (the "License"); you may not use this file ;; except in compliance with the License. You may obtain a copy of ;; the License at http://www.mozilla.org/MPL/ ;; ;; Software distributed under the License is distributed on an "AS ;; IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ;; implied. See the License for the specific language governing ;; rights and limitations under the License. ;; ;; The Original Code is the Second Interpreter of Scheme Code (SISC). ;; ;; The Initial Developer of the Original Code is Scott G. Miller. ;; Portions created by Scott G. Miller are Copyright (C) 2000-2007 ;; Scott G. Miller. All Rights Reserved. ;; ;; Contributor(s): ;; Matthias Radestock ;; ;; Alternatively, the contents of this file may be used under the ;; terms of the GNU General Public License Version 2 or later (the ;; "GPL"), in which case the provisions of the GPL are applicable ;; instead of those above. If you wish to allow use of your ;; version of this file only under the terms of the GPL and not to ;; allow others to use your version of this file under the MPL, ;; indicate your decision by deleting the provisions above and ;; replace them with the notice and other provisions required by ;; the GPL. If you do not delete the provisions above, a recipient ;; may use your version of this file under either the MPL or the ;; GPL. ;; sisc-1.16.6.orig/src/sisc/boot/eval.sce0000644000175000017500000002051211445752462016261 0ustar amoeamoe(#%program ((|%%_7w-V8lgoK_x| . 1) (_make-parameter . 1)) () (_make-parameter) (#%define current-optimizer (_make-parameter (#%lambda #t (|%%_7w-V8lgoK_x|) () |%%_7w-V8lgoK_x|)))) (#%program ((_with-environment . 1)) () (_with-environment) (#%define with-environment _with-environment)) (#%program ((compile . 1) (|%%_7wowWvjoK_compile| . 1) (|%%_7w2AY2joK_analyze| . 1) (|%%_7wID-BioK_optimize| . 1) (|%%_7wmH09ioK_expand| . 1) (cons . 4) (list . 1) (|%%_7wMhOjloK_expr| . 1) (|%%_7wkS6OgoK_old-compile| . 1) (|%%_7wqlQSkoK_expr| . 1) (_analyze! . 1) (|%%_7w4pSpkoK_expr| . 1) (current-optimizer . 1) (|%%_7wGO4fhoK_flags| . 1) (|%%_7wKsUYjoK_expr| . 1) (sc-expand . 1) (apply . 1) (|%%_7w0L2IhoK_env| . 3) (with-environment . 1)) ((|%%_7wowWvjoK_compile| . 1) (|%%_7w2AY2joK_analyze| . 1) (|%%_7wID-BioK_optimize| . 1) (|%%_7wmH09ioK_expand| . 1)) (compile list cons _analyze! current-optimizer sc-expand apply with-environment) (#%define compilation-phases ((#%lambda #t (|%%_7wkS6OgoK_old-compile|) () (#%lambda #t (|%%_7wGO4fhoK_flags| |%%_7w0L2IhoK_env|) (|%%_7wkS6OgoK_old-compile|) (#%letrec #t ((|%%_7wmH09ioK_expand| (#%lambda #t (|%%_7wKsUYjoK_expr|) (|%%_7w0L2IhoK_env| |%%_7wGO4fhoK_flags|) (with-environment |%%_7w0L2IhoK_env| (#%lambda #t () (|%%_7wKsUYjoK_expr| |%%_7wGO4fhoK_flags|) (apply sc-expand |%%_7wKsUYjoK_expr| |%%_7wGO4fhoK_flags|))))) (|%%_7wID-BioK_optimize| (#%lambda #t (|%%_7w4pSpkoK_expr|) () ((current-optimizer) |%%_7w4pSpkoK_expr|))) (|%%_7w2AY2joK_analyze| (#%lambda #t (|%%_7wqlQSkoK_expr|) (|%%_7w0L2IhoK_env|) (_analyze! |%%_7wqlQSkoK_expr| |%%_7w0L2IhoK_env|))) (|%%_7wowWvjoK_compile| (#%lambda #t (|%%_7wMhOjloK_expr|) (|%%_7w0L2IhoK_env| |%%_7wkS6OgoK_old-compile|) (|%%_7wkS6OgoK_old-compile| |%%_7wMhOjloK_expr| |%%_7w0L2IhoK_env|)))) (|%%_7w0L2IhoK_env| |%%_7wGO4fhoK_flags| |%%_7wkS6OgoK_old-compile|) (list (cons (#%quote expand) |%%_7wmH09ioK_expand|) (cons (#%quote optimize) |%%_7wID-BioK_optimize|) (cons (#%quote analyze) |%%_7w2AY2joK_analyze|) (cons (#%quote compile) |%%_7wowWvjoK_compile|))))) compile))) (#%program ((interaction-environment . 1) (|%%_7w6eMMloK_env| . 2) (|%%_7w83G7noK_expr| . 1) (|%%_7waUzuooK_env| . 1) (|%%_7wsaKdmoK_flags| . 1) (compilation-phases . 1) (|%%_7wO6IGmoK_start-phase| . 1) (|%%_7wQXB1ooK_select-phases| . 2) (map . 1) (|%%_7weyncroK_start-phase| . 2) (|%%_7wAulFroK_phases| . 3) (caar . 1) (eq? . 1) (cdr . 3) (|%%_7wu_DAnoK_compose| . 2) (apply . 2) (car . 2) (|%%_7wyFriqoK_x| . 1) (|%%_7wSMvopoK_fn| . 1) (|%%_7wcJtRpoK_tail| . 1) (|%%_7wUBpLqoK_x| . 1) (|%%_7wwQxXooK_fs| . 3) (null? . 2)) ((|%%_7wQXB1ooK_select-phases| . 1) (|%%_7wu_DAnoK_compose| . 1)) (null? apply cdr car caar eq? map interaction-environment compilation-phases) (#%define compile-with-flags (#%lambda #t (|%%_7w83G7noK_expr| |%%_7wO6IGmoK_start-phase| |%%_7wsaKdmoK_flags| . |%%_7w6eMMloK_env|) () (#%letrec #t ((|%%_7wu_DAnoK_compose| (#%lambda #t |%%_7wwQxXooK_fs| (|%%_7wu_DAnoK_compose|) (#%if (null? |%%_7wwQxXooK_fs|) (#%lambda #t (|%%_7wUBpLqoK_x|) () |%%_7wUBpLqoK_x|) ((#%lambda #t (|%%_7wSMvopoK_fn| |%%_7wcJtRpoK_tail|) () (#%lambda #t (|%%_7wyFriqoK_x|) (|%%_7wcJtRpoK_tail| |%%_7wSMvopoK_fn|) (|%%_7wcJtRpoK_tail| (|%%_7wSMvopoK_fn| |%%_7wyFriqoK_x|)))) (car |%%_7wwQxXooK_fs|) (apply |%%_7wu_DAnoK_compose| (cdr |%%_7wwQxXooK_fs|)))))) (|%%_7wQXB1ooK_select-phases| (#%lambda #t (|%%_7weyncroK_start-phase| |%%_7wAulFroK_phases|) (|%%_7wQXB1ooK_select-phases|) (#%if (eq? (caar |%%_7wAulFroK_phases|) |%%_7weyncroK_start-phase|) (map cdr |%%_7wAulFroK_phases|) (|%%_7wQXB1ooK_select-phases| |%%_7weyncroK_start-phase| (cdr |%%_7wAulFroK_phases|)))))) (|%%_7w6eMMloK_env| |%%_7wsaKdmoK_flags| |%%_7wO6IGmoK_start-phase| |%%_7w83G7noK_expr|) ((#%lambda #t (|%%_7waUzuooK_env|) (|%%_7wQXB1ooK_select-phases| |%%_7wu_DAnoK_compose| |%%_7wsaKdmoK_flags| |%%_7wO6IGmoK_start-phase| |%%_7w83G7noK_expr|) ((apply |%%_7wu_DAnoK_compose| (|%%_7wQXB1ooK_select-phases| |%%_7wO6IGmoK_start-phase| (compilation-phases |%%_7wsaKdmoK_flags| |%%_7waUzuooK_env|))) |%%_7w83G7noK_expr|)) (#%if (null? |%%_7w6eMMloK_env|) (interaction-environment) (car |%%_7w6eMMloK_env|))))))) (#%program ((|%%_7wWqj6soK_env| . 1) (|%%_7wgnhzsoK_expr| . 1) (compile-with-flags . 1) (apply . 1) (compile . 1)) ((compile . 1)) (compile-with-flags apply) (#%set! compile (#%lambda #t (|%%_7wgnhzsoK_expr| . |%%_7wWqj6soK_env|) () (apply compile-with-flags |%%_7wgnhzsoK_expr| (#%quote expand) (#%quote ((l) (l))) |%%_7wWqj6soK_env|)))) (#%program ((compile-with-flags . 1) (apply . 1) (with-environment . 1) (|%%_7wE89nuoK_compiled-expr| . 2) (error . 1) (strict-r5rs-compliance . 1) (|%%_7wCjf0toK_env| . 4) (null? . 2) (cadr . 2) (|%%_7wicbWtoK_phase| . 3) (car . 3) (equal? . 2) (|%%_7wYfdttoK_x| . 9) (pair? . 2)) ((|%%_7wYfdttoK_x| . 2) (|%%_7wicbWtoK_phase| . 2)) (error null? strict-r5rs-compliance cadr pair? car equal? apply compile-with-flags with-environment) (#%define eval (#%lambda #t (|%%_7wYfdttoK_x| . |%%_7wCjf0toK_env|) () ((#%lambda #t (|%%_7wicbWtoK_phase|) (|%%_7wCjf0toK_env| |%%_7wYfdttoK_x|) (#%begin (#%if (#%if (pair? |%%_7wYfdttoK_x|) (equal? (car |%%_7wYfdttoK_x|) "noexpand") #f) (#%begin (#%set! |%%_7wicbWtoK_phase| (#%quote compile)) (#%set! |%%_7wYfdttoK_x| (cadr |%%_7wYfdttoK_x|))) (#%if (#%if (pair? |%%_7wYfdttoK_x|) (equal? (car |%%_7wYfdttoK_x|) "analyzeonly") #f) (#%begin (#%set! |%%_7wicbWtoK_phase| (#%quote analyze)) (#%set! |%%_7wYfdttoK_x| (cadr |%%_7wYfdttoK_x|))) (#%if (#%if (null? |%%_7wCjf0toK_env|) (strict-r5rs-compliance) #f) (error (#%quote eval) "expected 2 arguments to procedure, got 1.") #!void))) ((#%lambda #t (|%%_7wE89nuoK_compiled-expr|) (|%%_7wCjf0toK_env|) (#%if (null? |%%_7wCjf0toK_env|) (|%%_7wE89nuoK_compiled-expr|) (with-environment (car |%%_7wCjf0toK_env|) |%%_7wE89nuoK_compiled-expr|))) (apply compile-with-flags |%%_7wYfdttoK_x| |%%_7wicbWtoK_phase| (#%quote ((e) (e))) |%%_7wCjf0toK_env|)))) (#%quote expand))))) sisc-1.16.6.orig/src/sisc/boot/compat.scm0000644000175000017500000000776511445752462016644 0ustar amoeamoe;; ;; The contents of this file are subject to the Mozilla Public ;; License Version 1.1 (the "License"); you may not use this file ;; except in compliance with the License. You may obtain a copy of ;; the License at http://www.mozilla.org/MPL/ ;; ;; Software distributed under the License is distributed on an "AS ;; IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ;; implied. See the License for the specific language governing ;; rights and limitations under the License. ;; ;; The Original Code is the Second Interpreter of Scheme Code (SISC). ;; ;; The Initial Developer of the Original Code is Scott G. Miller. ;; Portions created by Scott G. Miller are Copyright (C) 2000-2007 ;; Scott G. Miller. All Rights Reserved. ;; ;; Contributor(s): ;; Matthias Radestock ;; ;; Alternatively, the contents of this file may be used under the ;; terms of the GNU General Public License Version 2 or later (the ;; "GPL"), in which case the provisions of the GPL are applicable ;; instead of those above. If you wish to allow use of your ;; version of this file only under the terms of the GPL and not to ;; allow others to use your version of this file under the MPL, ;; indicate your decision by deleting the provisions above and ;; replace them with the notice and other provisions required by ;; the GPL. If you do not delete the provisions above, a recipient ;; may use your version of this file under either the MPL or the ;; GPL. ;; ;;; compat.ss ;;; Robert Hieb & Kent Dybvig ;;; 92/06/18 ;;; This file contains nonstandard help procedures. ;;; They are all present in Chez Scheme, but are easily defined ;;; in any standard Scheme system. ;;; These versions do no error checking. ; In Chez Scheme "(void)" returns an object that is ignored by the ; REP loop. It is returned whenever a "nonspecified" value is specified ; by the standard. The following should pick up an appropriate value. ;(define void ; (let ((void-object (if #f #f))) ; (lambda () void-object))) ; "andmap" is like "map" except instead of "consing" the results it ; "ands" them, quitting early if #f" is obtained. ; The following does no error checking. (define andmap (lambda (f first . rest) (or (null? first) (if (null? rest) (let andmap ((first first)) (let ((x (car first)) (first (cdr first))) (if (null? first) (f x) (and (f x) (andmap first))))) (let andmap ((first first) (rest rest)) (let ((x (car first)) (xr (map car rest)) (first (cdr first)) (rest (map cdr rest))) (if (null? first) (apply f (cons x xr)) (and (apply f (cons x xr)) (andmap first rest))))))))) (define (gen-sym base) (if base (string->symbol (string-append (symbol->string (gensym)) "_" (symbol->string base))) (gensym))) (define (ormap proc list1) (and (not (null? list1)) (or (proc (car list1)) (ormap proc (cdr list1))))) (define (remq o lst) (cond [(null? lst) '()] [(eq? o (car lst)) (remq o (cdr lst))] [else (cons (car lst) (remq o (cdr lst)))])) (define $sc-put-cte) (define identifier?) (define sc-expand) (define datum->syntax-object) (define syntax-object->datum) (define generate-temporaries) (define free-identifier=?) (define bound-identifier=?) (define literal-identifier=?) (define syntax-error) (define $syntax-dispatch) (define $make-environment) (define (throw . args) (apply error args)) (define (error . args) (for-each (lambda (arg) (display arg) (display #\space)) args) (newline)) (define strict-r5rs-compliance (_make-native-parameter "strictR5RSCompliance")) (define (atom? v) (not (or (pair? v) (symbol? v)))) (define (make-false v) #f) ;;;;;;;;;;;;; Module loading (if (not (getprop 'LITE (get-symbolic-environment '*sisc*))) (for-each load-module '("sisc.modules.OptionalPrimitives$Index"))) sisc-1.16.6.orig/src/sisc/boot/init2.scm0000644000175000017500000011543211445752462016375 0ustar amoeamoe;; ;; The contents of this file are subject to the Mozilla Public ;; License Version 1.1 (the "License"); you may not use this file ;; except in compliance with the License. You may obtain a copy of ;; the License at http://www.mozilla.org/MPL/ ;; ;; Software distributed under the License is distributed on an "AS ;; IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ;; implied. See the License for the specific language governing ;; rights and limitations under the License. ;; ;; The Original Code is the Second Interpreter of Scheme Code (SISC). ;; ;; The Initial Developer of the Original Code is Scott G. Miller. ;; Portions created by Scott G. Miller are Copyright (C) 2000-2007 ;; Scott G. Miller. All Rights Reserved. ;; ;; Contributor(s): ;; Matthias Radestock ;; ;; Alternatively, the contents of this file may be used under the ;; terms of the GNU General Public License Version 2 or later (the ;; "GPL"), in which case the provisions of the GPL are applicable ;; instead of those above. If you wish to allow use of your ;; version of this file only under the terms of the GPL and not to ;; allow others to use your version of this file under the MPL, ;; indicate your decision by deleting the provisions above and ;; replace them with the notice and other provisions required by ;; the GPL. If you do not delete the provisions above, a recipient ;; may use your version of this file under either the MPL or the ;; GPL. ;; ;; Parameter Support, compatible with SRFI-39 (define (make-parameter value . converter) (cond [(null? converter) (_make-parameter value)] [(null? (cdr converter)) (let ([param (_make-parameter value)] [converter (car converter)]) (lambda arg (if (null? arg) (param) (param (converter (car arg))))))] [else (error 'make-parameter "too many arguments.")])) (define (make-config-parameter name value . converter) (cond [(null? converter) (_make-config-parameter name value)] [(null? (cdr converter)) (let ([param (_make-config-parameter name value)] [converter (car converter)]) (lambda arg (if (null? arg) (param) (param (converter (car arg))))))] [else (error 'make-config-parameter "too many arguments.")])) (define (make-native-parameter name . converter) (cond [(null? converter) (_make-native-parameter name)] [(null? (cdr converter)) (let ([param (_make-native-parameter name)] [converter (car converter)]) (lambda arg (if (null? arg) (param) (param (converter (car arg))))))] [else (error 'make-config-parameter "too many arguments.")])) (define-syntax parameterize (syntax-rules () [(_ ((param-name new-value) ...) . body) (let ([old-values #f] [tmps (list new-value ...)]) (dynamic-wind (lambda () (set! old-values (list (param-name) ...)) (for-each (lambda (p l) (p l)) (list param-name ...) tmps)) (lambda () . body) (lambda () (set! tmps (list (param-name) ...)) (for-each (lambda (p l) (p l)) (list param-name ...) old-values))))])) ;; native parameters (define current-input-port (make-native-parameter "inputPort")) (define current-output-port (make-native-parameter "outputPort")) (define case-sensitive (make-native-parameter "caseSensitive")) (define print-shared (make-native-parameter "printShared")) (define vector-length-prefixing (make-native-parameter "vectorLengthPrefixing")) (define emit-debugging-symbols (make-native-parameter "emitDebuggingSymbols")) (define emit-annotations (make-native-parameter "emitAnnotations")) (define character-set (make-native-parameter "characterSet")) (define permissive-parsing (make-native-parameter "permissiveParsing")) (define internal-debugging (make-native-parameter "internalDebugging")) (define synopsis-length (make-native-parameter "synopsisLength")) (define source-annotations (make-native-parameter "sourceAnnotations")) (define max-stack-trace-depth (make-native-parameter "maxStackTraceDepth")) ; Enable inlining and optimizer assumptions while expanding libraries (putprop 'assumptive-procedures '*opt* '(not + - * / car cdr caar cadr cdar cddr zero? null? pair? number? procedure?)) (if (equal? (getenv "sisc.debugging") "true") (begin (emit-annotations #t) (emit-debugging-symbols #t))) ;;;;;;;;;; hooks ;;;;;;;;;; (define (hook-items proc) (annotation proc 'items)) (define (set-hook-items! proc items) (set-annotation! proc 'items items)) (define (make-hook default) (let ([items (list default)]) (define (hook key item) (cond [(assq key (cdr items)) => (lambda (x) (set-cdr! x item))] [else (set-cdr! items (cons (cons key item) (cdr items)))])) (set-hook-items! hook items) hook)) (define (invoke-hook hook . args) (let* ([all-items (hook-items hook)] [def (car all-items)]) (let loop ([items (cdr all-items)] [args args]) (if (null? items) (apply def args) (apply (cdar items) (lambda args (loop (cdr items) args)) args))))) ;;;;;;;;;;;;;;;; error handling ;;;;;;;;;;;;;;; ; Needed later (define pretty-print) ;; Most of the code here is for providing SRFI-23 style error ;; producing, which is then applied into SISC's failure-continuation ;; model. (define (make-exception error error-k) `((error-continuation . ,error-k) . ,error)) (define (exception? e) (and (pair? e) (pair? (car e)) (eq? (caar e) 'error-continuation))) (define (exception-continuation exception) (cdar exception)) (define (exception-error exception) (cdr exception)) (define (throw error-or-exception . error-k) (call-with-failure-continuation (lambda (fk) (cond [(pair? error-or-exception) (if (null? error-k) (call-with-current-continuation (lambda (k) (fk error-or-exception k))) (fk error-or-exception (car error-k)))] [(and (exception? error-or-exception) (null? error-k)) (fk (exception-error error-or-exception) (exception-continuation error-or-exception))] [else (error 'throw "expected error-record or exception, got ~a" error-or-exception)])))) (define (error . args) (throw (apply make-error args))) (define (make-nested-error error-record parent-record . parent-k) `((parent . ,(if (null? parent-k) parent-record (make-exception parent-record (car parent-k)))) . ,error-record)) (define (make-error . args) (let ([ops (print-shared #t)] [error-record '()]) ;;Location (cond [(null? args) (void)] [(and (not (null? (cdr args))) (symbol? (car args))) (set! error-record (cons (cons 'location (car args)) error-record)) (set! args (cdr args))] [(not (car args)) (set! args (cdr args))]) ;;Message/Value (let ([message (and (not (null? args)) (car args))]) (if message (set! args (cdr args))) (if (null? args) (if message (set! error-record (cons `(message . ,message) error-record))) (if (string? message) (set! error-record (cons `(message . ,(apply format message args)) error-record)) (error 'error "cannot specify arguments to a non format-string error.")))) (print-shared ops) error-record)) (define (error-location error-record) (cond [(and (pair? error-record) (assq 'location error-record)) => cdr] [else #f])) (define (error-message error-record) (cond [(and (pair? error-record) (assq 'message error-record)) => cdr] [else #f])) (define (error-parent error-record) (cond [(and (pair? error-record) (assq 'parent error-record)) => cdr] [else #f])) (define (error-parent-error error-record) (let ([error-parent (error-parent error-record)]) (and error-parent (exception-error error-parent)))) (define (error-parent-continuation error-record) (let ([error-parent (error-parent error-record)]) (and error-parent (exception-continuation error-parent)))) (define (make-error-message location message) (if location (if message (format "Error in ~a: ~a" location message) (format "Error in ~a." location)) (if message (format "Error: ~a" message) "Error."))) (define (display-error e) (display (make-error-message (error-location e) (error-message e))) (newline)) (define print-exception-stack-trace-hook (make-hook (lambda args (display "{warning: printing of stack trace not supported}\n")))) (define (print-exception-stack-trace e) (invoke-hook print-exception-stack-trace-hook e)) (define (print-exception e . st) (let ([error (exception-error e)]) (display-error error) (if (or (null? st) (car st)) (print-exception-stack-trace e)) (let ([p (and (pair? error) (error-parent error))]) (if p (begin (display "===========================\nCaused by ") (apply print-exception p st)))))) (define (print-error e k) (print-exception (make-exception e k))) ;; FORMAT (define format (let () (define (round* n scale) ;; assert scale < 0 (let ((one (expt 10 (- scale)))) (/ (round (* n one)) one))) (define (string-index str c) (let ((len (string-length str))) (let loop ((i 0)) (cond ((= i len) #f) ((eqv? c (string-ref str i)) i) (else (loop (+ i 1))))))) (define (string-grow str len char) (let ((off (- len (string-length str)))) (if (positive? off) (string-append (make-string off char) str) str))) (define (string-pad-right str len char) (let ((slen (string-length str))) (cond ((< slen len) (string-append str (make-string (- len slen) char))) ((> slen len) (substring str 0 len)) (else str)))) (define documentation-string "(format [] [...]) -- is #t, #f or an output-port OPTION [MNEMONIC] DESCRIPTION -- Implementation Assumes ASCII Text Encoding ~H [Help] output this text ~A [Any] (display arg) for humans ~S [Slashified] (write arg) for parsers ~W [WriteCircular] like ~s but outputs circular and recursive data structures ~~ [tilde] output a tilde ~T [Tab] output a tab character ~% [Newline] output a newline character ~& [Freshline] output a newline character if the previous output was not a newline ~D [Decimal] the arg is a number which is output in decimal radix ~X [heXadecimal] the arg is a number which is output in hexdecimal radix ~O [Octal] the arg is a number which is output in octal radix ~B [Binary] the arg is a number which is output in binary radix ~w,dF [Fixed] the arg is a string or number which has width w and d digits after the decimal ~C [Character] charater arg is output by write-char ~_ [Space] a single space character is output ~Y [Yuppify] the list arg is pretty-printed to the output ~? [Indirection] recursive format: next 2 args are format-string and list of arguments ~K [Indirection] same as ~? ") (define (format-fixed number-or-string width digits) ; returns a string (cond ((string? number-or-string) (string-grow number-or-string width #\space)) ((number? number-or-string) (let ((real (real-part number-or-string)) (imag (imag-part number-or-string))) (cond ((not (zero? imag)) (string-grow (string-append (format-fixed real 0 digits) (if (negative? imag) "" "+") (format-fixed imag 0 digits) "i") width #\space)) (digits (let* ((rounded-number (exact->inexact (round* real (- digits)))) (rounded-string (number->string rounded-number)) (dot-index (string-index rounded-string #\.)) (exp-index (string-index rounded-string #\e)) (length (string-length rounded-string)) (pre-string (cond (exp-index (if dot-index (substring rounded-string 0 (+ dot-index 1)) (substring rounded-string 0 (+ exp-index 1)))) (dot-index (substring rounded-string 0 (+ dot-index 1))) (else rounded-string))) (exp-string (if exp-index (substring rounded-string exp-index length) "")) (frac-string (if exp-index (substring rounded-string (+ dot-index 1) exp-index) (substring rounded-string (+ dot-index 1) length)))) (string-grow (string-append pre-string (if dot-index "" ".") (string-pad-right frac-string digits #\0) exp-string) width #\space))) (else ;; no digits (string-grow (number->string real) width #\space))))) (else (error 'format "~~F requires a number or a string, got ~s" number-or-string)))) (lambda args (cond ((null? args) (error 'format "required format-string argument is missing")) ((string? (car args)) (apply format #f args)) ((< (length args) 2) (error 'format "too few arguments ~s" args)) (else (let ((output-port (car args)) (format-string (cadr args)) (args (cddr args))) (letrec ((port (cond ((output-port? output-port) output-port) ((eq? output-port #t) (current-output-port)) ((eq? output-port #f) (open-output-string)) (else (error 'format "bad output-port argument: ~s" output-port)))) (return-value (if (eq? output-port #f) ;; if format into a string (lambda () (get-output-string port)) ;; then return the string void))) ;; else do something harmless (define (format-help format-strg arglist) (let ((length-of-format-string (string-length format-strg))) (letrec ((anychar-dispatch (lambda (pos arglist last-was-newline) (if (>= pos length-of-format-string) arglist ; return unused args (let ((char (string-ref format-strg pos))) (cond ((eqv? char #\~) (tilde-dispatch (+ pos 1) arglist last-was-newline)) (else (write-char char port) (anychar-dispatch (+ pos 1) arglist #f))))))) (has-newline? (lambda (whatever last-was-newline) (or (eqv? whatever #\newline) (and (string? whatever) (let ((len (string-length whatever))) (if (zero? len) last-was-newline (eqv? #\newline (string-ref whatever (- len 1))))))))) (tilde-dispatch (lambda (pos arglist last-was-newline) (cond ((>= pos length-of-format-string) (write-char #\~ port) ; tilde at end of string is just output arglist) ; return unused args (else (case (char-upcase (string-ref format-strg pos)) ((#\A) ; Any -- for humans (let ((whatever (car arglist))) (display whatever port) (anychar-dispatch (+ pos 1) (cdr arglist) (has-newline? whatever last-was-newline)))) ((#\S) ; Slashified -- for parsers (let ((whatever (car arglist))) (write whatever port) (anychar-dispatch (+ pos 1) (cdr arglist) (has-newline? whatever last-was-newline)))) ((#\W) (let ((whatever (car arglist))) (let ([old-shared-state (print-shared #t)]) (write whatever port) (print-shared old-shared-state)) (anychar-dispatch (+ pos 1) (cdr arglist) (has-newline? whatever last-was-newline)))) ((#\D) ; Decimal (display (number->string (car arglist) 10) port) (anychar-dispatch (+ pos 1) (cdr arglist) #f)) ((#\X) ; HeXadecimal (display (number->string (car arglist) 16) port) (anychar-dispatch (+ pos 1) (cdr arglist) #f)) ((#\O) ; Octal (display (number->string (car arglist) 8) port) (anychar-dispatch (+ pos 1) (cdr arglist) #f)) ((#\B) ; Binary (display (number->string (car arglist) 2) port) (anychar-dispatch (+ pos 1) (cdr arglist) #f)) ((#\C) ; Character (write-char (car arglist) port) (anychar-dispatch (+ pos 1) (cdr arglist) (eqv? (car arglist) #\newline))) ((#\~) ; Tilde (write-char #\~ port) (anychar-dispatch (+ pos 1) arglist #f)) ((#\%) ; Newline (newline port) (anychar-dispatch (+ pos 1) arglist #t)) ((#\&) ; Freshline (if (not last-was-newline) ;; (unless last-was-newline .. (newline port)) (anychar-dispatch (+ pos 1) arglist #t)) ((#\_) ; Space (write-char #\space port) (anychar-dispatch (+ pos 1) arglist #f)) ((#\T) ; Tab (write-char #\tab port) (anychar-dispatch (+ pos 1) arglist #f)) ((#\Y) ; Pretty-print (pretty-print (car arglist) port) (anychar-dispatch (+ pos 1) (cdr arglist) #f)) ((#\F) (display (format-fixed (car arglist) 0 #f) port) (anychar-dispatch (+ pos 1) (cdr arglist) #f)) ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) ;; gather "~w[,d]F" w and d digits (let loop ((index (+ pos 1)) (w-digits (list (string-ref format-strg pos))) (d-digits '()) (in-width? #t)) (if (>= index length-of-format-string) (error 'format "improper numeric format directive in ~s" format-strg) (let ((next-char (string-ref format-strg index))) (cond ((char-numeric? next-char) (if in-width? (loop (+ index 1) (cons next-char w-digits) d-digits in-width?) (loop (+ index 1) w-digits (cons next-char d-digits) in-width?))) ((char=? next-char #\F) (let ((width (string->number (list->string (reverse w-digits)))) (digits (if (zero? (length d-digits)) #f (string->number (list->string (reverse d-digits)))))) (display (format-fixed (car arglist) width digits) port) (anychar-dispatch (+ index 1) (cdr arglist) #f))) ((char=? next-char #\,) (if in-width? (loop (+ index 1) w-digits d-digits #f) (error 'format "too many commas in directive ~s" format-strg))) (else (error "~~w,dF directive ill-formed in ~s" format-strg))))))) ((#\? #\K) ; indirection -- take next arg as format string (cond ; and following arg as list of format args ((< (length arglist) 2) (error 'format "less arguments than specified for ~~?: ~s" arglist)) ((not (string? (car arglist))) (error 'format "~~? requires a string: ~s" (car arglist))) (else (format-help (car arglist) (cdr arglist)) (anychar-dispatch (+ pos 1) (cddr arglist) #f)))) ((#\H) ; Help (display documentation-string port) (anychar-dispatch (+ pos 1) arglist #t)) (else (error "unknown tilde escape: ~s" (string-ref format-strg pos))))))))) ; format-help main (anychar-dispatch 0 arglist #f)))) ; format main (let ((unused-args (format-help format-string args))) (if (not (null? unused-args)) (error "unused arguments ~s" unused-args)) (return-value))))))))) ;Loads an already expanded file (ie does not run it through the expander) (define (load-expanded file) (call-with-input-file file (lambda (port) (do ((x (read port) (read port))) ((eof-object? x)) (eval (list "noexpand" x)))))) (add-file-handler 'sce load-expanded) (add-file-handler 'pp load-expanded) ;; This code is based on Richard Kelsey and Jonathan Rees' version of ;; dynamic-wind in Scheme48 (http://s48.org). It has been heavily ;; modified to account for SISC's lack of structures, make exception ;; handling work properly and conform with SRFI18 requirements with ;; regard to call/cc behaviour. (define dynamic-wind) (define call-with-current-continuation-unsafe call-with-current-continuation) (define call/cc-unsafe call-with-current-continuation) ;;a point in the dynamic wind stack ;;-this would be easier if we had structures (let-syntax ([point-depth (syntax-rules () ((_ point) (vector-ref point 0)))] [point-in (syntax-rules () ((_ point) (vector-ref point 1)))] [point-out (syntax-rules () ((_ point) (vector-ref point 2)))] [point-parent (syntax-rules () ((_ point) (vector-ref point 3)))]) (let ((original-call/cc call-with-current-continuation)) ;;the dynamic wind stack (define get-dynamic-point current-wind) (define set-dynamic-point! current-wind) (define make-point vector) ; (depth in out parent) ;; (define (travel-between-points here target) (cond ((eq? here target) (set-dynamic-point! here)) ((if here ; HERE has reached the root. (and target (< (point-depth here) (point-depth target))) #t) (travel-between-points here (point-parent target)) ((point-in target)) (set-dynamic-point! target)) (else (set-dynamic-point! (point-parent here)) ((point-out here)) (travel-between-points (point-parent here) target)))) ;;wind-safe call/cc (define (make-wind-safe cont) (let* ((point (get-dynamic-point)) (safe-k (lambda results (travel-between-points (get-dynamic-point) point) (apply cont results)))) (set-annotation! safe-k 'unsafe-cont cont) safe-k)) (define (dynwind-call/cc proc) (original-call/cc (lambda (cont) (proc (make-wind-safe cont))))) (define (dynamic-wind/impl in body out) (let* ((here (get-dynamic-point)) (point (make-point (if here (+ (point-depth here) 1) 1) in out here))) (in) (set-dynamic-point! point) (call-with-values (lambda () (with/fc (lambda (m e) (let ([wind-safe-exception (make-wind-safe e)]) (set-dynamic-point! here) (out) (throw m wind-safe-exception))) body)) (lambda results (set-dynamic-point! here) (out) (apply values results))))) ;;finally, the install the dynamic-wind hooks (set! dynamic-wind dynamic-wind/impl) (set! call-with-current-continuation dynwind-call/cc))) (define call/fc call-with-failure-continuation) (define with/fc with-failure-continuation) (define call/ec call-with-escape-continuation) (define call/cc call-with-current-continuation) (define (with-environment env thunk) (let ([old-env (interaction-environment env)]) (dynamic-wind (lambda () (interaction-environment env)) (lambda () (_with-environment env thunk)) (lambda () (interaction-environment old-env))))) ;;;; "ratize.scm" Convert number to rational number (ported from SLIB) (define rationalize (void)) (letrec ([rational:simplest (lambda (x y) (cond ((< y x) (rational:simplest y x)) ((not (< x y)) (if (rational? x) x (error 'rationalize "~s weirdness" x))) ((positive? x) (sr x y)) ((negative? y) (- (sr (- y) (- x)))) (else (if (and (exact? x) (exact? y)) 0 0.0))))] [sr (lambda (x y) (let ((fx (floor x)) (fy (floor y))) (cond ((not (< fx x)) fx) ((= fx fy) (+ fx (/ (sr (/ (- y fy)) (/ (- x fx)))))) (else (+ 1 fx)))))]) (set! rationalize (lambda (x e) (rational:simplest (- x e) (+ x e))))) (define list-tail (lambda (x k) (if (zero? k) x (list-tail (cdr x) (- k 1))))) (define make-polar (lambda (x y) (make-rectangular (* x (cos y)) (* x (sin y))))) (define magnitude (lambda (x) (cond [(real? x) (abs x)] [else (let ([r (real-part x)] [i (imag-part x)]) (sqrt (+ (* r r) (* i i))))]))) (define angle (lambda (x) (cond [(integer? x) (if (>= x 0) (atan 0 1) (atan 0 -1))] [(real? x) (atan 0 x)] [else (atan (imag-part x) (real-part x))]))) (define (string-copy x) (string-append x)) ;(define (unquote x) ; (error 'unquote "expression ~s not valid outside of a quasiquote." ; x)) ;(define (unquote-splicing x) ; (error 'unquote-splicing "expression ~s valid outside of a quasiquote." ; x)) ;;; macro-defs.ss ;;; Robert Hieb & Kent Dybvig ;;; 92/06/18 ;;; simple delay and force; also defines make-promise (define-syntax delay (lambda (x) (syntax-case x () ((delay exp) (syntax (make-promise (lambda () exp))))))) (define (make-promise proc) (let ([result-ready? #f] [result #!void]) (lambda () (if result-ready? result (let ([x (proc)]) (if result-ready? result (begin (set! result-ready? #t) (set! result x) result))))))) (define (force promise) (promise)) (define-syntax time (lambda (x) (syntax-case x () ((_ e) (syntax (let* ((st (system-time)) (val e) (et (system-time))) (list val (list (- et st) 'ms))))) ((_ n e) (syntax (let* ((st (system-time)) (val (let loop ([x (- n 1)]) (if (zero? x) e (begin e (loop (- x 1)))))) (et (system-time))) (list val (list (quotient (- et st) n) 'avg 'ms)))))))) ;; Unless and When (define-syntax when (syntax-rules () ((_ e0 e1 e2 ...) (if e0 (begin e1 e2 ...))))) (define-syntax unless (syntax-rules () ((_ e0 e1 e2 ...) (if e0 '#!void (begin e1 e2 ...))))) ;;perform macro expansion on a file (define (expand-file from to . scexpopts) (let ([inf (open-source-input-file from)] [outf (open-output-file to)]) (let loop ([e (read-code inf)]) (or (eof-object? e) (let ([source (_analyze! ((current-optimizer) (apply sc-expand e scexpopts)) (interaction-environment))]) (pretty-print source outf) (newline outf) (loop (read-code inf))))) (close-output-port outf) (close-input-port inf))) ;; I/O ;; (define (call-with-input-port&close port proc) (with/fc (lambda (m e) (close-input-port port) (throw m e)) (lambda () (call-with-values (lambda () (proc port)) (lambda results (close-input-port port) (apply values results)))))) (define (call-with-output-port&close port proc) (with/fc (lambda (m e) (close-output-port port) (throw m e)) (lambda () (call-with-values (lambda () (proc port)) (lambda results (close-output-port port) (apply values results)))))) (define (call-with-input-file file procOrEncoding . proc) (cond [(null? proc) (call-with-input-port&close (open-input-file file) procOrEncoding)] [(null? (cdr proc)) (call-with-input-port&close (open-input-file file procOrEncoding) (car proc))] [else (error 'call-with-input-file "too many arguments.")])) (define (call-with-output-file file procOrEncoding . proc) (cond [(null? proc) (call-with-output-port&close (open-output-file file) procOrEncoding)] [(null? (cdr proc)) (call-with-output-port&close (open-output-file file procOrEncoding) (car proc))] [else (error 'call-with-output-file "too many arguments.")])) (define (with-input-from-port port thunk) (let ([cip (current-input-port)]) (dynamic-wind (lambda () (current-input-port port)) thunk (lambda () (current-input-port cip))))) (define (with-output-to-port port thunk) (let ([cop (current-output-port)]) (dynamic-wind (lambda () (current-output-port port)) thunk (lambda () (current-output-port cop))))) (define (with-input-from-file file thunkOrEncoding . thunk) (cond [(null? thunk) (call-with-input-file file (lambda (port) (with-input-from-port port thunkOrEncoding)))] [(null? (cdr thunk)) (call-with-input-file file thunkOrEncoding (lambda (port) (with-input-from-port port (car thunk))))] [else (error 'with-input-from-file "too many arguments.")])) (define (with-output-to-file file thunkOrEncoding . thunk) (cond [(null? thunk) (call-with-output-file file (lambda (port) (with-output-to-port port thunkOrEncoding)))] [(null? (cdr thunk)) (call-with-output-file file thunkOrEncoding (lambda (port) (with-output-to-port port (car thunk))))] [else (error 'with-output-to-file "too many arguments.")])) (define (with-character-set set thunk) (let ([previous-set (character-set)]) (dynamic-wind (lambda () (character-set set)) thunk (lambda () (character-set previous-set))))) (define (with-current-url url thunk) (let ([previous-url (current-url)]) (dynamic-wind (lambda () (current-url (normalize-url previous-url url))) thunk (lambda () (current-url previous-url))))) (set! class-path-extension-append! (let ([original-cpea class-path-extension-append!]) (lambda (urls) (let ([c-url (current-url)]) (original-cpea (map (lambda (url) (normalize-url c-url url)) urls)))))) ;; needed in a few places; cut-down version from SRFI-1 (define (iota count) (do ((count (- count 1) (- count 1)) (ans '() (cons count ans))) ((< count 0) ans))) ;;;;;;;;;;;;;;;; native functions ;;;;;;;;;;;;; (if (getprop 'string-order) (let ((string-order-predicate (lambda (p o) (lambda (str1 str2) (p (o str1 str2) 0))))) ;; string=? isn't present because equal? str1 str2 is far faster (set! string? (string-order-predicate > string-order)) (set! string<=? (string-order-predicate <= string-order)) (set! string>=? (string-order-predicate >= string-order)) (set! string-ci=? (string-order-predicate = string-order-ci)) (set! string-ci>? (string-order-predicate > string-order-ci)) (set! string-ci=? (string-order-predicate >= string-order-ci)))) ;;;;;;;;;;;;; legacy macro support ;;;;;;;;;;;; (define-syntax define-macro (lambda (x) (syntax-case x () ((_ (name . args) . body) (syntax (define-macro name (lambda args . body)))) ((_ name transformer) (syntax (define-syntax name (lambda (y) (syntax-case y () ((_ . args) (datum->syntax-object (syntax _) (apply transformer (syntax-object->datum (syntax args))))))))))))) (define-syntax defmacro (syntax-rules () ((_ name args . body) (define-macro name (lambda args . body))))) ;;our srfi-0 implementation relies on this (define *features* '()) (define (add-feature feature) (if (not (memq feature *features*)) (set! *features* (cons feature *features*)))) (define (add-features features) (for-each add-feature features)) (define (has-feature? feature) (memq feature *features*)) (add-feature 'sisc) ;;hook that gets invoked when SISC is started (define initialize #f) (define repl-initialize #f) (define on-startup #f) (define on-repl-start (let ([repl-start-hooks '()]) (set! repl-initialize (lambda () (for-each (lambda (thunk) (thunk)) (reverse repl-start-hooks)))) (lambda (thunk) (if (not (procedure? thunk)) (error "~a is not a procedure" thunk)) (set! repl-start-hooks (cons thunk repl-start-hooks))))) (let ([*startup-hooks* '()] [startup-enabled? #t]) (set! initialize (lambda () (set! startup-enabled? #f) (for-each (lambda (thunk) (thunk)) (reverse *startup-hooks*)))) (set! on-startup (lambda (thunk) (if (not startup-enabled?) (error "on-startup is only callable during heap build")) (if (not (procedure? thunk)) (error "~a is not a procedure" thunk)) (set! *startup-hooks* (cons thunk *startup-hooks*))))) ;; (if (not (getprop 'LITE (get-symbolic-environment '*sisc*))) (load "../modules/std-modules.scm")) ;;And disable inlining/assumptions (putprop 'assumptive-procedures '*opt* '()) sisc-1.16.6.orig/src/sisc/boot/analyzer.sce0000644000175000017500000012240711445752462017165 0ustar amoeamoe(#%program ((|%%_LBtb5tq6T_make-arecord| . 1) (|%%_LBbVWJs6T_env| . 1) (|%%_LBxRUat6T_arec| . 5) (|%%_LBRYYgs6T_v| . 2) (_expression-type . 1) (|%%_LBXCEQK6T_v| . 3) (|%%_LBjowEM6T_oper| . 1) (|%%_LBldq_N6T_loop| . 2) (|%%_LB16mVO6T_rv| . 2) (not . 1) (|%%_LBH9osO6T_v| . 4) (|%%_LBpTdJQ6T_t| . 2) (|%%_LB3XfgQ6T_t| . 2) (|%%_LBJ-hPP6T_s| . 6) (|%%_LBd4N2X6T_binding| . 3) (|%%_LBz0LvX6T_t| . 2) (map . 1) (cadar . 1) (|%%_LBbfTHV6T_loop| . 2) (|%%_LBT7PBW6T_refs| . 2) (|%%_LBxbR8W6T_bindings| . 3) (cddr . 1) (|%%_LBtx1rT6T_refs| . 1) (|%%_LB7B3-S6T_newlxs| . 2) (|%%_LBPt_TT6T_v| . 1) (|%%_LBNE5xS6T_locals| . 2) (|%%_LB9qZkU6T_refs| . 2) (|%%_LBRiVeV6T_lexicals| . 1) (|%%_LB5M9DR6T_v| . 7) (|%%_LBLPbaR6T_analyzed| . 3) (|%%_LBvmXNU6T_locally-frees| . 2) (eq? . 2) (|%%_LBfVGpY6T_v| . 3) (|%%_LBDvAKL6T_env| . 9) (cadr . 3) (|%%_LB941nr6T_analyze!| . 9) (|%%_LBBRESY6T_locals| . 2) (|%%_LBhKAMZ6T_refs| . 2) (|%%_LBRC0j_5T_in| . 2) (set-car! . 2) (|%%_LBjzu7_6T_lexicals| . 1) (|%%_LBXNCjZ6T_v| . 5) (|%%_LBVYIYX6T_analyzed| . 3) (|%%_LBhzChL6T_arec| . 19) (|%%_LBXgISh6T_arecord-union-frees!| . 2) (|%%_LBZrybM6T_lxs| . 12) (|%%_LBDGyd-6T_locally-frees| . 3) (|%%_LB9K4p-5T_difference| . 5) (|%%_LBFku5N6T_v| . 12) (map-car . 1) (|%%_LB_gsyN6T_exp-type| . 8) (= . 8) (|%%_LBVNKtJ6T_env| . 1) (|%%_LBv0_Pr6T_analyze-app!| . 1) (|%%_LBBkKph6T_arecord-add-free!| . 1) (|%%_LBfKIWJ6T_lxs| . 2) (assq . 4) (|%%_LBzRM0J6T_arec| . 5) (|%%_LB3qlP86T_inc-cdr!| . 4) (|%%_LBBGGnK6T_t| . 2) (|%%_LBdVOzI6T_v| . 8) (symbol? . 2) (|%%_LBP73Wq6T_build-refs| . 4) (cdar . 1) (zero? . 1) (|%%_LBTYQ6I6T_vals| . 5) (|%%_LBx0TFH6T_v| . 1) (vector . 1) (list . 6) (|%%_LB7f70q6T_->proper-list| . 2) (pair? . 3) (|%%_LBb4VcH6T_elem| . 5) (|%%_LBPi1pF6T_v| . 2) (> . 1) (|%%_LBtm3YE6T_newfrees| . 1) (|%%_LBPN6YZ5T_union| . 6) (|%%_LB7q5vE6T_arec| . 2) (|%%_LB5Bb8D6T_arec| . 1) (vector-ref . 19) (|%%_LBNt72E6T_afrees| . 3) (|%%_LBrx9BD6T_newfree| . 2) (+ . 1) (|%%_LBLEdHC6T_v| . 2) (|%%_LBpIfeC6T_ls2| . 1) (|%%_LB3MhNB6T_ls1| . 1) (|%%_LBvG2S-5T_intersection| . 1) (reverse . 1) (|%%_LBl2swz6T_ls1| . 1) (|%%_LB1XnqA6T_loop| . 3) (|%%_LBH-pZz6T_ls2| . 1) (|%%_LBJPjkB6T_acc| . 3) (|%%_LBnTlTA6T_ls1| . 5) (|%%_LBDkCfx6T_ls1| . 1) (|%%_LBjdy9y6T_loop| . 3) (|%%_LBZgAIx6T_ls2| . 1) (|%%_LB_5u3z6T_acc| . 3) (|%%_LBF9wCy6T_ls1| . 5) (|%%_LBTNSDt6T_ls1| . 1) (cons . 19) (|%%_LBXrGlw6T_cc| . 2) (cdr . 35) (|%%_LBzGOxu6T_loop| . 3) (car . 25) (memq . 5) (|%%_LBBvIUv6T_acc| . 3) (|%%_LBdKQ4u6T_ls2| . 3) (set-cdr! . 10) (|%%_LBfzKrv6T_tail| . 5) (|%%_LBVCM-u6T_ls1| . 5) (null? . 7) ($sc-put-cte . 1)) ((|%%_LBldq_N6T_loop| . 1) (|%%_LBbfTHV6T_loop| . 1) (|%%_LB1XnqA6T_loop| . 1) (|%%_LBjdy9y6T_loop| . 1) (|%%_LBzGOxu6T_loop| . 1) (|%%_LBv0_Pr6T_analyze-app!| . 1) (|%%_LB941nr6T_analyze!| . 1) (|%%_LBP73Wq6T_build-refs| . 1) (|%%_LBtb5tq6T_make-arecord| . 1) (|%%_LB7f70q6T_->proper-list| . 1) (|%%_LBrmb6p6T__cdr>0| . 1) (|%%_LBXgISh6T_arecord-union-frees!| . 1) (|%%_LBBkKph6T_arecord-add-free!| . 1) (|%%_LB3qlP86T_inc-cdr!| . 1) (|%%_LBRC0j_5T_in| . 1) (|%%_LBvG2S-5T_intersection| . 1) (|%%_LB9K4p-5T_difference| . 1) (|%%_LBPN6YZ5T_union| . 1) (|%%_LB7Va2Z5T__letrec| . 1) (|%%_LBNYcBY5T_makeannotation| . 1) (|%%_LBr0f8Y5T__define| . 1) (|%%_LB54hHX5T_set| . 1) (|%%_LBL7jeX5T__quote| . 1) (|%%_LBJipTV5T__lambda| . 1) (|%%_LBnmrqV5T_application| . 1) (|%%_LB1qtZU5T_program| . 1)) ($sc-put-cte _expression-type = eq? cadr set-car! not cddr cadar map map-car assq symbol? cdar zero? vector pair? list > vector-ref + reverse null? set-cdr! cons cdr memq car) (#%begin ($sc-put-cte '_analyze! (#%quote (global . _analyze!))) (#%define _analyze! (#%letrec #t ((|%%_LB1qtZU5T_program| 0) (|%%_LBnmrqV5T_application| 1) (|%%_LBJipTV5T__lambda| 2) (|%%_LBL7jeX5T__quote| 5) (|%%_LB54hHX5T_set| 6) (|%%_LBr0f8Y5T__define| 7) (|%%_LBNYcBY5T_makeannotation| 8) (|%%_LB7Va2Z5T__letrec| 9) (|%%_LBPN6YZ5T_union| (#%lambda #t (|%%_LBTNSDt6T_ls1| |%%_LBdKQ4u6T_ls2|) () ((#%letrec #t ((|%%_LBzGOxu6T_loop| (#%lambda #t (|%%_LBVCM-u6T_ls1| |%%_LBfzKrv6T_tail| |%%_LBBvIUv6T_acc|) (|%%_LBzGOxu6T_loop| |%%_LBdKQ4u6T_ls2|) (#%if (null? |%%_LBVCM-u6T_ls1|) (#%if |%%_LBfzKrv6T_tail| (#%begin (set-cdr! |%%_LBfzKrv6T_tail| |%%_LBdKQ4u6T_ls2|) |%%_LBBvIUv6T_acc|) |%%_LBdKQ4u6T_ls2|) (#%if (memq (car |%%_LBVCM-u6T_ls1|) |%%_LBdKQ4u6T_ls2|) (|%%_LBzGOxu6T_loop| (cdr |%%_LBVCM-u6T_ls1|) |%%_LBfzKrv6T_tail| |%%_LBBvIUv6T_acc|) ((#%lambda #t (|%%_LBXrGlw6T_cc|) (|%%_LBfzKrv6T_tail| |%%_LBVCM-u6T_ls1| |%%_LBzGOxu6T_loop|) (|%%_LBzGOxu6T_loop| (cdr |%%_LBVCM-u6T_ls1|) (#%if |%%_LBfzKrv6T_tail| |%%_LBfzKrv6T_tail| |%%_LBXrGlw6T_cc|) |%%_LBXrGlw6T_cc|)) (cons (car |%%_LBVCM-u6T_ls1|) |%%_LBBvIUv6T_acc|))))))) (|%%_LBdKQ4u6T_ls2|) |%%_LBzGOxu6T_loop|) |%%_LBTNSDt6T_ls1| #f ()))) (|%%_LB9K4p-5T_difference| (#%lambda #t (|%%_LBDkCfx6T_ls1| |%%_LBZgAIx6T_ls2|) () ((#%letrec #t ((|%%_LBjdy9y6T_loop| (#%lambda #t (|%%_LBF9wCy6T_ls1| |%%_LB_5u3z6T_acc|) (|%%_LBjdy9y6T_loop| |%%_LBZgAIx6T_ls2|) (#%if (null? |%%_LBF9wCy6T_ls1|) |%%_LB_5u3z6T_acc| (#%if (memq (car |%%_LBF9wCy6T_ls1|) |%%_LBZgAIx6T_ls2|) (|%%_LBjdy9y6T_loop| (cdr |%%_LBF9wCy6T_ls1|) |%%_LB_5u3z6T_acc|) (|%%_LBjdy9y6T_loop| (cdr |%%_LBF9wCy6T_ls1|) (cons (car |%%_LBF9wCy6T_ls1|) |%%_LB_5u3z6T_acc|))))))) (|%%_LBZgAIx6T_ls2|) |%%_LBjdy9y6T_loop|) |%%_LBDkCfx6T_ls1| ()))) (|%%_LBvG2S-5T_intersection| (#%lambda #t (|%%_LBl2swz6T_ls1| |%%_LBH-pZz6T_ls2|) () ((#%letrec #t ((|%%_LB1XnqA6T_loop| (#%lambda #t (|%%_LBnTlTA6T_ls1| |%%_LBJPjkB6T_acc|) (|%%_LB1XnqA6T_loop| |%%_LBH-pZz6T_ls2|) (#%if (null? |%%_LBnTlTA6T_ls1|) |%%_LBJPjkB6T_acc| (#%if (memq (car |%%_LBnTlTA6T_ls1|) |%%_LBH-pZz6T_ls2|) (|%%_LB1XnqA6T_loop| (cdr |%%_LBnTlTA6T_ls1|) (cons (car |%%_LBnTlTA6T_ls1|) |%%_LBJPjkB6T_acc|)) (|%%_LB1XnqA6T_loop| (cdr |%%_LBnTlTA6T_ls1|) |%%_LBJPjkB6T_acc|)))))) (|%%_LBH-pZz6T_ls2|) |%%_LB1XnqA6T_loop|) |%%_LBl2swz6T_ls1| ()))) (|%%_LBRC0j_5T_in| (#%lambda #t (|%%_LB3MhNB6T_ls1| |%%_LBpIfeC6T_ls2|) (|%%_LBvG2S-5T_intersection|) (reverse (|%%_LBvG2S-5T_intersection| |%%_LB3MhNB6T_ls1| |%%_LBpIfeC6T_ls2|)))) (|%%_LB3qlP86T_inc-cdr!| (#%lambda #t (|%%_LBLEdHC6T_v|) () (set-cdr! |%%_LBLEdHC6T_v| (+ 1 (cdr |%%_LBLEdHC6T_v|))))) (|%%_LBBkKph6T_arecord-add-free!| (#%lambda #t (|%%_LB5Bb8D6T_arec| |%%_LBrx9BD6T_newfree|) () ((#%lambda #t (|%%_LBNt72E6T_afrees|) (|%%_LBrx9BD6T_newfree|) (#%if (memq |%%_LBrx9BD6T_newfree| (cdr |%%_LBNt72E6T_afrees|)) #!void (set-cdr! |%%_LBNt72E6T_afrees| (cons |%%_LBrx9BD6T_newfree| (cdr |%%_LBNt72E6T_afrees|))))) (vector-ref |%%_LB5Bb8D6T_arec| 2)))) (|%%_LBXgISh6T_arecord-union-frees!| (#%lambda #t (|%%_LB7q5vE6T_arec| |%%_LBtm3YE6T_newfrees|) (|%%_LBPN6YZ5T_union|) (set-cdr! (vector-ref |%%_LB7q5vE6T_arec| 2) (|%%_LBPN6YZ5T_union| (cdr (vector-ref |%%_LB7q5vE6T_arec| 2)) |%%_LBtm3YE6T_newfrees|)))) (|%%_LBrmb6p6T__cdr>0| (#%lambda #t (|%%_LBPi1pF6T_v|) () (#%if (> (cdr |%%_LBPi1pF6T_v|) 0) (cdr |%%_LBPi1pF6T_v|) #f))) (|%%_LB7f70q6T_->proper-list| (#%lambda #t (|%%_LBb4VcH6T_elem|) (|%%_LB7f70q6T_->proper-list|) (#%if (null? |%%_LBb4VcH6T_elem|) () (#%if (pair? |%%_LBb4VcH6T_elem|) (cons (car |%%_LBb4VcH6T_elem|) (|%%_LB7f70q6T_->proper-list| (cdr |%%_LBb4VcH6T_elem|))) (list |%%_LBb4VcH6T_elem|))))) (|%%_LBtb5tq6T_make-arecord| (#%lambda #t (|%%_LBx0TFH6T_v|) () (vector (list (#%quote *refs*)) (list (#%quote *sets*)) (list (#%quote *frees*)) |%%_LBx0TFH6T_v|))) (|%%_LBP73Wq6T_build-refs| (#%lambda #t (|%%_LBTYQ6I6T_vals|) (|%%_LBP73Wq6T_build-refs|) (#%if (null? |%%_LBTYQ6I6T_vals|) () (#%if (zero? (cdar |%%_LBTYQ6I6T_vals|)) (|%%_LBP73Wq6T_build-refs| (cdr |%%_LBTYQ6I6T_vals|)) (cons (car |%%_LBTYQ6I6T_vals|) (|%%_LBP73Wq6T_build-refs| (cdr |%%_LBTYQ6I6T_vals|))))))) (|%%_LB941nr6T_analyze!| (#%lambda #t (|%%_LBdVOzI6T_v| |%%_LBzRM0J6T_arec| |%%_LBVNKtJ6T_env| |%%_LBfKIWJ6T_lxs|) (|%%_LBv0_Pr6T_analyze-app!| |%%_LBBkKph6T_arecord-add-free!| |%%_LB3qlP86T_inc-cdr!|) (#%if (symbol? |%%_LBdVOzI6T_v|) (#%begin ((#%lambda #t (|%%_LBBGGnK6T_t|) (|%%_LBzRM0J6T_arec| |%%_LBdVOzI6T_v| |%%_LB3qlP86T_inc-cdr!|) (#%if |%%_LBBGGnK6T_t| (|%%_LB3qlP86T_inc-cdr!| |%%_LBBGGnK6T_t|) (set-cdr! (vector-ref |%%_LBzRM0J6T_arec| 0) (cons (cons |%%_LBdVOzI6T_v| 1) (cdr (vector-ref |%%_LBzRM0J6T_arec| 0)))))) (assq |%%_LBdVOzI6T_v| (cdr (vector-ref |%%_LBzRM0J6T_arec| 0)))) (#%if (memq |%%_LBdVOzI6T_v| |%%_LBfKIWJ6T_lxs|) #!void (|%%_LBBkKph6T_arecord-add-free!| |%%_LBzRM0J6T_arec| |%%_LBdVOzI6T_v|)) (list |%%_LBdVOzI6T_v|)) (#%if (pair? |%%_LBdVOzI6T_v|) (|%%_LBv0_Pr6T_analyze-app!| |%%_LBdVOzI6T_v| |%%_LBzRM0J6T_arec| |%%_LBVNKtJ6T_env| |%%_LBfKIWJ6T_lxs|) ())))) (|%%_LBv0_Pr6T_analyze-app!| (#%lambda #t (|%%_LBXCEQK6T_v| |%%_LBhzChL6T_arec| |%%_LBDvAKL6T_env| |%%_LBZrybM6T_lxs|) (|%%_LB941nr6T_analyze!| |%%_LB7f70q6T_->proper-list| |%%_LBXgISh6T_arecord-union-frees!| |%%_LB3qlP86T_inc-cdr!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LBjowEM6T_oper| |%%_LBFku5N6T_v| |%%_LB_gsyN6T_exp-type|) (|%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LB7f70q6T_->proper-list| |%%_LBXgISh6T_arecord-union-frees!| |%%_LB3qlP86T_inc-cdr!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) (#%if (= |%%_LB_gsyN6T_exp-type| 5) () (#%if (= |%%_LB_gsyN6T_exp-type| 0) (map-car (car |%%_LBFku5N6T_v|)) (#%if (= |%%_LB_gsyN6T_exp-type| 2) ((#%lambda #t (|%%_LBVYIYX6T_analyzed|) (|%%_LBFku5N6T_v| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LB7f70q6T_->proper-list| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LBfVGpY6T_v|) (|%%_LBVYIYX6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LB7f70q6T_->proper-list| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LBBRESY6T_locals|) (|%%_LBfVGpY6T_v| |%%_LBVYIYX6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LBXNCjZ6T_v|) (|%%_LBBRESY6T_locals| |%%_LBVYIYX6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LBhKAMZ6T_refs|) (|%%_LBXNCjZ6T_v| |%%_LBBRESY6T_locals| |%%_LBVYIYX6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBhzChL6T_arec| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference|) ((#%lambda #t (|%%_LBDGyd-6T_locally-frees|) (|%%_LBhKAMZ6T_refs| |%%_LBXNCjZ6T_v| |%%_LBVYIYX6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBhzChL6T_arec| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference|) (#%begin (|%%_LB9K4p-5T_difference| |%%_LBDGyd-6T_locally-frees| |%%_LBZrybM6T_lxs|) ((#%lambda #t (|%%_LBjzu7_6T_lexicals|) (|%%_LBDGyd-6T_locally-frees| |%%_LBXNCjZ6T_v| |%%_LBVYIYX6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBhzChL6T_arec| |%%_LBXgISh6T_arecord-union-frees!| |%%_LB9K4p-5T_difference|) (#%begin (|%%_LBXgISh6T_arecord-union-frees!| |%%_LBhzChL6T_arec| (|%%_LB9K4p-5T_difference| |%%_LBDGyd-6T_locally-frees| |%%_LBZrybM6T_lxs|)) (#%if |%%_LBVYIYX6T_analyzed| #!void (#%begin (set-cdr! |%%_LBXNCjZ6T_v| (cons (car |%%_LBXNCjZ6T_v|) (cons |%%_LBjzu7_6T_lexicals| (cdr |%%_LBXNCjZ6T_v|)))) (set-car! |%%_LBXNCjZ6T_v| #t))) |%%_LBDGyd-6T_locally-frees|)) (|%%_LBRC0j_5T_in| |%%_LBZrybM6T_lxs| |%%_LBhKAMZ6T_refs|)))) (|%%_LB9K4p-5T_difference| |%%_LBhKAMZ6T_refs| |%%_LBBRESY6T_locals|))) (|%%_LB941nr6T_analyze!| (cadr |%%_LBXNCjZ6T_v|) |%%_LBhzChL6T_arec| |%%_LBDvAKL6T_env| (|%%_LBPN6YZ5T_union| |%%_LBBRESY6T_locals| |%%_LBZrybM6T_lxs|)))) (#%if |%%_LBVYIYX6T_analyzed| (cdr |%%_LBfVGpY6T_v|) |%%_LBfVGpY6T_v|))) (|%%_LB7f70q6T_->proper-list| (car |%%_LBfVGpY6T_v|)))) (#%if |%%_LBVYIYX6T_analyzed| (cdr |%%_LBFku5N6T_v|) |%%_LBFku5N6T_v|))) (eq? (car |%%_LBFku5N6T_v|) #t)) (#%if (= |%%_LB_gsyN6T_exp-type| 9) ((#%lambda #t (|%%_LBLPbaR6T_analyzed|) (|%%_LBFku5N6T_v| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBXgISh6T_arecord-union-frees!| |%%_LB3qlP86T_inc-cdr!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LB5M9DR6T_v|) (|%%_LBLPbaR6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBXgISh6T_arecord-union-frees!| |%%_LB3qlP86T_inc-cdr!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LBNE5xS6T_locals|) (|%%_LB5M9DR6T_v| |%%_LBLPbaR6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LB7B3-S6T_newlxs|) (|%%_LBNE5xS6T_locals| |%%_LB5M9DR6T_v| |%%_LBLPbaR6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LBtx1rT6T_refs|) (|%%_LB7B3-S6T_newlxs| |%%_LBNE5xS6T_locals| |%%_LB5M9DR6T_v| |%%_LBLPbaR6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LBPt_TT6T_v|) (|%%_LBtx1rT6T_refs| |%%_LB7B3-S6T_newlxs| |%%_LBNE5xS6T_locals| |%%_LB5M9DR6T_v| |%%_LBLPbaR6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference| |%%_LBPN6YZ5T_union|) ((#%lambda #t (|%%_LB9qZkU6T_refs|) (|%%_LBNE5xS6T_locals| |%%_LB5M9DR6T_v| |%%_LBLPbaR6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBhzChL6T_arec| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference|) ((#%lambda #t (|%%_LBvmXNU6T_locally-frees|) (|%%_LB9qZkU6T_refs| |%%_LB5M9DR6T_v| |%%_LBLPbaR6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBhzChL6T_arec| |%%_LBXgISh6T_arecord-union-frees!| |%%_LBRC0j_5T_in| |%%_LB9K4p-5T_difference|) ((#%lambda #t (|%%_LBRiVeV6T_lexicals|) (|%%_LBvmXNU6T_locally-frees| |%%_LB5M9DR6T_v| |%%_LBLPbaR6T_analyzed| |%%_LBZrybM6T_lxs| |%%_LBhzChL6T_arec| |%%_LBXgISh6T_arecord-union-frees!| |%%_LB9K4p-5T_difference|) (#%begin (|%%_LBXgISh6T_arecord-union-frees!| |%%_LBhzChL6T_arec| (|%%_LB9K4p-5T_difference| |%%_LBvmXNU6T_locally-frees| |%%_LBZrybM6T_lxs|)) (#%if |%%_LBLPbaR6T_analyzed| #!void (#%begin (set-cdr! |%%_LB5M9DR6T_v| (cons (car |%%_LB5M9DR6T_v|) (cons |%%_LBRiVeV6T_lexicals| (cdr |%%_LB5M9DR6T_v|)))) (set-car! |%%_LB5M9DR6T_v| #t))) |%%_LBvmXNU6T_locally-frees|)) (|%%_LBRC0j_5T_in| |%%_LBZrybM6T_lxs| |%%_LB9qZkU6T_refs|))) (|%%_LB9K4p-5T_difference| |%%_LB9qZkU6T_refs| |%%_LBNE5xS6T_locals|))) (|%%_LBPN6YZ5T_union| (|%%_LB941nr6T_analyze!| (car |%%_LBPt_TT6T_v|) |%%_LBhzChL6T_arec| |%%_LBDvAKL6T_env| |%%_LB7B3-S6T_newlxs|) |%%_LBtx1rT6T_refs|))) ((#%if |%%_LBLPbaR6T_analyzed| cddr cdr) |%%_LB5M9DR6T_v|))) ((#%letrec #t ((|%%_LBbfTHV6T_loop| (#%lambda #t (|%%_LBxbR8W6T_bindings| |%%_LBT7PBW6T_refs|) (|%%_LBbfTHV6T_loop| |%%_LB7B3-S6T_newlxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBPN6YZ5T_union|) (#%if (null? |%%_LBxbR8W6T_bindings|) |%%_LBT7PBW6T_refs| (|%%_LBbfTHV6T_loop| (cdr |%%_LBxbR8W6T_bindings|) (|%%_LBPN6YZ5T_union| (|%%_LB941nr6T_analyze!| (cadar |%%_LBxbR8W6T_bindings|) |%%_LBhzChL6T_arec| |%%_LBDvAKL6T_env| |%%_LB7B3-S6T_newlxs|) |%%_LBT7PBW6T_refs|)))))) (|%%_LB7B3-S6T_newlxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBPN6YZ5T_union|) |%%_LBbfTHV6T_loop|) (car |%%_LB5M9DR6T_v|) ()))) (|%%_LBPN6YZ5T_union| |%%_LBNE5xS6T_locals| |%%_LBZrybM6T_lxs|))) (map (#%lambda #t (|%%_LBd4N2X6T_binding|) (|%%_LBhzChL6T_arec| |%%_LB3qlP86T_inc-cdr!|) (#%begin ((#%lambda #t (|%%_LBz0LvX6T_t|) (|%%_LBd4N2X6T_binding| |%%_LBhzChL6T_arec| |%%_LB3qlP86T_inc-cdr!|) (#%if |%%_LBz0LvX6T_t| (|%%_LB3qlP86T_inc-cdr!| |%%_LBz0LvX6T_t|) (set-cdr! (vector-ref |%%_LBhzChL6T_arec| 1) (cons (cons (car |%%_LBd4N2X6T_binding|) 1) (cdr (vector-ref |%%_LBhzChL6T_arec| 1)))))) (assq (car |%%_LBd4N2X6T_binding|) (cdr (vector-ref |%%_LBhzChL6T_arec| 1)))) (car |%%_LBd4N2X6T_binding|))) (car |%%_LB5M9DR6T_v|)))) (#%if |%%_LBLPbaR6T_analyzed| (cdr |%%_LBFku5N6T_v|) |%%_LBFku5N6T_v|))) (eq? (car |%%_LBFku5N6T_v|) #t)) (#%if (= |%%_LB_gsyN6T_exp-type| 6) ((#%lambda #t (|%%_LBJ-hPP6T_s|) (|%%_LBFku5N6T_v| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LB3qlP86T_inc-cdr!|) (#%begin (#%if (symbol? |%%_LBJ-hPP6T_s|) (#%begin ((#%lambda #t (|%%_LB3XfgQ6T_t|) (|%%_LBJ-hPP6T_s| |%%_LBhzChL6T_arec| |%%_LB3qlP86T_inc-cdr!|) (#%if |%%_LB3XfgQ6T_t| (|%%_LB3qlP86T_inc-cdr!| |%%_LB3XfgQ6T_t|) (set-cdr! (vector-ref |%%_LBhzChL6T_arec| 0) (cons (cons |%%_LBJ-hPP6T_s| 1) (cdr (vector-ref |%%_LBhzChL6T_arec| 0)))))) (assq |%%_LBJ-hPP6T_s| (cdr (vector-ref |%%_LBhzChL6T_arec| 0)))) ((#%lambda #t (|%%_LBpTdJQ6T_t|) (|%%_LBJ-hPP6T_s| |%%_LBhzChL6T_arec| |%%_LB3qlP86T_inc-cdr!|) (#%if |%%_LBpTdJQ6T_t| (|%%_LB3qlP86T_inc-cdr!| |%%_LBpTdJQ6T_t|) (set-cdr! (vector-ref |%%_LBhzChL6T_arec| 1) (cons (cons |%%_LBJ-hPP6T_s| 1) (cdr (vector-ref |%%_LBhzChL6T_arec| 1)))))) (assq |%%_LBJ-hPP6T_s| (cdr (vector-ref |%%_LBhzChL6T_arec| 1))))) #!void) (cons |%%_LBJ-hPP6T_s| (|%%_LB941nr6T_analyze!| (cadr |%%_LBFku5N6T_v|) |%%_LBhzChL6T_arec| |%%_LBDvAKL6T_env| |%%_LBZrybM6T_lxs|)))) (car |%%_LBFku5N6T_v|)) (#%if (= |%%_LB_gsyN6T_exp-type| 7) (|%%_LB941nr6T_analyze!| (cadr |%%_LBFku5N6T_v|) |%%_LBhzChL6T_arec| |%%_LBDvAKL6T_env| |%%_LBZrybM6T_lxs|) (#%if (= |%%_LB_gsyN6T_exp-type| 8) (|%%_LB941nr6T_analyze!| (car |%%_LBFku5N6T_v|) |%%_LBhzChL6T_arec| |%%_LBDvAKL6T_env| |%%_LBZrybM6T_lxs|) ((#%letrec #t ((|%%_LBldq_N6T_loop| (#%lambda #t (|%%_LBH9osO6T_v| |%%_LB16mVO6T_rv|) (|%%_LBldq_N6T_loop| |%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBPN6YZ5T_union|) (#%if (#%if (null? |%%_LBH9osO6T_v|) #t (not (pair? |%%_LBH9osO6T_v|))) |%%_LB16mVO6T_rv| (|%%_LBldq_N6T_loop| (cdr |%%_LBH9osO6T_v|) (|%%_LBPN6YZ5T_union| (|%%_LB941nr6T_analyze!| (car |%%_LBH9osO6T_v|) |%%_LBhzChL6T_arec| |%%_LBDvAKL6T_env| |%%_LBZrybM6T_lxs|) |%%_LB16mVO6T_rv|)))))) (|%%_LBZrybM6T_lxs| |%%_LBDvAKL6T_env| |%%_LBhzChL6T_arec| |%%_LB941nr6T_analyze!| |%%_LBPN6YZ5T_union|) |%%_LBldq_N6T_loop|) |%%_LBFku5N6T_v| (#%if (= |%%_LB_gsyN6T_exp-type| 1) (|%%_LB941nr6T_analyze!| |%%_LBjowEM6T_oper| |%%_LBhzChL6T_arec| |%%_LBDvAKL6T_env| |%%_LBZrybM6T_lxs|) ())))))))))) (car |%%_LBXCEQK6T_v|) (cdr |%%_LBXCEQK6T_v|) (_expression-type |%%_LBDvAKL6T_env| (car |%%_LBXCEQK6T_v|)))))) () (#%lambda #t (|%%_LBRYYgs6T_v| |%%_LBbVWJs6T_env|) (|%%_LB941nr6T_analyze!| |%%_LBP73Wq6T_build-refs| |%%_LBtb5tq6T_make-arecord|) ((#%lambda #t (|%%_LBxRUat6T_arec|) (|%%_LBbVWJs6T_env| |%%_LBRYYgs6T_v| |%%_LB941nr6T_analyze!| |%%_LBP73Wq6T_build-refs|) (#%begin (|%%_LB941nr6T_analyze!| |%%_LBRYYgs6T_v| |%%_LBxRUat6T_arec| |%%_LBbVWJs6T_env| ()) (list #%program (|%%_LBP73Wq6T_build-refs| (cdr (vector-ref |%%_LBxRUat6T_arec| 0))) (|%%_LBP73Wq6T_build-refs| (cdr (vector-ref |%%_LBxRUat6T_arec| 1))) (cdr (vector-ref |%%_LBxRUat6T_arec| 2)) (vector-ref |%%_LBxRUat6T_arec| 3)))) (|%%_LBtb5tq6T_make-arecord| |%%_LBRYYgs6T_v|))))))) sisc-1.16.6.orig/src/sisc/boot/init.sce0000644000175000017500000017602411445752462016307 0ustar amoeamoe(#%program ((_make-native-parameter . 1)) () (_make-native-parameter) (#%define hedged-inlining (_make-native-parameter "hedgedInlining"))) (#%program ((hedged-inlining . 1)) () (hedged-inlining) (hedged-inlining #f)) (#%program () () () #!void) (#%program ((map-cdr . 1) (for-each . 1) (map-car . 1) (|%%_f7IgJHTds_proc| . 2) (apply . 2) (cons . 1) (|%%_f70oNNSds_lists| . 4) (|%%_f7mkLeTds_ls1| . 2) (null? . 1)) ((|%%_f70oNNSds_lists| . 1)) (cons map-car apply map-cdr for-each null?) (#%define for-each (#%lambda #t (|%%_f7IgJHTds_proc| |%%_f7mkLeTds_ls1| . |%%_f70oNNSds_lists|) () (#%if (null? |%%_f7mkLeTds_ls1|) #!void (#%begin (#%set! |%%_f70oNNSds_lists| (cons |%%_f7mkLeTds_ls1| |%%_f70oNNSds_lists|)) (apply |%%_f7IgJHTds_proc| (map-car |%%_f70oNNSds_lists|)) (apply for-each |%%_f7IgJHTds_proc| (map-cdr |%%_f70oNNSds_lists|))))))) (#%program ((|%%_f72dH8Uds_x| . 1) (eq? . 1)) () (eq?) (#%define eof-object? (#%lambda #t (|%%_f72dH8Uds_x|) () (eq? |%%_f72dH8Uds_x| #!eof)))) (#%program ((|%%_f7o9FBUds_x| . 1)) () () (#%define not (#%lambda #t (|%%_f7o9FBUds_x|) () (#%if |%%_f7o9FBUds_x| #f #t)))) (#%program ((|%%_f7K5D2Vds_port| . 1) (display . 1) (apply . 1)) () (display apply) (#%define newline (#%lambda #t |%%_f7K5D2Vds_port| () (apply display #\newline |%%_f7K5D2Vds_port|)))) (#%program ((|%%_f7q-yYVds_ls| . 1) (car . 1) (cons . 1) (cdr . 1) (|%%_f742BvVds_iter| . 2) (|%%_f76TuSWds_acc| . 2) (|%%_f7MWwpWds_ls| . 3) (null? . 1)) ((|%%_f742BvVds_iter| . 1)) (cdr car cons null?) (#%define reverse (#%letrec #t ((|%%_f742BvVds_iter| (#%lambda #t (|%%_f7MWwpWds_ls| |%%_f76TuSWds_acc|) (|%%_f742BvVds_iter|) (#%if (null? |%%_f7MWwpWds_ls|) |%%_f76TuSWds_acc| (|%%_f742BvVds_iter| (cdr |%%_f7MWwpWds_ls|) (cons (car |%%_f7MWwpWds_ls|) |%%_f76TuSWds_acc|)))))) () (#%lambda #t (|%%_f7q-yYVds_ls|) (|%%_f742BvVds_iter|) (|%%_f742BvVds_iter| |%%_f7q-yYVds_ls| ()))))) (#%program ((|%%_f7OLqMXds_s| . 1) (cdr . 1) (|%%_f7QAk7Zds_d| . 1) (|%%_f7sPsjXds_iter| . 2) (set-cdr! . 1) (|%%_f7uEmGYds_r| . 2) (|%%_f78IodYds_s| . 4) (null? . 1)) ((|%%_f7sPsjXds_iter| . 1)) (set-cdr! cdr null?) (#%define reverse! (#%letrec #t ((|%%_f7sPsjXds_iter| (#%lambda #t (|%%_f78IodYds_s| |%%_f7uEmGYds_r|) (|%%_f7sPsjXds_iter|) (#%if (null? |%%_f78IodYds_s|) |%%_f7uEmGYds_r| ((#%lambda #t (|%%_f7QAk7Zds_d|) (|%%_f7uEmGYds_r| |%%_f78IodYds_s| |%%_f7sPsjXds_iter|) (#%begin (set-cdr! |%%_f78IodYds_s| |%%_f7uEmGYds_r|) (|%%_f7sPsjXds_iter| |%%_f7QAk7Zds_d| |%%_f78IodYds_s|))) (cdr |%%_f78IodYds_s|)))))) () (#%lambda #t (|%%_f7OLqMXds_s|) (|%%_f7sPsjXds_iter|) (|%%_f7sPsjXds_iter| |%%_f7OLqMXds_s| ()))))) (#%program ((cdr . 1) (map-car . 1) (caar . 1) (cons . 1) (|%%_f7axiAZds_ls| . 3) (null? . 1)) () (cons caar cdr map-car null?) (#%define map-car (#%lambda #t (|%%_f7axiAZds_ls|) () (#%if (null? |%%_f7axiAZds_ls|) () (cons (caar |%%_f7axiAZds_ls|) (map-car (cdr |%%_f7axiAZds_ls|))))))) (#%program ((cdr . 1) (map-cdr . 1) (cdar . 1) (cons . 1) (%%_f7wtg1-ds_ls . 3) (null? . 1)) () (cons cdar cdr map-cdr null?) (#%define map-cdr (#%lambda #t (%%_f7wtg1-ds_ls) () (#%if (null? %%_f7wtg1-ds_ls) () (cons (cdar %%_f7wtg1-ds_ls) (map-cdr (cdr %%_f7wtg1-ds_ls))))))) (#%program ((|%%_f7Ue8R_ds_list1| . 2) (%%_f7eb6i0es_proc . 2) (%%_f7yiao_ds_lists . 2) (map-car . 1) (apply . 1) (|%%_f7iRV_2es_lists| . 2) (map-cdr . 1) (|%%_f7CYZ52es_proc| . 2) (|%%_f7cmcX-ds_loop| . 2) (|%%_f7ENTs3es_c| . 2) (|%%_f7YUXy2es_list1| . 3) (car . 2) (cons . 2) (cdr . 2) (|%%_f7A74L0es_proc| . 2) (|%%_f7Speu-ds_map1| . 2) (|%%_f7g00F1es_acc| . 2) (reverse . 2) (|%%_f7W32c1es_list| . 3) (null? . 3)) ((|%%_f7cmcX-ds_loop| . 1) (|%%_f7Speu-ds_map1| . 1)) (map-cdr apply map-car cdr car cons reverse null?) (#%define map (#%letrec #t ((|%%_f7Speu-ds_map1| (#%lambda #t (|%%_f7A74L0es_proc| |%%_f7W32c1es_list| |%%_f7g00F1es_acc|) (|%%_f7Speu-ds_map1|) (#%if (null? |%%_f7W32c1es_list|) (reverse |%%_f7g00F1es_acc|) (|%%_f7Speu-ds_map1| |%%_f7A74L0es_proc| (cdr |%%_f7W32c1es_list|) (cons (|%%_f7A74L0es_proc| (car |%%_f7W32c1es_list|)) |%%_f7g00F1es_acc|))))) (|%%_f7cmcX-ds_loop| (#%lambda #t (|%%_f7CYZ52es_proc| |%%_f7YUXy2es_list1| |%%_f7iRV_2es_lists| |%%_f7ENTs3es_c|) (|%%_f7cmcX-ds_loop|) (#%if (null? |%%_f7YUXy2es_list1|) (reverse |%%_f7ENTs3es_c|) (|%%_f7cmcX-ds_loop| |%%_f7CYZ52es_proc| (cdr |%%_f7YUXy2es_list1|) (map-cdr |%%_f7iRV_2es_lists|) (cons (apply |%%_f7CYZ52es_proc| (car |%%_f7YUXy2es_list1|) (map-car |%%_f7iRV_2es_lists|)) |%%_f7ENTs3es_c|)))))) () (#%lambda #t (%%_f7eb6i0es_proc |%%_f7Ue8R_ds_list1| . %%_f7yiao_ds_lists) (|%%_f7cmcX-ds_loop| |%%_f7Speu-ds_map1|) (#%if (null? %%_f7yiao_ds_lists) (|%%_f7Speu-ds_map1| %%_f7eb6i0es_proc |%%_f7Ue8R_ds_list1| ()) (|%%_f7cmcX-ds_loop| %%_f7eb6i0es_proc |%%_f7Ue8R_ds_list1| %%_f7yiao_ds_lists ())))))) (#%program ((|%%_f7GCNP4es_x| . 1) (|%%_f7kGPm4es_g| . 1) (|%%_f7-JRV3es_f| . 1)) () () (#%define compose2 (#%lambda #t (|%%_f7-JRV3es_f| |%%_f7kGPm4es_g|) () (#%lambda #t (|%%_f7GCNP4es_x|) (|%%_f7kGPm4es_g| |%%_f7-JRV3es_f|) (|%%_f7-JRV3es_f| (|%%_f7kGPm4es_g| |%%_f7GCNP4es_x|)))))) (#%program ((void . 1)) () (void) (#%define assq (void))) (#%program ((void . 1)) () (void) (#%define assv (void))) (#%program ((void . 1)) () (void) (#%define assoc (void))) (#%program ((void . 1)) () (void) (#%define memq (void))) (#%program ((void . 1)) () (void) (#%define memv (void))) (#%program ((void . 1)) () (void) (#%define member (void))) (#%program ((|%%_f7uPk9bes_list| . 1) (|%%_f78TmIaes_obj| . 1) (member . 1) (|%%_f7OWofaes_list| . 1) (|%%_f7s-qO9es_obj| . 1) (memv . 1) (%%_f762tl9es_list . 1) (|%%_f7M5vU8es_obj| . 1) (memq . 1) (%%_f7q9xr8es_alist . 1) (%%_f74dz-7es_obj . 1) (equal? . 2) (assoc . 1) (|%%_f7KgBx7es_alist| . 1) (|%%_f7okD47es_obj| . 1) (eqv? . 2) (assv . 1) (|%%_f72oFD6es_alist| . 1) (|%%_f7IrHa6es_obj| . 1) (eq? . 2) (assq . 1) (|%%_f7mvJJ5es_memn| . 4) (%%_f7cxaqdes_obj . 2) (|%%_f7SAcZces_n| . 2) (|%%_f7yt8Tdes_list| . 4) (cdr . 2) (|%%_f70zLg5es_assn| . 4) (car . 2) (|%%_f7aIg3ces_obj| . 2) (caar . 1) (|%%_f7QLiCbes_n| . 2) (|%%_f7wEewces_alist| . 4) (null? . 2)) ((member . 1) (memv . 1) (memq . 1) (assoc . 1) (assv . 1) (assq . 1) (|%%_f7mvJJ5es_memn| . 1) (|%%_f70zLg5es_assn| . 1)) (assq eq? assv eqv? assoc equal? memq memv member caar car cdr null?) (#%letrec #t ((|%%_f70zLg5es_assn| (#%lambda #t (|%%_f7QLiCbes_n| |%%_f7aIg3ces_obj| |%%_f7wEewces_alist|) (|%%_f70zLg5es_assn|) (#%if (null? |%%_f7wEewces_alist|) #f (#%if (|%%_f7QLiCbes_n| (caar |%%_f7wEewces_alist|) |%%_f7aIg3ces_obj|) (car |%%_f7wEewces_alist|) (|%%_f70zLg5es_assn| |%%_f7QLiCbes_n| |%%_f7aIg3ces_obj| (cdr |%%_f7wEewces_alist|)))))) (|%%_f7mvJJ5es_memn| (#%lambda #t (|%%_f7SAcZces_n| %%_f7cxaqdes_obj |%%_f7yt8Tdes_list|) (|%%_f7mvJJ5es_memn|) (#%if (null? |%%_f7yt8Tdes_list|) #f (#%if (|%%_f7SAcZces_n| (car |%%_f7yt8Tdes_list|) %%_f7cxaqdes_obj) |%%_f7yt8Tdes_list| (|%%_f7mvJJ5es_memn| |%%_f7SAcZces_n| %%_f7cxaqdes_obj (cdr |%%_f7yt8Tdes_list|))))))) () (#%begin (#%set! assq (#%lambda #t (|%%_f7IrHa6es_obj| |%%_f72oFD6es_alist|) (|%%_f70zLg5es_assn|) (|%%_f70zLg5es_assn| eq? |%%_f7IrHa6es_obj| |%%_f72oFD6es_alist|))) (#%set! assv (#%lambda #t (|%%_f7okD47es_obj| |%%_f7KgBx7es_alist|) (|%%_f70zLg5es_assn|) (|%%_f70zLg5es_assn| eqv? |%%_f7okD47es_obj| |%%_f7KgBx7es_alist|))) (#%set! assoc (#%lambda #t (%%_f74dz-7es_obj %%_f7q9xr8es_alist) (|%%_f70zLg5es_assn|) (|%%_f70zLg5es_assn| equal? %%_f74dz-7es_obj %%_f7q9xr8es_alist))) (#%set! memq (#%lambda #t (|%%_f7M5vU8es_obj| %%_f762tl9es_list) (|%%_f7mvJJ5es_memn|) (|%%_f7mvJJ5es_memn| eq? |%%_f7M5vU8es_obj| %%_f762tl9es_list))) (#%set! memv (#%lambda #t (|%%_f7s-qO9es_obj| |%%_f7OWofaes_list|) (|%%_f7mvJJ5es_memn|) (|%%_f7mvJJ5es_memn| eqv? |%%_f7s-qO9es_obj| |%%_f7OWofaes_list|))) (#%set! member (#%lambda #t (|%%_f78TmIaes_obj| |%%_f7uPk9bes_list|) (|%%_f7mvJJ5es_memn|) (|%%_f7mvJJ5es_memn| equal? |%%_f78TmIaes_obj| |%%_f7uPk9bes_list|)))))) (#%program ((cdr . 1) (car . 1) (compose2 . 1)) () (cdr car compose2) (#%define cadr (compose2 car cdr))) (#%program ((car . 1) (cdr . 1) (compose2 . 1)) () (car cdr compose2) (#%define cdar (compose2 cdr car))) (#%program ((cdr . 2) (compose2 . 1)) () (cdr compose2) (#%define cddr (compose2 cdr cdr))) (#%program ((car . 2) (compose2 . 1)) () (car compose2) (#%define caar (compose2 car car))) (#%program ((caar . 1) (car . 1) (compose2 . 1)) () (caar car compose2) (#%define caaar (compose2 car caar))) (#%program ((cadr . 1) (car . 1) (compose2 . 1)) () (cadr car compose2) (#%define caadr (compose2 car cadr))) (#%program ((cdar . 1) (car . 1) (compose2 . 1)) () (cdar car compose2) (#%define cadar (compose2 car cdar))) (#%program ((cddr . 1) (car . 1) (compose2 . 1)) () (cddr car compose2) (#%define caddr (compose2 car cddr))) (#%program ((caar . 1) (cdr . 1) (compose2 . 1)) () (caar cdr compose2) (#%define cdaar (compose2 cdr caar))) (#%program ((cadr . 1) (cdr . 1) (compose2 . 1)) () (cadr cdr compose2) (#%define cdadr (compose2 cdr cadr))) (#%program ((cdar . 1) (cdr . 1) (compose2 . 1)) () (cdar cdr compose2) (#%define cddar (compose2 cdr cdar))) (#%program ((cddr . 1) (cdr . 1) (compose2 . 1)) () (cddr cdr compose2) (#%define cdddr (compose2 cdr cddr))) (#%program ((caaar . 1) (car . 1) (compose2 . 1)) () (caaar car compose2) (#%define caaaar (compose2 car caaar))) (#%program ((caadr . 1) (car . 1) (compose2 . 1)) () (caadr car compose2) (#%define caaadr (compose2 car caadr))) (#%program ((cadar . 1) (car . 1) (compose2 . 1)) () (cadar car compose2) (#%define caadar (compose2 car cadar))) (#%program ((caddr . 1) (car . 1) (compose2 . 1)) () (caddr car compose2) (#%define caaddr (compose2 car caddr))) (#%program ((cdaar . 1) (car . 1) (compose2 . 1)) () (cdaar car compose2) (#%define cadaar (compose2 car cdaar))) (#%program ((cdadr . 1) (car . 1) (compose2 . 1)) () (cdadr car compose2) (#%define cadadr (compose2 car cdadr))) (#%program ((cddar . 1) (car . 1) (compose2 . 1)) () (cddar car compose2) (#%define caddar (compose2 car cddar))) (#%program ((cdddr . 1) (car . 1) (compose2 . 1)) () (cdddr car compose2) (#%define cadddr (compose2 car cdddr))) (#%program ((caaar . 1) (cdr . 1) (compose2 . 1)) () (caaar cdr compose2) (#%define cdaaar (compose2 cdr caaar))) (#%program ((caadr . 1) (cdr . 1) (compose2 . 1)) () (caadr cdr compose2) (#%define cdaadr (compose2 cdr caadr))) (#%program ((cadar . 1) (cdr . 1) (compose2 . 1)) () (cadar cdr compose2) (#%define cdadar (compose2 cdr cadar))) (#%program ((caddr . 1) (cdr . 1) (compose2 . 1)) () (caddr cdr compose2) (#%define cdaddr (compose2 cdr caddr))) (#%program ((cdaar . 1) (cdr . 1) (compose2 . 1)) () (cdaar cdr compose2) (#%define cddaar (compose2 cdr cdaar))) (#%program ((cdadr . 1) (cdr . 1) (compose2 . 1)) () (cdadr cdr compose2) (#%define cddadr (compose2 cdr cdadr))) (#%program ((cddar . 1) (cdr . 1) (compose2 . 1)) () (cddar cdr compose2) (#%define cdddar (compose2 cdr cddar))) (#%program ((cdddr . 1) (cdr . 1) (compose2 . 1)) () (cdddr cdr compose2) (#%define cddddr (compose2 cdr cdddr))) (#%program ((cdr . 1) (append2 . 1) (car . 1) (cons . 1) (|%%_f7em4Nees_ls2| . 2) (|%%_f7Up6kees_ls1| . 3) (null? . 1)) () (cons car cdr append2 null?) (#%define append2 (#%lambda #t (|%%_f7Up6kees_ls1| |%%_f7em4Nees_ls2|) () (#%if (null? |%%_f7Up6kees_ls1|) |%%_f7em4Nees_ls2| (cons (car |%%_f7Up6kees_ls1|) (append2 (cdr |%%_f7Up6kees_ls1|) |%%_f7em4Nees_ls2|)))))) (#%program ((append2 . 1)) () (append2) (#%define append append2)) (#%program ((|%%_f7We0Hfes_base-case| . 1) (|%%_f7C7YAges_args| . 3) (cdr . 2) (car . 2) (|%%_f7Ai2efes_proc| . 1) (%%_f7gb-7ges_helper . 2) (|%%_f7Y3W1hes_acc| . 2) (|%%_f7i0Uuhes_argls| . 3) (null? . 2)) ((%%_f7gb-7ges_helper . 1)) (null? cdr car) (#%define _make-left-pairwise-nary (#%lambda #t (|%%_f7Ai2efes_proc| |%%_f7We0Hfes_base-case|) () (#%letrec #t ((%%_f7gb-7ges_helper (#%lambda #t (|%%_f7Y3W1hes_acc| |%%_f7i0Uuhes_argls|) (%%_f7gb-7ges_helper |%%_f7Ai2efes_proc|) (#%if (null? |%%_f7i0Uuhes_argls|) |%%_f7Y3W1hes_acc| (%%_f7gb-7ges_helper (|%%_f7Ai2efes_proc| |%%_f7Y3W1hes_acc| (car |%%_f7i0Uuhes_argls|)) (cdr |%%_f7i0Uuhes_argls|)))))) (|%%_f7We0Hfes_base-case| |%%_f7Ai2efes_proc|) (#%lambda #t |%%_f7C7YAges_args| (%%_f7gb-7ges_helper |%%_f7We0Hfes_base-case|) (#%if (null? |%%_f7C7YAges_args|) |%%_f7We0Hfes_base-case| (%%_f7gb-7ges_helper (car |%%_f7C7YAges_args|) (cdr |%%_f7C7YAges_args|)))))))) (#%program ((length . 1) (make-string . 1) (|%%_f7-UPoies_l| . 2) (+ . 1) (cdr . 1) (|%%_f7EYRXhes_l2s| . 2) (car . 1) (|%%_f70KJLjes_n| . 2) (string-set! . 1) (|%%_f7GNLijes_s| . 3) (|%%_f7kRNRies_l| . 3) (null? . 1)) ((|%%_f7EYRXhes_l2s| . 1)) (make-string length car string-set! + cdr null?) (#%define list->string (#%letrec #t ((|%%_f7EYRXhes_l2s| (#%lambda #t (|%%_f7kRNRies_l| |%%_f7GNLijes_s| |%%_f70KJLjes_n|) (|%%_f7EYRXhes_l2s|) (#%if (null? |%%_f7kRNRies_l|) |%%_f7GNLijes_s| (#%begin (string-set! |%%_f7GNLijes_s| |%%_f70KJLjes_n| (car |%%_f7kRNRies_l|)) (|%%_f7EYRXhes_l2s| (cdr |%%_f7kRNRies_l|) |%%_f7GNLijes_s| (+ |%%_f70KJLjes_n| 1))))))) () (#%lambda #t (|%%_f7-UPoies_l|) (|%%_f7EYRXhes_l2s|) (|%%_f7EYRXhes_l2s| |%%_f7-UPoies_l| (make-string (length |%%_f7-UPoies_l|)) 0))))) (#%program ((string-length . 1) (|%%_f7ICFFkes_s| . 2) (- . 2) (string-ref . 1) (cons . 1) (|%%_f72zD6les_s| . 2) (|%%_f7mGHckes_s2l| . 2) (|%%_f7ovBzles_h| . 2) (|%%_f7Krz0mes_n| . 3) (< . 1)) ((|%%_f7mGHckes_s2l| . 1)) (string-length string-ref cons - <) (#%define string->list (#%letrec #t ((|%%_f7mGHckes_s2l| (#%lambda #t (|%%_f72zD6les_s| |%%_f7ovBzles_h| |%%_f7Krz0mes_n|) (|%%_f7mGHckes_s2l|) (#%if (< |%%_f7Krz0mes_n| 0) |%%_f7ovBzles_h| (|%%_f7mGHckes_s2l| |%%_f72zD6les_s| (cons (string-ref |%%_f72zD6les_s| |%%_f7Krz0mes_n|) |%%_f7ovBzles_h|) (- |%%_f7Krz0mes_n| 1)))))) () (#%lambda #t (|%%_f7ICFFkes_s|) (|%%_f7mGHckes_s2l|) (|%%_f7mGHckes_s2l| |%%_f7ICFFkes_s| () (- (string-length |%%_f7ICFFkes_s|) 1)))))) (#%program ((%%_f74oxtmes_elems . 1) (list->vector . 1)) () (list->vector) (#%define vector (#%lambda #t %%_f74oxtmes_elems () (list->vector %%_f74oxtmes_elems)))) (#%program ((|%%_f7qkvWmes_elems| . 1) (list->string . 1)) () (list->string) (#%define string (#%lambda #t |%%_f7qkvWmes_elems| () (list->string |%%_f7qkvWmes_elems|)))) (#%program ((_make-parameter . 1)) () (_make-parameter) (#%define current-url (_make-parameter "file:."))) (#%program ((car . 1) (string-length . 1) (string-append . 1) (%%_f7s9phoes_l . 1) (- . 1) (|%%_f76drQnes_v| . 4) (string-ref . 1) (eqv? . 1) (current-url . 3) (normalize-url . 2) (|%%_f7Mgtnnes_rest| . 2) (null? . 1)) () (string-length string-ref - eqv? string-append car normalize-url current-url null?) (#%define current-directory (#%lambda #t |%%_f7Mgtnnes_rest| () (#%if (null? |%%_f7Mgtnnes_rest|) (normalize-url (current-url) ".") (current-url (normalize-url (current-url) ((#%lambda #t (|%%_f76drQnes_v|) () ((#%lambda #t (%%_f7s9phoes_l) (|%%_f76drQnes_v|) (#%if (eqv? (string-ref |%%_f76drQnes_v| (- %%_f7s9phoes_l 1)) #\/) |%%_f76drQnes_v| (string-append |%%_f76drQnes_v| "/"))) (string-length |%%_f76drQnes_v|))) (car |%%_f7Mgtnnes_rest|)))))))) (#%program ((void . 1)) () (void) (#%define file-handler (void))) (#%program ((void . 1)) () (void) (#%define add-file-handler (void))) (#%program ((load . 1) (|%%_f7aTeyqes_extension| . 1) (string-downcase . 1) (string->symbol . 1) (|%%_f7QWg5qes__load| . 1) (cdr . 1) (|%%_f7wPc_qes_t| . 2) (file-handler . 1) (|%%_f7u-iEpes_thunk| . 1) (cons . 2) (|%%_f7O5nKoes_*file-handlers*| . 4) (%%_f782lbpes_extension . 2) (assq . 2) (not . 1) (add-file-handler . 1)) ((file-handler . 1) (|%%_f7O5nKoes_*file-handlers*| . 1) (add-file-handler . 1)) (cdr string->symbol string-downcase load file-handler cons not assq add-file-handler) ((#%lambda #t (|%%_f7O5nKoes_*file-handlers*|) () (#%begin (#%set! add-file-handler (#%lambda #t (%%_f782lbpes_extension |%%_f7u-iEpes_thunk|) (|%%_f7O5nKoes_*file-handlers*|) (#%if (not (assq %%_f782lbpes_extension |%%_f7O5nKoes_*file-handlers*|)) (#%set! |%%_f7O5nKoes_*file-handlers*| (cons (cons %%_f782lbpes_extension |%%_f7u-iEpes_thunk|) |%%_f7O5nKoes_*file-handlers*|)) #!void))) (#%set! file-handler ((#%lambda #t (|%%_f7QWg5qes__load|) (|%%_f7O5nKoes_*file-handlers*|) (#%lambda #t (|%%_f7aTeyqes_extension|) (|%%_f7QWg5qes__load| |%%_f7O5nKoes_*file-handlers*|) ((#%lambda #t (|%%_f7wPc_qes_t|) (|%%_f7QWg5qes__load|) (#%if |%%_f7wPc_qes_t| (cdr |%%_f7wPc_qes_t|) |%%_f7QWg5qes__load|)) (assq (string->symbol (string-downcase |%%_f7aTeyqes_extension|)) |%%_f7O5nKoes_*file-handlers*|)))) load)))) ())) (#%program ((|%%_f7cI8Vres_rest| . 1) (|%%_f7yE6mses_file| . 1) (current-url . 1) (normalize-url . 1) (|%%_f7SLasres_proc| . 1) (apply . 1)) () (apply current-url normalize-url) (#%define make-io-proc (#%lambda #t (|%%_f7SLasres_proc|) () (#%lambda #t (|%%_f7yE6mses_file| . |%%_f7cI8Vres_rest|) (|%%_f7SLasres_proc|) (apply |%%_f7SLasres_proc| (normalize-url (current-url) |%%_f7yE6mses_file|) |%%_f7cI8Vres_rest|))))) (#%program ((|%%_f7ibSZves_url| . 1) (string->list . 1) (reverse! . 1) (cons . 1) (cdr . 1) (|%%_f7E7Qqwes_loop| . 2) (|%%_f7k0Mkxes_acc| . 2) (list->string . 1) (car . 2) (equal? . 1) (|%%_f7-3OTwes_x| . 4) (null? . 1) (void . 1) (|%%_f7UA4Pses_file-extension| . 1) (|%%_f7YeUwves_fe| . 2) (file-handler . 1) (|%%_f7gmYCues_e| . 1) (|%%_f7Wp-9ues_m| . 1) (|%%_f7CiW3ves_fk| . 1) (call-with-failure-continuation . 1) (with-failure-continuation . 1) (%%_f7ex2gtes_file . 1) (|%%_f7At0Jtes_previous-url| . 3) (normalize-url . 1) (current-url . 6) (load . 1) (open-output-file . 2) (open-source-input-file . 2) (make-io-proc . 3) (open-input-file . 2)) ((|%%_f7E7Qqwes_loop| . 1) (load . 1) (open-output-file . 1) (open-source-input-file . 1) (open-input-file . 1)) (open-input-file open-input-file make-io-proc open-source-input-file open-source-input-file open-output-file open-output-file load normalize-url current-url file-handler call-with-failure-continuation with-failure-continuation void reverse! string->list null? cdr cons list->string equal? car) ((#%lambda #t (|%%_f7UA4Pses_file-extension|) () (#%begin (#%set! open-input-file (make-io-proc open-input-file)) (#%set! open-source-input-file (make-io-proc open-source-input-file)) (#%set! open-output-file (make-io-proc open-output-file)) (#%set! load (#%lambda #t (%%_f7ex2gtes_file) (|%%_f7UA4Pses_file-extension|) (#%begin ((#%lambda #t (|%%_f7At0Jtes_previous-url|) (%%_f7ex2gtes_file |%%_f7UA4Pses_file-extension|) (#%begin (current-url (normalize-url |%%_f7At0Jtes_previous-url| %%_f7ex2gtes_file)) (with-failure-continuation (#%lambda #t (|%%_f7Wp-9ues_m| |%%_f7gmYCues_e|) (|%%_f7At0Jtes_previous-url|) (#%begin (current-url |%%_f7At0Jtes_previous-url|) (call-with-failure-continuation (#%lambda #t (|%%_f7CiW3ves_fk|) (|%%_f7gmYCues_e| |%%_f7Wp-9ues_m|) (|%%_f7CiW3ves_fk| |%%_f7Wp-9ues_m| |%%_f7gmYCues_e|))))) (#%lambda #t () (|%%_f7UA4Pses_file-extension|) ((#%lambda #t (|%%_f7YeUwves_fe|) () ((file-handler (#%if |%%_f7YeUwves_fe| |%%_f7YeUwves_fe| "scm")) (current-url))) (|%%_f7UA4Pses_file-extension| (current-url))))) (current-url |%%_f7At0Jtes_previous-url|))) (current-url)) (void)))))) (#%lambda #t (|%%_f7ibSZves_url|) () ((#%letrec #t ((|%%_f7E7Qqwes_loop| (#%lambda #t (|%%_f7-3OTwes_x| |%%_f7k0Mkxes_acc|) (|%%_f7E7Qqwes_loop|) (#%if (null? |%%_f7-3OTwes_x|) #f (#%if (equal? (car |%%_f7-3OTwes_x|) #\.) (list->string |%%_f7k0Mkxes_acc|) (|%%_f7E7Qqwes_loop| (cdr |%%_f7-3OTwes_x|) (cons (car |%%_f7-3OTwes_x|) |%%_f7k0Mkxes_acc|))))))) () |%%_f7E7Qqwes_loop|) (reverse! (string->list |%%_f7ibSZves_url|)) ())))) (#%program ((|%%_f7GYJNxes_str| . 1) (load-native-library . 1) (native-library-binding-names . 1) (|%%_f7mRFHyes_binding-names| . 1) (|%%_f70VHeyes_nl| . 2) (native-library-binding . 1) (|%%_f7IND8zes_name| . 2) (putprop . 1) (for-each . 1)) () (load-native-library native-library-binding putprop for-each native-library-binding-names) (#%define load-module (#%lambda #t (|%%_f7GYJNxes_str|) () ((#%lambda #t (|%%_f70VHeyes_nl|) () ((#%lambda #t (|%%_f7mRFHyes_binding-names|) (|%%_f70VHeyes_nl|) (for-each (#%lambda #t (|%%_f7IND8zes_name|) (|%%_f70VHeyes_nl|) (putprop |%%_f7IND8zes_name| (native-library-binding |%%_f70VHeyes_nl| |%%_f7IND8zes_name|))) |%%_f7mRFHyes_binding-names|)) (native-library-binding-names |%%_f70VHeyes_nl|))) (load-native-library |%%_f7GYJNxes_str|))))) (#%program ((append2 . 1) (_make-left-pairwise-nary . 1)) () (append2 _make-left-pairwise-nary) (#%define append (_make-left-pairwise-nary append2 ()))) (#%program ((|%%_f72KBBzes_x| . 2) (null? . 2) (|%%_f74zvYAes_lag| . 1) (cdr . 3) (|%%_f7oGz2Aes_lp| . 2) (|%%_f76opjCes_lag| . 2) (|%%_f7MrrSBes_x| . 2) (eq? . 1) (not . 1) (|%%_f7qvtpBes_x| . 3) (|%%_f7KCxvAes_x| . 3) (pair? . 2)) ((|%%_f7oGz2Aes_lp| . 1)) (pair? cdr eq? not null?) (#%define proper-list? (#%lambda #t (|%%_f72KBBzes_x|) () ((#%letrec #t ((|%%_f7oGz2Aes_lp| (#%lambda #t (|%%_f7KCxvAes_x| |%%_f74zvYAes_lag|) (|%%_f7oGz2Aes_lp|) (#%if (pair? |%%_f7KCxvAes_x|) ((#%lambda #t (|%%_f7qvtpBes_x|) (|%%_f74zvYAes_lag| |%%_f7oGz2Aes_lp|) (#%if (pair? |%%_f7qvtpBes_x|) ((#%lambda #t (|%%_f7MrrSBes_x| |%%_f76opjCes_lag|) (|%%_f7oGz2Aes_lp|) (#%if (not (eq? |%%_f7MrrSBes_x| |%%_f76opjCes_lag|)) (|%%_f7oGz2Aes_lp| |%%_f7MrrSBes_x| |%%_f76opjCes_lag|) #f)) (cdr |%%_f7qvtpBes_x|) (cdr |%%_f74zvYAes_lag|)) (null? |%%_f7qvtpBes_x|))) (cdr |%%_f7KCxvAes_x|)) (null? |%%_f7KCxvAes_x|))))) () |%%_f7oGz2Aes_lp|) |%%_f72KBBzes_x| |%%_f72KBBzes_x|)))) (#%program ((proper-list? . 1)) () (proper-list?) (#%define list? proper-list?)) (#%program ((|%%_f7sknMCes_general-expt| . 1) (|%%_f78djGDes_integer-expt| . 1) (denominator . 1) (numerator . 1) (|%%_f7OgldDes_rational-expt| . 1) (integer? . 2) (not . 1) (rational? . 1) (|%%_f7u9h7Ees_base| . 9) (|%%_f7Q5fAEes_exponent| . 8) (|%%_f7CtUyJes_squaring| . 3) (odd? . 1) (quotient . 1) (|%%_f7AE-bIes_loop| . 2) (|%%_f7gxW5Jes_result| . 3) (|%%_f7WAYEIes_rest| . 3) (zero? . 3) (abs . 2) (ashl . 2) (|%%_f7eI0LHes_exponent| . 7) (negative? . 3) (= . 1) (|%%_f7UL2iHes_base| . 4) (exact? . 5) (|%%_f7cT6oGes_base-denominator| . 1) (|%%_f7yP4RGes_exponent| . 2) (|%%_f7SW8XFes_base-numerator| . 1) (expt . 2) (/ . 3) (|%%_f7a2d1Fes_base| . 1) (log . 1) (|%%_f7w-auFes_exponent| . 1) (* . 3) (exp . 1)) ((|%%_f7AE-bIes_loop| . 1) (|%%_f78djGDes_integer-expt| . 1) (|%%_f7OgldDes_rational-expt| . 1) (|%%_f7sknMCes_general-expt| . 1)) (numerator denominator not integer? rational? quotient odd? zero? negative? ashl abs exact? = expt / * log exp) (#%define expt (#%letrec #t ((|%%_f7sknMCes_general-expt| (#%lambda #t (|%%_f7a2d1Fes_base| |%%_f7w-auFes_exponent|) () (exp (* |%%_f7w-auFes_exponent| (log |%%_f7a2d1Fes_base|))))) (|%%_f7OgldDes_rational-expt| (#%lambda #t (|%%_f7SW8XFes_base-numerator| |%%_f7cT6oGes_base-denominator| |%%_f7yP4RGes_exponent|) () (/ (expt |%%_f7SW8XFes_base-numerator| |%%_f7yP4RGes_exponent|) (expt |%%_f7cT6oGes_base-denominator| |%%_f7yP4RGes_exponent|)))) (|%%_f78djGDes_integer-expt| (#%lambda #t (|%%_f7UL2iHes_base| |%%_f7eI0LHes_exponent|) () (#%if (#%if (exact? |%%_f7UL2iHes_base|) (= |%%_f7UL2iHes_base| 2) #f) (#%if (negative? |%%_f7eI0LHes_exponent|) (/ (ashl 1 (abs |%%_f7eI0LHes_exponent|))) (ashl 1 |%%_f7eI0LHes_exponent|)) ((#%letrec #t ((|%%_f7AE-bIes_loop| (#%lambda #t (|%%_f7WAYEIes_rest| |%%_f7gxW5Jes_result| |%%_f7CtUyJes_squaring|) (|%%_f7AE-bIes_loop|) (#%if (zero? |%%_f7WAYEIes_rest|) |%%_f7gxW5Jes_result| (|%%_f7AE-bIes_loop| (quotient |%%_f7WAYEIes_rest| 2) (#%if (odd? |%%_f7WAYEIes_rest|) (* |%%_f7gxW5Jes_result| |%%_f7CtUyJes_squaring|) |%%_f7gxW5Jes_result|) (* |%%_f7CtUyJes_squaring| |%%_f7CtUyJes_squaring|)))))) () |%%_f7AE-bIes_loop|) (#%if (negative? |%%_f7eI0LHes_exponent|) (abs |%%_f7eI0LHes_exponent|) |%%_f7eI0LHes_exponent|) 1 (#%if (negative? |%%_f7eI0LHes_exponent|) (/ |%%_f7UL2iHes_base|) |%%_f7UL2iHes_base|)))))) () (#%lambda #t (|%%_f7u9h7Ees_base| |%%_f7Q5fAEes_exponent|) (|%%_f78djGDes_integer-expt| |%%_f7OgldDes_rational-expt| |%%_f7sknMCes_general-expt|) (#%if (zero? |%%_f7Q5fAEes_exponent|) (#%if (exact? |%%_f7Q5fAEes_exponent|) 1 1.0) (#%if (zero? |%%_f7u9h7Ees_base|) (#%if (exact? |%%_f7Q5fAEes_exponent|) |%%_f7u9h7Ees_base| 0.0) (#%if (#%if (exact? |%%_f7u9h7Ees_base|) (#%if (rational? |%%_f7u9h7Ees_base|) (not (integer? |%%_f7u9h7Ees_base|)) #f) #f) (|%%_f7OgldDes_rational-expt| (numerator |%%_f7u9h7Ees_base|) (denominator |%%_f7u9h7Ees_base|) |%%_f7Q5fAEes_exponent|) (#%if (#%if (exact? |%%_f7Q5fAEes_exponent|) (integer? |%%_f7Q5fAEes_exponent|) #f) (|%%_f78djGDes_integer-expt| |%%_f7u9h7Ees_base| |%%_f7Q5fAEes_exponent|) (|%%_f7sknMCes_general-expt| |%%_f7u9h7Ees_base| |%%_f7Q5fAEes_exponent|))))))))) (#%program ((- . 1) (|%%_f7-eMmLes_tmp| . 2) (/ . 2) (modpow . 2) (|%%_f7kbKPLes_tmp| . 2) (* . 3) (even? . 1) (|%%_f7EiOVKes_n| . 6) (|%%_f7YpS_Jes_x| . 4) (modulo . 4) (|%%_f7imQsKes_y| . 4) (= . 1)) () (even? modpow / * - modulo =) (#%define modpow (#%lambda #t (|%%_f7YpS_Jes_x| |%%_f7imQsKes_y| |%%_f7EiOVKes_n|) () (#%if (= |%%_f7imQsKes_y| 1) (modulo |%%_f7YpS_Jes_x| |%%_f7EiOVKes_n|) (#%if (even? |%%_f7imQsKes_y|) ((#%lambda #t (|%%_f7kbKPLes_tmp|) (|%%_f7EiOVKes_n|) (modulo (* |%%_f7kbKPLes_tmp| |%%_f7kbKPLes_tmp|) |%%_f7EiOVKes_n|)) (modpow |%%_f7YpS_Jes_x| (/ |%%_f7imQsKes_y| 2) |%%_f7EiOVKes_n|)) ((#%lambda #t (|%%_f7-eMmLes_tmp|) (|%%_f7EiOVKes_n| |%%_f7YpS_Jes_x|) (modulo (* |%%_f7YpS_Jes_x| (modulo (* |%%_f7-eMmLes_tmp| |%%_f7-eMmLes_tmp|) |%%_f7EiOVKes_n|)) |%%_f7EiOVKes_n|)) (modpow |%%_f7YpS_Jes_x| (/ (- |%%_f7imQsKes_y| 1) 2) |%%_f7EiOVKes_n|))))))) (#%program ((round . 1) (= . 1) (real? . 1) (|%%_f7G7IgMes_n| . 4) (_integer? . 1)) () (real? round = _integer?) (#%define integer? (#%lambda #t (|%%_f7G7IgMes_n|) () (#%if (_integer? |%%_f7G7IgMes_n|) #t (#%if (real? |%%_f7G7IgMes_n|) (= (round |%%_f7G7IgMes_n|) |%%_f7G7IgMes_n|) #f))))) (#%program ((complex? . 1) (|%%_f704GJMes_oldcomp?| . 1) (not . 1) (|%%_f7m0EaNes_n| . 2) (number? . 1)) () (complex? number? not) (#%define real? ((#%lambda #t (|%%_f704GJMes_oldcomp?|) () (#%lambda #t (|%%_f7m0EaNes_n|) (|%%_f704GJMes_oldcomp?|) (#%if (number? |%%_f7m0EaNes_n|) (not (|%%_f704GJMes_oldcomp?| |%%_f7m0EaNes_n|)) #f))) complex?))) (#%program ((real? . 1)) () (real?) (#%define rational? real?)) (#%program ((number? . 1)) () (number?) (#%define complex? number?)) (#%program ((- . 1) (< . 1) (imag-part . 1) (real-part . 1) (|%%_f7oRxxOes_b| . 2) (|%%_f72Vz4Oes_a| . 2) (* . 2) (+ . 1) (sqrt . 1) (|%%_f7IYBDNes_num| . 6) (real? . 1) (not . 1)) () (< - + * sqrt real-part imag-part not real?) (#%define abs (#%lambda #t (|%%_f7IYBDNes_num|) () (#%if (not (real? |%%_f7IYBDNes_num|)) ((#%lambda #t (|%%_f72Vz4Oes_a| |%%_f7oRxxOes_b|) () (sqrt (+ (* |%%_f72Vz4Oes_a| |%%_f72Vz4Oes_a|) (* |%%_f7oRxxOes_b| |%%_f7oRxxOes_b|)))) (real-part |%%_f7IYBDNes_num|) (imag-part |%%_f7IYBDNes_num|)) (#%if (< |%%_f7IYBDNes_num| 0) (- |%%_f7IYBDNes_num|) |%%_f7IYBDNes_num|))))) (#%program ((void . 1)) () (void) (#%define min (void))) (#%program ((void . 1)) () (void) (#%define max (void))) (#%program ((> . 1) (|%%_f76znOQes_x1| . 3) (|%%_f7MCplQes_args| . 2) (max . 1) (< . 1) (|%%_f7qGrUPes_x1| . 3) (|%%_f74KtrPes_args| . 2) (min . 1) (inexact? . 3) (cdr . 2) (|%%_f7KNv-Oes__min_max| . 4) (car . 3) (|%%_f7svlfRes_proc| . 3) (exact->inexact . 1) (|%%_f7OrjIRes_mv| . 5) (exact? . 1) (|%%_f7ukfCSes_inexact| . 3) (|%%_f78oh9Ses_args| . 6) (null? . 3)) ((max . 1) (min . 1) (|%%_f7KNv-Oes__min_max| . 1)) (min < max > car inexact? cdr exact? exact->inexact null?) (#%letrec #t ((|%%_f7KNv-Oes__min_max| (#%lambda #t (|%%_f7svlfRes_proc| |%%_f7OrjIRes_mv| |%%_f78oh9Ses_args| |%%_f7ukfCSes_inexact|) (|%%_f7KNv-Oes__min_max|) (#%if (null? |%%_f78oh9Ses_args|) (#%if (#%if |%%_f7ukfCSes_inexact| (exact? |%%_f7OrjIRes_mv|) #f) (exact->inexact |%%_f7OrjIRes_mv|) |%%_f7OrjIRes_mv|) (#%if (|%%_f7svlfRes_proc| (car |%%_f78oh9Ses_args|) |%%_f7OrjIRes_mv|) (|%%_f7KNv-Oes__min_max| |%%_f7svlfRes_proc| (car |%%_f78oh9Ses_args|) (cdr |%%_f78oh9Ses_args|) (#%if |%%_f7ukfCSes_inexact| #t (inexact? (car |%%_f78oh9Ses_args|)))) (|%%_f7KNv-Oes__min_max| |%%_f7svlfRes_proc| |%%_f7OrjIRes_mv| (cdr |%%_f78oh9Ses_args|) |%%_f7ukfCSes_inexact|)))))) () (#%begin (#%set! min (#%lambda #t (|%%_f7qGrUPes_x1| . |%%_f74KtrPes_args|) (|%%_f7KNv-Oes__min_max|) (#%if (null? |%%_f74KtrPes_args|) |%%_f7qGrUPes_x1| (|%%_f7KNv-Oes__min_max| < |%%_f7qGrUPes_x1| |%%_f74KtrPes_args| (inexact? |%%_f7qGrUPes_x1|))))) (#%set! max (#%lambda #t (|%%_f76znOQes_x1| . |%%_f7MCplQes_args|) (|%%_f7KNv-Oes__min_max|) (#%if (null? |%%_f7MCplQes_args|) |%%_f76znOQes_x1| (|%%_f7KNv-Oes__min_max| > |%%_f76znOQes_x1| |%%_f7MCplQes_args| (inexact? |%%_f76znOQes_x1|)))))))) (#%program ((|%%_f7Qgd3Tes_n| . 1) (< . 1)) () (<) (#%define negative? (#%lambda #t (|%%_f7Qgd3Tes_n|) () (< |%%_f7Qgd3Tes_n| 0)))) (#%program ((|%%_f7adbwTes_n| . 1) (> . 1)) () (>) (#%define positive? (#%lambda #t (|%%_f7adbwTes_n|) () (> |%%_f7adbwTes_n| 0)))) (#%program ((|%%_f7w99ZTes_n| . 1) (modulo . 1) (= . 1)) () (modulo =) (#%define even? (#%lambda #t (|%%_f7w99ZTes_n|) () (= 0 (modulo |%%_f7w99ZTes_n| 2))))) (#%program ((|%%_f7S57qUes_n| . 1) (even? . 1) (not . 1)) () (even? not) (#%define odd? (#%lambda #t (|%%_f7S57qUes_n|) () (not (even? |%%_f7S57qUes_n|))))) (#%program ((|%%_f7c25TUes_n| . 1) (= . 1)) () (=) (#%define zero? (#%lambda #t (|%%_f7c25TUes_n|) () (= |%%_f7c25TUes_n| 0)))) (#%program ((|%%_f7y-2kVes_n| . 1) (+ . 1)) () (+) (#%define add1 (#%lambda #t (|%%_f7y-2kVes_n|) () (+ |%%_f7y-2kVes_n| 1)))) (#%program ((|%%_f7UW0NVes_n| . 1) (- . 1)) () (-) (#%define sub1 (#%lambda #t (|%%_f7UW0NVes_n|) () (- |%%_f7UW0NVes_n| 1)))) (#%program ((void . 1)) () (void) (#%define >= (void))) (#%program ((void . 1)) () (void) (#%define <= (void))) (#%program ((|%%_f7I7A60fs_y| . 1) (|%%_f7mbCF_es_x| . 1) (|%%_f7kmIi-es_args| . 1) (|%%_f7GiGL-es_loop| . 2) (cadr . 1) (car . 1) (|%%_f7ixOXYes_comparator| . 1) (|%%_f7EtMoZes_chainer| . 1) (cdr . 2) (|%%_f7-pKRZes_endstate| . 2) (|%%_f70fEc_es_x| . 5) (null? . 2) (|%%_f7YAQuYes_b| . 2) (|%%_f7CES1Yes_a| . 2) (> . 1) (>= . 1) (|%%_f7APYGWes__and2| . 2) (= . 2) (|%%_f7gIUAXes_b| . 2) (|%%_f7WLW7Xes_a| . 2) (< . 1) (|%%_f7eT-dWes__comp_help| . 2) (<= . 1)) ((|%%_f7GiGL-es_loop| . 1) (>= . 1) (<= . 1)) (null? cadr car cdr <= = < >= >) ((#%lambda #t (|%%_f7eT-dWes__comp_help| |%%_f7APYGWes__and2|) () (#%begin (#%set! <= (|%%_f7eT-dWes__comp_help| (#%lambda #t (|%%_f7WLW7Xes_a| |%%_f7gIUAXes_b|) () (#%if (< |%%_f7WLW7Xes_a| |%%_f7gIUAXes_b|) #t (= |%%_f7WLW7Xes_a| |%%_f7gIUAXes_b|))) |%%_f7APYGWes__and2| #t)) (#%set! >= (|%%_f7eT-dWes__comp_help| (#%lambda #t (|%%_f7CES1Yes_a| |%%_f7YAQuYes_b|) () (#%if (> |%%_f7CES1Yes_a| |%%_f7YAQuYes_b|) #t (= |%%_f7CES1Yes_a| |%%_f7YAQuYes_b|))) |%%_f7APYGWes__and2| #t)))) (#%lambda #t (|%%_f7ixOXYes_comparator| |%%_f7EtMoZes_chainer| |%%_f7-pKRZes_endstate|) () (#%lambda #t |%%_f7kmIi-es_args| (|%%_f7-pKRZes_endstate| |%%_f7EtMoZes_chainer| |%%_f7ixOXYes_comparator|) ((#%letrec #t ((|%%_f7GiGL-es_loop| (#%lambda #t (|%%_f70fEc_es_x|) (|%%_f7GiGL-es_loop| |%%_f7-pKRZes_endstate| |%%_f7EtMoZes_chainer| |%%_f7ixOXYes_comparator|) (#%if (null? |%%_f70fEc_es_x|) |%%_f7-pKRZes_endstate| (#%if (null? (cdr |%%_f70fEc_es_x|)) |%%_f7-pKRZes_endstate| (|%%_f7EtMoZes_chainer| (|%%_f7ixOXYes_comparator| (car |%%_f70fEc_es_x|) (cadr |%%_f70fEc_es_x|)) (|%%_f7GiGL-es_loop| (cdr |%%_f70fEc_es_x|)))))))) (|%%_f7-pKRZes_endstate| |%%_f7EtMoZes_chainer| |%%_f7ixOXYes_comparator|) |%%_f7GiGL-es_loop|) |%%_f7kmIi-es_args|))) (#%lambda #t (|%%_f7mbCF_es_x| |%%_f7I7A60fs_y|) () (#%if |%%_f7mbCF_es_x| |%%_f7I7A60fs_y| #f)))) (#%program ((|%%_f7KYtt1fs_chainer| . 1) (apply . 1) (%%_f7o0w01fs_comparator . 1) (cadr . 2) (car . 2) (= . 1) (cdr . 2) (|%%_f74VrW1fs_args| . 7) (null? . 2) (< . 1) (<= . 2) (> . 1) (%%_f724yz0fs__?= . 2) (>= . 2)) ((<= . 1) (>= . 1)) (< <= <= > >= >= null? = car cadr apply cdr) ((#%lambda #t (%%_f724yz0fs__?=) () (#%begin (#%set! >= (%%_f724yz0fs__?= > >=)) (#%set! <= (%%_f724yz0fs__?= < <=)))) (#%lambda #t (%%_f7o0w01fs_comparator |%%_f7KYtt1fs_chainer|) () (#%lambda #t |%%_f74VrW1fs_args| (|%%_f7KYtt1fs_chainer| %%_f7o0w01fs_comparator) (#%if (null? |%%_f74VrW1fs_args|) #t (#%if (null? (cdr |%%_f74VrW1fs_args|)) #t (#%if (#%if (= (car |%%_f74VrW1fs_args|) (cadr |%%_f74VrW1fs_args|)) #t (%%_f7o0w01fs_comparator (car |%%_f74VrW1fs_args|) (cadr |%%_f74VrW1fs_args|))) (apply |%%_f7KYtt1fs_chainer| (cdr |%%_f74VrW1fs_args|)) #f))))))) (#%program ((gcd . 1) (apply . 1) (_gcd . 1) (car . 2) (cdr . 2) (|%%_f7MNnQ2fs_args| . 5) (null? . 2)) () (cdr car apply gcd _gcd null?) (#%define gcd (#%lambda #t |%%_f7MNnQ2fs_args| () (#%if (null? |%%_f7MNnQ2fs_args|) 0 (#%if (null? (cdr |%%_f7MNnQ2fs_args|)) (car |%%_f7MNnQ2fs_args|) (_gcd (car |%%_f7MNnQ2fs_args|) (apply gcd (cdr |%%_f7MNnQ2fs_args|)))))))) (#%program ((lcm . 1) (apply . 1) (_lcm . 1) (car . 2) (cdr . 2) (|%%_f76Klh3fs_args| . 5) (null? . 2)) () (cdr car apply lcm _lcm null?) (#%define lcm (#%lambda #t |%%_f76Klh3fs_args| () (#%if (null? |%%_f76Klh3fs_args|) 1 (#%if (null? (cdr |%%_f76Klh3fs_args|)) (car |%%_f76Klh3fs_args|) (_lcm (car |%%_f76Klh3fs_args|) (apply lcm (cdr |%%_f76Klh3fs_args|)))))))) (#%program ((|%%_f7sGjK3fs_x| . 1) (remainder . 1) (+ . 1) (|%%_f78zfE4fs_r| . 3) (positive? . 1) (|%%_f7OChb4fs_y| . 3) (negative? . 2)) () (remainder positive? negative? +) (#%define modulo (#%lambda #t (|%%_f7sGjK3fs_x| |%%_f7OChb4fs_y|) () ((#%lambda #t (|%%_f78zfE4fs_r|) (|%%_f7OChb4fs_y|) (#%if ((#%if (negative? |%%_f7OChb4fs_y|) positive? negative?) |%%_f78zfE4fs_r|) (+ |%%_f78zfE4fs_r| |%%_f7OChb4fs_y|) |%%_f78zfE4fs_r|)) (remainder |%%_f7sGjK3fs_x| |%%_f7OChb4fs_y|))))) (#%program ((- . 1) (char->integer . 4) (%%_f7wk7s6fs_c . 2) (%%_f7ao9_5fs_lc-offset . 1) (+ . 1) (integer->char . 1) (|%%_f7Qrby5fs_z| . 1) (<= . 1) (%%_f7uvd55fs_a . 2) (|%%_f7Sg5V6fs_cv| . 3) (>= . 1)) () (integer->char + >= <= char->integer -) (#%define char-downcase ((#%lambda #t (%%_f7uvd55fs_a) () ((#%lambda #t (|%%_f7Qrby5fs_z|) (%%_f7uvd55fs_a) ((#%lambda #t (%%_f7ao9_5fs_lc-offset) (|%%_f7Qrby5fs_z| %%_f7uvd55fs_a) (#%lambda #t (%%_f7wk7s6fs_c) (%%_f7ao9_5fs_lc-offset |%%_f7Qrby5fs_z| %%_f7uvd55fs_a) ((#%lambda #t (|%%_f7Sg5V6fs_cv|) (%%_f7wk7s6fs_c %%_f7ao9_5fs_lc-offset |%%_f7Qrby5fs_z| %%_f7uvd55fs_a) (#%if (#%if (>= |%%_f7Sg5V6fs_cv| %%_f7uvd55fs_a) (<= |%%_f7Sg5V6fs_cv| |%%_f7Qrby5fs_z|) #f) (integer->char (+ |%%_f7Sg5V6fs_cv| %%_f7ao9_5fs_lc-offset)) %%_f7wk7s6fs_c)) (char->integer %%_f7wk7s6fs_c)))) (- (char->integer #\a) %%_f7uvd55fs_a))) (char->integer #\Z))) (char->integer #\A)))) (#%program ((char->integer . 4) (|%%_f7e2ZI8fs_c| . 2) (|%%_f7U5_f8fs_uc-offset| . 1) (- . 2) (integer->char . 1) (|%%_f7y91P7fs_z| . 1) (<= . 1) (%%_f7cd3m7fs_a . 2) (|%%_f7A-W99fs_cv| . 3) (>= . 1)) () (integer->char - >= <= char->integer) (#%define char-upcase ((#%lambda #t (%%_f7cd3m7fs_a) () ((#%lambda #t (|%%_f7y91P7fs_z|) (%%_f7cd3m7fs_a) ((#%lambda #t (|%%_f7U5_f8fs_uc-offset|) (|%%_f7y91P7fs_z| %%_f7cd3m7fs_a) (#%lambda #t (|%%_f7e2ZI8fs_c|) (|%%_f7U5_f8fs_uc-offset| |%%_f7y91P7fs_z| %%_f7cd3m7fs_a) ((#%lambda #t (|%%_f7A-W99fs_cv|) (|%%_f7e2ZI8fs_c| |%%_f7U5_f8fs_uc-offset| |%%_f7y91P7fs_z| %%_f7cd3m7fs_a) (#%if (#%if (>= |%%_f7A-W99fs_cv| %%_f7cd3m7fs_a) (<= |%%_f7A-W99fs_cv| |%%_f7y91P7fs_z|) #f) (integer->char (- |%%_f7A-W99fs_cv| |%%_f7U5_f8fs_uc-offset|)) |%%_f7e2ZI8fs_c|)) (char->integer |%%_f7e2ZI8fs_c|)))) (- %%_f7cd3m7fs_a (char->integer #\A)))) (char->integer #\z))) (char->integer #\a)))) (#%program ((|%%_f7WWUC9fs_args| . 1) (map . 1) (|%%_f7gTS3afs_c2| . 1) (|%%_f7CPQwafs_c1| . 1) (char->integer . 3) (> . 1) (apply . 1)) () (map char->integer > apply) (#%define char>? (#%lambda #t (|%%_f7CPQwafs_c1| |%%_f7gTS3afs_c2| . |%%_f7WWUC9fs_args|) () (apply > (char->integer |%%_f7CPQwafs_c1|) (char->integer |%%_f7gTS3afs_c2|) (map char->integer |%%_f7WWUC9fs_args|))))) (#%program ((|%%_f7YLOZafs_args| . 1) (map . 1) (|%%_f7iIMqbfs_c2| . 1) (|%%_f7EEKTbfs_c1| . 1) (char->integer . 3) (< . 1) (apply . 1)) () (map char->integer < apply) (#%define charinteger |%%_f7EEKTbfs_c1|) (char->integer |%%_f7iIMqbfs_c2|) (map char->integer |%%_f7YLOZafs_args|))))) (#%program ((char=? . 1) (|%%_f7kxGNcfs_c2| . 2) (|%%_f7-AIkcfs_c1| . 2) (char>? . 1)) () (char=? char>?) (#%define char>=? (#%lambda #t (|%%_f7-AIkcfs_c1| |%%_f7kxGNcfs_c2|) () (#%if (char>? |%%_f7-AIkcfs_c1| |%%_f7kxGNcfs_c2|) #t (char=? |%%_f7-AIkcfs_c1| |%%_f7kxGNcfs_c2|))))) (#%program ((char=? . 1) (|%%_f70qCHdfs_c2| . 2) (|%%_f7GtEedfs_c1| . 2) (char? . 1) (apply . 1)) () (map char-downcase char>? apply) (#%define char-ci>? (#%lambda #t (%%_f72fw2ffs_c1 |%%_f7IiyBefs_c2| . |%%_f7mmA8efs_args|) () (apply char>? (char-downcase %%_f72fw2ffs_c1) (char-downcase |%%_f7IiyBefs_c2|) (map char-downcase |%%_f7mmA8efs_args|))))) (#%program ((%%_f7obuvffs_args . 1) (map . 1) (|%%_f7K7sYffs_c2| . 1) (%%_f744qpgfs_c1 . 1) (char-downcase . 3) (char? . 1)) () (char-ci=? char-ci>?) (#%define char-ci>=? (#%lambda #t (|%%_f7sRhdifs_c1| |%%_f7ONfGifs_c2|) () (#%if (char-ci>? |%%_f7sRhdifs_c1| |%%_f7ONfGifs_c2|) #t (char-ci=? |%%_f7sRhdifs_c1| |%%_f7ONfGifs_c2|))))) (#%program ((char-ci=? . 1) (|%%_f7uGbAjfs_c2| . 2) (|%%_f78Kd7jfs_c1| . 2) (char-cilist . 2) (car . 2) (cdr . 2) (|%%_f7-LGPqfs_s? . 1) (%%_f72quxtfs_c2 . 2) (|%%_f7Itw4tfs_c1| . 2) (charlist car char? not null?) (#%define string? |%%_f7Itw4tfs_c1| %%_f72quxtfs_c2) #f (|%%_f7-LGPqfs_slist |%%_f7kIEgrfs_s1|) (string->list |%%_f7GECJrfs_s2|)))))) (#%program ((|%%_f74foUufs_s2| . 1) (|%%_f7Kiqrufs_s1| . 1) (string->list . 2) (car . 2) (cdr . 2) (%%_f7oms-tfs_s>? . 2) (char? . 1) (%%_f7qbmlvfs_s1 . 4) (not . 1) (|%%_f7M7kOvfs_s2| . 3) (null? . 3)) ((%%_f7oms-tfs_s>? . 1)) (string->list car char>? cdr char? (#%letrec #t ((%%_f7oms-tfs_s>? (#%lambda #t (%%_f7qbmlvfs_s1 |%%_f7M7kOvfs_s2|) (%%_f7oms-tfs_s>?) (#%if (null? |%%_f7M7kOvfs_s2|) (not (null? %%_f7qbmlvfs_s1)) (#%if (null? %%_f7qbmlvfs_s1) #f ((#%lambda #t (%%_f764ifwfs_c1 |%%_f7s0gIwfs_c2|) (|%%_f7M7kOvfs_s2| %%_f7qbmlvfs_s1 %%_f7oms-tfs_s>?) (#%if (char>? %%_f764ifwfs_c1 |%%_f7s0gIwfs_c2|) #t (#%if (char? (cdr %%_f7qbmlvfs_s1) (cdr |%%_f7M7kOvfs_s2|))))) (car %%_f7qbmlvfs_s1) (car |%%_f7M7kOvfs_s2|))))))) () (#%lambda #t (|%%_f7Kiqrufs_s1| |%%_f74foUufs_s2|) (%%_f7oms-tfs_s>?) (%%_f7oms-tfs_s>? (string->list |%%_f7Kiqrufs_s1|) (string->list |%%_f74foUufs_s2|)))))) (#%program ((string=? . 1) (|%%_f78VbCxfs_s2| . 2) (|%%_f7OYd9xfs_s1| . 2) (string? . 1)) () (string=? string>?) (#%define string>=? (#%lambda #t (|%%_f7uR93yfs_s1| |%%_f7QN7wyfs_s2|) () (#%if (string>? |%%_f7uR93yfs_s1| |%%_f7QN7wyfs_s2|) #t (string=? |%%_f7uR93yfs_s1| |%%_f7QN7wyfs_s2|))))) (#%program ((|%%_f7wG3qzfs_s2| . 1) (|%%_f7aK5Zyfs_s1| . 1) (string-downcase . 2) (string=? . 1)) () (string-downcase string=?) (#%define string-ci=? (#%lambda #t (|%%_f7aK5Zyfs_s1| |%%_f7wG3qzfs_s2|) () (string=? (string-downcase |%%_f7aK5Zyfs_s1|) (string-downcase |%%_f7wG3qzfs_s2|))))) (#%program ((|%%_f7cz_jAfs_s2| . 1) (|%%_f7SC1Tzfs_s1| . 1) (string-downcase . 2) (string? . 1)) () (string-downcase string>?) (#%define string-ci>? (#%lambda #t (|%%_f7yvZMAfs_s1| |%%_f7UrXdBfs_s2|) () (string>? (string-downcase |%%_f7yvZMAfs_s1|) (string-downcase |%%_f7UrXdBfs_s2|))))) (#%program ((|%%_f7AkT7Cfs_s2| . 1) (|%%_f7eoVGBfs_s1| . 1) (string-downcase . 2) (string>=? . 1)) () (string-downcase string>=?) (#%define string-ci>=? (#%lambda #t (|%%_f7eoVGBfs_s1| |%%_f7AkT7Cfs_s2|) () (string>=? (string-downcase |%%_f7eoVGBfs_s1|) (string-downcase |%%_f7AkT7Cfs_s2|))))) (#%program ((|%%_f7gdP1Dfs_s2| . 1) (|%%_f7WgRACfs_s1| . 1) (string-downcase . 2) (string<=? . 1)) () (string-downcase string<=?) (#%define string-ci<=? (#%lambda #t (|%%_f7WgRACfs_s1| |%%_f7gdP1Dfs_s2|) () (string<=? (string-downcase |%%_f7WgRACfs_s1|) (string-downcase |%%_f7gdP1Dfs_s2|))))) (#%program ((- . 1) (make-string . 1) (|%%_f7E-GREfs_end| . 2) (|%%_f7i2JoEfs_start| . 2) (|%%_f7-WEiFfs_newstr| . 2) (|%%_f7Y5LXDfs_str| . 1) (+ . 2) (|%%_f7C9NuDfs_fill-string| . 2) (|%%_f7kTCLFfs_sstr| . 2) (string-ref . 1) (|%%_f70MyFGfs_n| . 2) (|%%_f7GPAcGfs_dstr| . 2) (string-set! . 1) (|%%_f7IEuzHfs_e| . 2) (|%%_f7mIw6Hfs_s| . 3) (< . 1)) ((|%%_f7C9NuDfs_fill-string| . 1)) (make-string - string-ref string-set! + <) (#%define substring (#%letrec #t ((|%%_f7C9NuDfs_fill-string| (#%lambda #t (|%%_f7kTCLFfs_sstr| |%%_f7GPAcGfs_dstr| |%%_f70MyFGfs_n| |%%_f7mIw6Hfs_s| |%%_f7IEuzHfs_e|) (|%%_f7C9NuDfs_fill-string|) (#%if (< |%%_f7mIw6Hfs_s| |%%_f7IEuzHfs_e|) (#%begin (string-set! |%%_f7GPAcGfs_dstr| |%%_f70MyFGfs_n| (string-ref |%%_f7kTCLFfs_sstr| |%%_f7mIw6Hfs_s|)) (|%%_f7C9NuDfs_fill-string| |%%_f7kTCLFfs_sstr| |%%_f7GPAcGfs_dstr| (+ |%%_f70MyFGfs_n| 1) (+ |%%_f7mIw6Hfs_s| 1) |%%_f7IEuzHfs_e|)) #!void)))) () (#%lambda #t (|%%_f7Y5LXDfs_str| |%%_f7i2JoEfs_start| |%%_f7E-GREfs_end|) (|%%_f7C9NuDfs_fill-string|) ((#%lambda #t (|%%_f7-WEiFfs_newstr|) (|%%_f7E-GREfs_end| |%%_f7i2JoEfs_start| |%%_f7Y5LXDfs_str| |%%_f7C9NuDfs_fill-string|) (#%begin (|%%_f7C9NuDfs_fill-string| |%%_f7Y5LXDfs_str| |%%_f7-WEiFfs_newstr| 0 |%%_f7i2JoEfs_start| |%%_f7E-GREfs_end|) |%%_f7-WEiFfs_newstr|)) (make-string (- |%%_f7E-GREfs_end| |%%_f7i2JoEfs_start|))))))) (#%program ((- . 1) (cdr . 1) (list-ref . 1) (|%%_f72Bs0Ifs_list| . 2) (car . 1) (|%%_f7oxqtIfs_n| . 2) (zero? . 1)) () (list-ref cdr - car zero?) (#%define list-ref (#%lambda #t (|%%_f72Bs0Ifs_list| |%%_f7oxqtIfs_n|) () (#%if (zero? |%%_f7oxqtIfs_n|) (car |%%_f72Bs0Ifs_list|) (list-ref (cdr |%%_f72Bs0Ifs_list|) (- |%%_f7oxqtIfs_n| 1)))))) (#%program ((|%%_f7KtoWIfs_args| . 1) (|%%_f74qmnJfs_k| . 1) (apply . 1) (call-with-current-continuation . 1)) () (apply call-with-current-continuation) (#%define values (#%lambda #t |%%_f7KtoWIfs_args| () (call-with-current-continuation (#%lambda #t (|%%_f74qmnJfs_k|) (|%%_f7KtoWIfs_args|) (apply |%%_f74qmnJfs_k| |%%_f7KtoWIfs_args|)))))) sisc-1.16.6.orig/src/sisc/boot/sisc-heap.jar0000644000175000017500000000000011445752462017176 0ustar amoeamoesisc-1.16.6.orig/src/sisc/boot/repl.scm0000644000175000017500000001576711445752462016324 0ustar amoeamoe;; ;; The contents of this file are subject to the Mozilla Public ;; License Version 1.1 (the "License"); you may not use this file ;; except in compliance with the License. You may obtain a copy of ;; the License at http://www.mozilla.org/MPL/ ;; ;; Software distributed under the License is distributed on an "AS ;; IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ;; implied. See the License for the specific language governing ;; rights and limitations under the License. ;; ;; The Original Code is the Second Interpreter of Scheme Code (SISC). ;; ;; The Initial Developer of the Original Code is Scott G. Miller. ;; Portions created by Scott G. Miller are Copyright (C) 2000-2007 ;; Scott G. Miller. All Rights Reserved. ;; ;; Contributor(s): ;; Matthias Radestock ;; ;; Alternatively, the contents of this file may be used under the ;; terms of the GNU General Public License Version 2 or later (the ;; "GPL"), in which case the provisions of the GPL are applicable ;; instead of those above. If you wish to allow use of your ;; version of this file only under the terms of the GPL and not to ;; allow others to use your version of this file under the MPL, ;; indicate your decision by deleting the provisions above and ;; replace them with the notice and other provisions required by ;; the GPL. If you do not delete the provisions above, a recipient ;; may use your version of this file under either the MPL or the ;; GPL. ;; ;; The SISC read-eval-print-loop ; Most of the REPL is parameterized, here we define those ; parameters (define _exit-handler (make-parameter '())) (define current-exit-handler (make-parameter (lambda (rv) rv))) (define current-default-error-handler (make-parameter (lambda (m e) (let ([exception (make-exception m e)]) (putprop 'last-exception '*debug* exception) (print-exception exception (stack-trace-on-error)))))) (define current-writer (make-parameter (lambda (v) (if (and (procedure? (getprop 'pretty-print)) (not (getprop '*sisc* 'LITE)) (not (circular? v))) (pretty-print v) ;;dynamic wind would be better here, but ;;we don't want to use it in core code (let ([ps (print-shared)]) (print-shared #t) (write v) (print-shared ps)))))) (define repl-prompt (make-config-parameter "replPrompt" (lambda (repl-depth) (format "#;~a> " (if (zero? repl-depth) "" repl-depth))))) (define stack-trace-on-error (make-config-parameter "stackTraceOnError" #t)) (define (get-last-exception) (getprop 'last-exception '*debug*)) (define repl-thread (let ((thread #f)) (lambda arg (if (null? arg) thread (let ((old thread)) (set! thread (car arg)) old))))) (define make-interrupt-handler (if (not (getprop 'LITE (get-symbolic-environment '*sisc*))) (lambda () ; We use absolute references to threading here so that this can ; coexist with the lite and full dists without using import (repl-thread (|@threading-native::thread/current|)) (letrec ([handler (lambda () (_signal-unhook! "INT" handler) (if (repl-thread) (|@threading-native::thread/interrupt| (repl-thread))))]) handler)) (lambda () #f))) (define (repl) (define (repl/read) (let ([handler (and (permit-interrupts) (make-interrupt-handler))]) (define (repl/eval exp) (let ([compiled (compile-with-flags exp 'expand '((e) (e)) (interaction-environment))]) (when handler (_signal-hook! "INT" handler)) (with/fc (lambda (m e) (when handler (_signal-unhook! "INT" handler)) (throw m e)) (lambda () (let ([val (compiled)]) (when handler (_signal-unhook! "INT" handler)) val))))) ;; Display the prompt (let ([rp (repl-prompt)] [repl-depth (- (length (_exit-handler)) 1)]) (display (if (procedure? rp) (rp repl-depth) rp))) ;;read (let ([exp (read-code (current-input-port))]) (if (eof-object? exp) (if ((current-exit-handler) exp) (exit exp) (repl/read)) (begin ;; Consume any whitespace (let loop () (when (and (char-ready? (current-input-port)) (char-whitespace? (peek-char))) (read-char) (loop))) ;;eval (let ([val (repl/eval exp)]) ;;print (if (not (void? val)) (begin ((current-writer) val) (newline)))) ;;loop (repl/read)))))) (let ([repl-start #f]) (repl-initialize) (or ((current-exit-handler) (call/cc (lambda (k) (_exit-handler (cons k (_exit-handler))) (begin (let ([kret (call/cc (lambda (k) (set! repl-start k) (putprop 'repl '*debug* k)))]) ; The repl-return continuation can optionally ; be passed a thunk which is executed ; *in this dynamic environment* (if (procedure? kret) (kret))) (let loop () (with/fc (lambda (m e) ((current-default-error-handler) m e) (loop)) (lambda () (repl/read) (void)))))))) (repl-start)))) (define (sisc-cli) (display (format "SISC (~a)\n" (getprop 'version (get-symbolic-environment '*sisc*)))) (let loop () (with/fc (lambda (m e) (display (format "Uncaught error: ~a~%Please report this error to sisc-devel@lists.sourceforge.net~%" m)) (if (pair? (_exit-handler)) (_exit-handler (cdr (_exit-handler)))) (loop)) repl))) (define (exit . return-value) (if (not (pair? (_exit-handler))) (error 'exit "not in a read-eval-print-loop.")) (let ([k (car (_exit-handler))] [rv (if (null? return-value) #!void (car return-value))]) (_exit-handler (cdr (_exit-handler))) (newline) (if k (k rv) rv))) (on-repl-start (lambda () (source-annotations '((source-kind . user))) (current-url (string-append "file:" (let ([dir (getenv "user.dir")]) (if dir (string-append dir (getenv "file.separator")) ".")))))) sisc-1.16.6.orig/src/sisc/boot/bootstrap.scm0000644000175000017500000000066311445752462017364 0ustar amoeamoe(display "Expanding init.scm...\n") (expand-file "init.scm" "init.sce" '(e) '(e)) (display "Expanding compat.scm...\n") (expand-file "compat.scm" "compat.sce" '(e) '(e)) (display "Expanding psyntax.ss...\n") (expand-file "psyntax.ss" "psyntax.sce" '(l) '(l)) (display "Expanding analyzer.scm...\n") (expand-file "analyzer.scm" "analyzer.sce" '(l) '(l)) (display "Expanding eval.scm...\n") (expand-file "eval.scm" "eval.sce" '(e) '(e)) sisc-1.16.6.orig/src/sisc/boot/psyntax.ss0000644000175000017500000045027511445752462016730 0ustar amoeamoe;;; Portable implementation of syntax-case ;;; Extracted from Chez Scheme Version 6.9 (Jul 12, 2002) ;;; Authors: R. Kent Dybvig, Oscar Waddell, Bob Hieb, Carl Bruggeman ;;; Copyright (c) 1992-2002 Cadence Research Systems ;;; Permission to copy this software, in whole or in part, to use this ;;; software for any lawful purpose, and to redistribute this software ;;; is granted subject to the restriction that all copies made of this ;;; software must include this copyright notice in full. This software ;;; is provided AS IS, with NO WARRANTY, EITHER EXPRESS OR IMPLIED, ;;; INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY ;;; OR FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE ;;; AUTHORS BE LIABLE FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES OF ANY ;;; NATURE WHATSOEVER. ;;; Before attempting to port this code to a new implementation of ;;; Scheme, please read the notes below carefully. ;;; This file defines the syntax-case expander, sc-expand, and a set ;;; of associated syntactic forms and procedures. Of these, the ;;; following are documented in The Scheme Programming Language, ;;; Second Edition (R. Kent Dybvig, Prentice Hall, 1996), which can be ;;; found online at http://www.scheme.com. Most are also documented ;;; in the R4RS and draft R5RS. ;;; ;;; bound-identifier=? ;;; datum->syntax-object ;;; define-syntax ;;; fluid-let-syntax ;;; free-identifier=? ;;; generate-temporaries ;;; identifier? ;;; identifier-syntax ;;; let-syntax ;;; letrec-syntax ;;; syntax ;;; syntax-case ;;; syntax-object->datum ;;; syntax-rules ;;; with-syntax ;;; ;;; All standard Scheme syntactic forms are supported by the expander ;;; or syntactic abstractions defined in this file. Only the R4RS ;;; delay is omitted, since its expansion is implementation-dependent. ;;; Also defined are three forms that support modules: module, import, ;;; and import-only. These are documented in the Chez Scheme User's ;;; Guide (R. Kent Dybvig, Cadence Research Systems, 1998), which can ;;; also be found online at http://www.scheme.com. They are described ;;; briefly here as well. ;;; ;;; Both are definitions and may appear where and only where other ;;; definitions may appear. modules may be named: ;;; ;;; (module id (ex ...) defn ... init ...) ;;; ;;; or anonymous: ;;; ;;; (module (ex ...) defn ... init ...) ;;; ;;; The latter form is semantically equivalent to: ;;; ;;; (module T (ex ...) defn ... init ...) ;;; (import T) ;;; ;;; where T is a fresh identifier. ;;; ;;; In either form, each of the exports in (ex ...) is either an ;;; identifier or of the form (id ex ...). In the former case, the ;;; single identifier ex is exported. In the latter, the identifier ;;; id is exported and the exports ex ... are "implicitly" exported. ;;; This listing of implicit exports is useful only when id is a ;;; keyword bound to a transformer that expands into references to ;;; the listed implicit exports. In the present implementation, ;;; listing of implicit exports is necessary only for top-level ;;; modules and allows the implementation to avoid placing all ;;; identifiers into the top-level environment where subsequent passes ;;; of the compiler will be unable to deal effectively with them. ;;; ;;; Named modules may be referenced in import statements, which ;;; always take one of the forms: ;;; ;;; (import id) ;;; (import-only id) ;;; ;;; id must name a module. Each exported identifier becomes visible ;;; within the scope of the import form. In the case of import-only, ;;; all other identifiers become invisible in the scope of the ;;; import-only form, except for those established by definitions ;;; that appear textually after the import-only form. ;;; The remaining exports are listed below. sc-expand, eval-when, and ;;; syntax-error are described in the Chez Scheme User's Guide. ;;; ;;; (sc-expand datum) ;;; if datum represents a valid expression, sc-expand returns an ;;; expanded version of datum in a core language that includes no ;;; syntactic abstractions. The core language includes begin, ;;; define, if, lambda, letrec, quote, and set!. ;;; (eval-when situations expr ...) ;;; conditionally evaluates expr ... at compile-time or run-time ;;; depending upon situations ;;; (syntax-error object message) ;;; used to report errors found during expansion ;;; ($syntax-dispatch e p) ;;; used by expanded code to handle syntax-case matching ;;; ($sc-put-cte symbol val) ;;; used to establish top-level compile-time (expand-time) bindings. ;;; The following nonstandard procedures must be provided by the ;;; implementation for this code to run. ;;; ;;; (void) ;;; returns the implementation's cannonical "unspecified value". The ;;; following usually works: ;;; ;;; (define void (lambda () (if #f #f))). ;;; ;;; (andmap proc list1 list2 ...) ;;; returns true if proc returns true when applied to each element of list1 ;;; along with the corresponding elements of list2 .... The following ;;; definition works but does no error checking: ;;; ;;; (define andmap ;;; (lambda (f first . rest) ;;; (or (null? first) ;;; (if (null? rest) ;;; (let andmap ((first first)) ;;; (let ((x (car first)) (first (cdr first))) ;;; (if (null? first) ;;; (f x) ;;; (and (f x) (andmap first))))) ;;; (let andmap ((first first) (rest rest)) ;;; (let ((x (car first)) ;;; (xr (map car rest)) ;;; (first (cdr first)) ;;; (rest (map cdr rest))) ;;; (if (null? first) ;;; (apply f (cons x xr)) ;;; (and (apply f (cons x xr)) (andmap first rest))))))))) ;;; ;;; (ormap proc list1) ;;; returns the first non-false return result of proc applied to ;;; the elements of list1 or false if none. The following definition ;;; works but does no error checking: ;;; ;;; (define ormap ;;; (lambda (proc list1) ;;; (and (not (null? list1)) ;;; (or (proc (car list1)) (ormap proc (cdr list1)))))) ;;; ;;; The following nonstandard procedures must also be provided by the ;;; implementation for this code to run using the standard portable ;;; hooks and output constructors. They are not used by expanded code, ;;; and so need be present only at expansion time. ;;; ;;; (eval x) ;;; where x is always in the form ("noexpand" expr). ;;; returns the value of expr. the "noexpand" flag is used to tell the ;;; evaluator/expander that no expansion is necessary, since expr has ;;; already been fully expanded to core forms. ;;; ;;; eval will not be invoked during the loading of psyntax.pp. After ;;; psyntax.pp has been loaded, the expansion of any macro definition, ;;; whether local or global, results in a call to eval. If, however, ;;; sc-expand has already been registered as the expander to be used ;;; by eval, and eval accepts one argument, nothing special must be done ;;; to support the "noexpand" flag, since it is handled by sc-expand. ;;; ;;; (error who format-string why what) ;;; where who is either a symbol or #f, format-string is always "~a ~s", ;;; why is always a string, and what may be any object. error should ;;; signal an error with a message something like ;;; ;;; "error in : " ;;; ;;; (gensym) ;;; returns a unique symbol each time it's called. In Chez Scheme, gensym ;;; returns a symbol with a "globally" unique name so that gensyms that ;;; end up in the object code of separately compiled files cannot conflict. ;;; This is necessary only if you intend to support compiled files. ;;; ;;; (putprop symbol key value) ;;; (getprop symbol key) ;;; (remprop symbol key) ;;; key is always a symbol; value may be any object. putprop should ;;; associate the given value with the given symbol and key in some way ;;; that it can be retrieved later with getprop. getprop should return ;;; #f if no value is associated with the given symbol and key. remprop ;;; should remove the association between the given symbol and key. ;;; When porting to a new Scheme implementation, you should define the ;;; procedures listed above, load the expanded version of psyntax.ss ;;; (psyntax.pp, which should be available whereever you found ;;; psyntax.ss), and register sc-expand as the current expander (how ;;; you do this depends upon your implementation of Scheme). You may ;;; change the hooks and constructors defined toward the beginning of ;;; the code below, but to avoid bootstrapping problems, do so only ;;; after you have a working version of the expander. ;;; Chez Scheme allows the syntactic form (syntax