diff options
author | Bryan Newbold <bnewbold@robocracy.org> | 2017-02-20 00:05:23 -0800 |
---|---|---|
committer | Bryan Newbold <bnewbold@robocracy.org> | 2017-02-20 00:05:23 -0800 |
commit | 5ca6e8e6a4e5c022a6fb5d28f30219c22c99eda8 (patch) | |
tree | 9b744b9dbf39e716e56daa620e2f3041968caf19 /scm.texi | |
download | scm-5ca6e8e6a4e5c022a6fb5d28f30219c22c99eda8.tar.gz scm-5ca6e8e6a4e5c022a6fb5d28f30219c22c99eda8.zip |
Import Upstream version 4e6upstream/4e6
Diffstat (limited to 'scm.texi')
-rw-r--r-- | scm.texi | 6911 |
1 files changed, 6911 insertions, 0 deletions
diff --git a/scm.texi b/scm.texi new file mode 100644 index 0000000..d7270f6 --- /dev/null +++ b/scm.texi @@ -0,0 +1,6911 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename scm.info +@settitle SCM +@setchapternewpage on +@c Choices for setchapternewpage are {on,off,odd}. +@paragraphindent 2 +@c %**end of header + +@iftex +@finalout +@c DL: lose the egregious vertical whitespace, esp. around examples +@c but paras in @defun-like things don't have parindent +@parskip 4pt plus 1pt +@end iftex + +@titlepage +@title SCM +@subtitle Scheme Implementation +@subtitle Version 4e6 +@subtitle March 1996 +@author by Aubrey Jaffer + +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1990, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by the author. +@end titlepage + +@node Top, Copying, (dir), (dir) + + +@ifinfo +This manual documents the SCM Scheme implementation. The most recent +information about SCM can be found on SCM's @dfn{WWW} home page: +@center http://www-swiss.ai.mit.edu/~jaffer/SCM.html + + +Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by the author. +@end ifinfo + +@menu +* Copying:: Conditions for copying and changing SCM. +* Overview:: Whats here and how to start using it. +* Installing SCM:: Where it goes and how to get it there. +* The Language:: Reference. +* Packages:: Optional Capabilities. +* The Implementation:: How it works. +* Procedure and Macro Index:: +* Variable Index:: +* Type Index:: +@end menu + +@node Copying, Overview, Top, Top +@chapter Copying + +@center COPYRIGHT (c) 1989 BY +@center PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS. +@center ALL RIGHTS RESERVED + +@noindent +Permission to use, copy, modify, distribute and sell this software +and its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all copies +and that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Paradigm Associates +Inc not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. + +@noindent +PARADIGM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +PARADIGM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +@noindent +gjc@@paradigm.com +@flushright +Phone: 617-492-6079 +@end flushright +@flushleft +Paradigm Associates Inc +29 Putnam Ave, Suite 6 +Cambridge, MA 02138 +@end flushleft + +@sp 2 + +@center Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995 +@center Free Software Foundation, Inc. +@center 675 Mass Ave, Cambridge, MA 02139, USA + +@noindent +Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. + +@center NO WARRANTY + +@noindent +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. + +@noindent +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. + +@node Overview, Installing SCM, Copying, Top +@chapter Overview + +@noindent +Scm is a portable Scheme implementation written in C. Scm provides a +machine independent platform for [JACAL], a symbolic algebra system. + +@iftex +@noindent +The most recent information about SCM can be found on SCM's @dfn{WWW} +home page: +@ifset html +<A HREF="http://www-swiss.ai.mit.edu/~jaffer/SCM.html"> +@end ifset + +@center http://www-swiss.ai.mit.edu/~jaffer/SCM.html + +@ifset html +</A> +@end ifset +@end iftex + +@menu +* SCM Features:: +* SCM Authors:: +* Bibliography:: +* Invoking SCM:: +* SCM Options:: +* SCM Variables:: +* SCM Examples:: +* SCM Session:: +* Editing Scheme Code:: +* Debugging Scheme Code:: +@end menu + +@node SCM Features, SCM Authors, Overview, Overview +@section Features + +@itemize @bullet +@item +Conforms to Revised^4 Report on the Algorithmic Language Scheme [R4RS] +and the [IEEE] P1178 specification. +@item +Support for [SICP], [R2RS], [R3RS], and (proposed) [R5RS] scheme code. +@item +Runs under Amiga, Atari-ST, MacOS, MS-DOS, OS/2, NOS/VE, Unicos, VMS, +Unix and similar systems. Supports ASCII and EBCDIC character sets. +@item +Is fully documented in @TeX{}info form, allowing documentation to be +generated in info, @TeX{}, html, nroff, and troff formats. +@item +Supports inexact real and complex numbers, 30 bit immediate integers and +large precision integers. +@item +Many Common Lisp functions: @code{logand}, @code{logor}, @code{logxor}, +@code{lognot}, @code{ash}, @code{logcount}, @code{integer-length}, +@code{bit-extract}, @code{defmacro}, @code{macroexpand}, +@code{macroexpand1}, @code{gentemp}, @code{defvar}, @code{force-output}, +@code{software-type}, @code{get-decoded-time}, +@code{get-internal-run-time}, @code{get-internal-real-time}, +@code{delete-file}, @code{rename-file}, @code{copy-tree}, @code{acons}, +and @code{eval}. +@item +@code{Char-code-limit}, @code{most-positive-fixnum}, +@code{most-negative-fixnum}, @code{and internal-time-units-per-second} +constants. @code{*Features*} and @code{*load-pathname*} variables. +@item +Arrays and bit-vectors. String ports and software emulation ports. +I/O extensions providing ANSI C and POSIX.1 facilities. +@item +Interfaces to standard libraries including REGEX string regular +expression matching and the CURSES screen management package. +@item +Available add-on packages including an interactive debugger, database, +X-window graphics, BGI graphics, Motif, and Open-Windows packages. +@item +A compiler (HOBBIT, available separately) and dynamic linking of +compiled modules. +@item +User definable responses to interrupts and errors, +Process-syncronization primitives. Setable levels of monitoring and +timing information printed interactively (the @code{verbose} function). +@code{Restart}, @code{quit}, and @code{exec}. +@end itemize + +@node SCM Authors, Bibliography, SCM Features, Overview +@section Authors + +@table @b +@item Aubrey Jaffer (jaffer@@ai.mit.edu) +Most of SCM. +@item Radey Shouman +Arrays. @code{gsubr}s, compiled closures, and records. +@item Jerry D. Hedden +Real and Complex functions. Fast mixed type arithmetics. +@item Hugh Secker-Walker +Syntax checking and memoization of special forms by evaluator. Storage +allocation strategy and parameters. +@item George Carrette +@dfn{Siod}, written by George Carrette, was the starting point for SCM. +The major innovations taken from Siod are the evaluator's use of the +C-stack and being able to garbage collect off the C-stack +(@pxref{Garbage Collection}). +@end table + +@noindent +There are many other contributors to SCM. They are acknowledged in the +file @file{ChangeLog}, a log of changes that have been made to scm. + +@node Bibliography, Invoking SCM, SCM Authors, Overview +@section Bibliography + +@table @asis +@item [IEEE] +@pindex IEEE +@cite{IEEE Standard 1178-1990. IEEE Standard for the Scheme +Programming Language.} IEEE, New York, 1991. + +@item [Simply] +@pindex Simply +Brian Harvey and Matthew Wright. +@ifset html +<A HREF="http://HTTP.CS.Berkeley.EDU/~bh/simply-toc.html"> +@end ifset +@cite{Simply Scheme: Introducing Computer Science} +@ifset html +</A> +@end ifset +MIT Press, 1994 ISBN 0-262-08226-8 + +@item [SICP] +@pindex SICP +Harold Abelson and Gerald Jay Sussman with Julie Sussman. +@cite{Structure and Interpretation of Computer Programs.} +MIT Press, Cambridge, 1985. + +@item [R4RS] +@pindex R4RS +William Clinger and Jonathan Rees, Editors. +@ifset html +<A HREF="r4rs_toc.html"> +@end ifset +Revised(4) Report on the Algorithmic Language Scheme. +@ifset html +</A> +@end ifset +@cite{ACM Lisp Pointers} Volume IV, Number 3 (July-September 1991), +pp. 1-55. +@ifinfo + +@ref{Top, , , r4rs, Revised(4) Report on the Algorithmic Language +Scheme}. +@end ifinfo + +@item [GUILE] +@pindex GUILE +Tom Lord. +@ifset html +<A HREF="http://www.cygnus.com/library/ctr/guile.html"> +@end ifset +The Guile Architecture for Ubiquitous Computing. +@ifset html +</A> +@end ifset +@cite{Usenix Symposium on Tcl/Tk}, 1995. + +@item [SLIB] +@pindex SLIB +Todd R. Eigenschink, Dave Love, and Aubrey Jaffer. +@ifset html +<A HREF="slib_toc.html"> +@end ifset +SLIB, The Portable Scheme Library. +@ifset html +</A> +@end ifset +Version 2a3, June 1995. +@ifinfo + +@ref{Top, , , slib, SLIB}. +@end ifinfo + +@item [JACAL] +@pindex JACAL +Aubrey Jaffer. +@ifset html +<A HREF="jacal_toc.html"> +@end ifset +JACAL Symbolic Mathematics System. +@ifset html +</A> +@end ifset +Version 1a5, April 1994. +@ifinfo + +@ref{Top, , , jacal, JACAL}. +@end ifinfo +@end table + +@table @file +@item scm.texi +@itemx scm.info +Documentation of @code{scm} extensions (beyond Scheme standards). +Documentation on the internal representation and how to extend or +include @code{scm} in other programs. +@end table + +@node Invoking SCM, SCM Options, Bibliography, Overview +@section Invoking SCM + +@quotation +@exdent @b{ scm } [-a @i{kbytes}] [-ibvqmu] [-p @i{number}] +@w{[-c @i{expression}]} @w{[-e @i{expression}]} @w{[-f @i{filename}]} +@w{[-l @i{filename}]} @w{[-r @i{feature}]} @w{[-- | - | -s]} +@w{[@i{filename}]} @w{[@i{arguments} @dots{}]} +@end quotation + +@noindent +Upon startup @code{scm} loads the file specified by by the environment +variable @var{SCM_INIT_PATH}. + +@noindent +If @var{SCM_INIT_PATH} is not defined or if the file it names is not +present, @code{scm} tries to find the directory containing the +executable file. If it is able to locate the executable, @code{scm} +looks for the initialization file (usually @file{Init.scm}) in +platform-dependent directories relative to this directory. +@xref{File-System Habitat} for a blow-by-blow description. + +@noindent +As a last resort (if initialization file cannot be located), the C +compile parameter @var{IMPLINIT} (defined in the makefile or +@file{scmfig.h}) is tried. + +@noindent +Unless the option @code{-no-init-file} or @code{--no-init-file} occurs +in the command line, @file{Init.scm} checks to see if there is file +@file{ScmInit.scm} in the path specified by the environment variable +@var{HOME} (or in the current directory if @var{HOME} is undefined). If +it finds such a file it is loaded. + +@noindent +@file{Init.scm} then looks for command input from one of three sources: +From an option on the command line, from a file named on the command +line, or from standard input. + +@noindent +This explanation applies to SCMLIT or other builds of SCM. + +@noindent +Scheme-code files can also invoke SCM and its variants. @xref{Syntax +Extensions, #!}. + +@node SCM Options, SCM Variables, Invoking SCM, Overview +@section Options + +@noindent +The options are processed in the order specified on the command line. + +@deffn {Command Option} -a kb +specifies that @code{scm} should allocate an initial heapsize of +@var{kb} kilobytes. This option, if present, must be the first on +the command line. If not specified, the default is +@code{INIT_HEAP_SIZE} in source file @file{setjump.h} which the +distribution sets at @code{25000*sizeof(cell)}. +@end deffn + +@deffn {Command Option} -no-init-file +@deffnx {Command Option} --no-init-file +Inhibits the loading of @file{ScmInit.scm} as described above. +@end deffn + +@deffn {Command Option} -e expression +@deffnx {Command Option} -c expression +specifies that the scheme expression @var{expression} is to be +evaluated. These options are inspired by @code{perl} and @code{sh} +respectively. On Amiga systems the entire option and argument need to be +enclosed in quotes. For instance @samp{"-e(newline)"}. +@end deffn + +@deffn {Command Option} -r feature +requires @var{feature}. This will load a file from [SLIB] if that +@var{feature} is not already supported. If @var{feature} is 2, 3, 4, or +5 @code{scm} will require the features neccessary to support [R2RS], +[R3RS], [R4RS], or proposed [R5RS], respectively. +@end deffn + +@deffn {Command Option} -l filename +@deffnx {Command Option} -f filename +loads @var{filename}. @code{Scm} will load the first (unoptioned) file +named on the command line if no @code{-c}, @code{-e}, @code{-f}, +@code{-l}, or @code{-s} option preceeds +it. +@end deffn + +@deffn {Command Option} -p level +sets the prolixity (verboseness) to @var{level}. This is the same as +the @code{scm} command (verobse @var{level}). +@end deffn + +@deffn {Command Option} -v +(verbose mode) specifies that @code{scm} will print prompts, evaluation +times, notice of loading files, and garbage collection statistics. This +is the same as @code{-p3}. +@end deffn + +@deffn {Command Option} -q +(quiet mode) specifies that @code{scm} will print no extra +information. This is the same as @code{-p0}. +@end deffn + +@deffn {Command Option} -m +specifies that subsequent loads, evaluations, and user interactions will +be with [R4RS] macro capability. To use a specific [R4RS] macro +implementation from [SLIB] (instead of [SLIB]'s default) put @code{-r} +@var{macropackage} before @code{-m} on the command line. +@end deffn + +@deffn {Command Option} -u +specifies that subsequent loads, evaluations, and user interactions will +be without [R4RS] macro capability. [R4RS] macro capability can +be restored by a subsequent @code{-m} on the command line or from Scheme +code. +@end deffn + +@deffn {Command Option} -i +specifies that @code{scm} should run interactively. That means that +@code{scm} will not terminate until the @code{(quit)} or @code{(exit)} +command is given, even if there are errors. It also sets the prolixity +level to 2 if it is less than 2. This will print prompts, evaluation +times, and notice of loading files. The prolixity level can be set by +subsequent options. If @code{scm} is started from a tty, it will assume +that it should be interactive unless given a subsequent @code{-b} +option. +@end deffn + +@deffn {Command Option} -b +specifies that @code{scm} should run non-interactively. That means that +@code{scm} will terminate after processing the command line or if there +are errors. +@end deffn + +@deffn {Command Option} -s +specifies, by analogy with @code{sh}, that further options are to be +treated as program aguments. +@end deffn + +@deffn {Command Option} - +@deffnx {Command Option} -- +specifies that there are no more options on the command line. +@end deffn + +@deffn {Command Option} -d filename +loads SLIB database-utilities and opens @var{filename} as a database. +@end deffn + +@deffn {Command Option} -o filename +saves the current SCM session as the executable program @file{filename}. +This option works only in SCM builds supporting @code{dump} +(@pxref{Dump}). + +If options appear on the command line after @samp{-o @var{filename}}, +then the saved session will continue with processing those options when +it is invoked. Otherwise the (new) command line is processed as usual +when the saved image is invoked. +@end deffn + +@deffn {Command Option} --help +prints usage information and URL; then exit. +@end deffn + +@deffn {Command Option} --version +prints version information and exit. +@end deffn + +@node SCM Variables, SCM Examples, SCM Options, Overview +@section Environment Variables + +@defvr {Environment Variable} SCM_INIT_PATH +is the pathname where @code{scm} will look for its initialization +code. The default is the file @file{Init.scm} in the source directory. +@end defvr + +@defvr {Environment Variable} SCHEME_LIBRARY_PATH +is the [SLIB] Scheme library directory. +@end defvr + +@defvr {Environment Variable} HOME +is the directory where @file{Init.scm} will look for the user +initialization file @file{ScmInit.scm}. +@end defvr + +@section Scheme Variables + +@defvar *argv* +contains the list of arguments to the program. @code{*argv*} can change +during argument processing. This list is suitable for use as an argument +to [SLIB] @code{getopt}. +@end defvar + +@defvar *R4RS-macro* +controls whether loading and interaction support [R4RS] macros. Define +this in @file{ScmInit.scm} or files specified on the command line. This +can be overridden by subsequent @code{-m} and @code{-u} options. +@end defvar + +@defvar *interactive* +controls interactivity as explained for the @code{-i} and @code{-b} +options. Define this in @file{ScmInit.scm} or files specified on the +command line. This can be overridden by subsequent @code{-i} and +@code{-b} options. +@end defvar + +@node SCM Examples, SCM Session, SCM Variables, Overview +@section Examples + +@table @code +@item % scm foo.scm +Loads and executes the contents of @file{foo.scm} and then enters +interactive session. + +@item % scm -f foo.scm arg1 arg2 arg3 +Parameters @code{arg1}, @code{arg2}, and @code{arg3} are stored in the +global list @code{*argv*}; Loads and executes the contents of +@file{foo.scm} and exits. + +@item % scm -s foo.scm arg1 arg2 +Sets *argv* to @code{("foo.scm" "arg1" "arg2")} and enters interactive +session. + +@item % scm -e `(write (list-ref *argv* *optind*))' bar +Prints @samp{"bar"}. + +@item % scm -rpretty-print -r format -i +Loads @code{pretty-print} and @code{format} and enters interactive +session. + +@item % scm -r5 +Loads @code{dynamic-wind}, @code{values}, and [R4RS] macros and enters +interactive (with macros) session. + +@item % scm -r5 -r4 +Like above but @code{rev4-optional-procedures} are also loaded. +@end table + +@node SCM Session, Editing Scheme Code, SCM Examples, Overview +@section SCM Session + +@itemize @bullet +@item +Options, file loading and features can be specified from the command +line. @xref{System interface, , , scm, SCM}. @xref{Require, , , slib, +SLIB}. +@item +Typing the end-of-file character at the top level session (while SCM is +not waiting for parenthesis closure) causes SCM to exit. +@item +Typing the interrupt character aborts evaluation of the current form +and resumes the top level read-eval-print loop. +@end itemize + +@node Editing Scheme Code, Debugging Scheme Code, SCM Session, Overview +@section Editing Scheme Code + +@table @asis +@item Gnu Emacs: +Editing of Scheme code is supported by emacs. Buffers holding files +ending in .scm are automatically put into scheme-mode. + +If your Emacs can run a process in a buffer you can use the Emacs +command @samp{M-x run-scheme} with SCM. However, the run-scheme +(@file{xscheme.el}) which comes included with Gnu Emacs 18 will work +only with MIT Cscheme. If you are using Emacs 18, get the emacs +packages: + +@ifclear html +@itemize @bullet +@item +ftp-swiss.ai.mit.edu:/pub/scheme-editor-packages/cmuscheme.el +@item +ftp-swiss.ai.mit.edu:/pub/scheme-editor-packages/comint.el +@end itemize +@end ifclear + +@ifset html +<A HREF="file://ftp-swiss.ai.mit.edu/pub/scheme-editor-packages/cmuscheme.el"> +ftp-swiss.ai.mit.edu:/pub/scheme-editor-packages/cmuscheme.el +</A> +<A HREF="file://ftp-swiss.ai.mit.edu/pub/scheme-editor-packages/comint.el"> +ftp-swiss.ai.mit.edu:/pub/scheme-editor-packages/comint.el +</A> +@end ifset + +These files are already standard in Emacs 19. + +If your Emacs can not run a process in a buffer, see ``under other +systems'' below. + +@item Epsilon (MS-DOS): +There is lisp (and scheme) mode available by use of the package +@samp{LISP.E}. It offers several different indentation formats. With +this package, buffers holding files ending in @samp{.L}, @samp{.LSP}, +@samp{.S}, and @samp{.SCM} (my modification) are automatically put into +lisp-mode. + +It is possible to run a process in a buffer under Epsilon. With Epsilon +5.0 the command line options @samp{-e512 -m0} are neccessary to manage +RAM properly. It has been reported that when compiling SCM with Turbo +C, you need to @samp{#define NOSETBUF} for proper operation in a process +buffer with Epsilon 5.0. + +One can also call out to an editor from SCM if RAM is at a premium; See +``under other systems'' below. + +@item other systems: +Define the environment variable @samp{EDITOR} to be the name of the +editing program you use. The SCM procedure @code{(ed arg1 @dots{})} +will invoke your editor and return to SCM when you exit the editor. The +following definition is convenient: + +@example +(define (e) (ed "work.scm") (load "work.scm")) +@end example + +Typing @samp{(e)} will invoke the editor with the file of interest. +After editing, the modified file will be loaded. +@end table + +@node Debugging Scheme Code, , Editing Scheme Code, Overview +@section Debugging Scheme Code + +@noindent +The @code{cautious} and @code{stack-limit} options of @code{build} +(@pxref{Build Options}) support debugging in Scheme. + +@table @dfn +@item CAUTIOUS +If SCM is built with the @samp{CAUTIOUS} flag, then when an error +occurs, a @dfn{stack trace} of certain pending calls are printed as part +of the default error response. A (memoized) expression and newline are +printed for each partially evaluated combination whose procedure is not +builtin. @xref{Memoized Expressions} for how to read memoized +expressions. + +Also as the result of the @samp{CAUTIOUS} flag, both @code{error} and +@code{user-interrupt} (invoked by @key{C-c}) to print stack traces and +conclude by calling @code{breakpoint} (@pxref{Breakpoints, , , slib, +SLIB}) instead of aborting to top level. Under either condition, +program execution can be resumed by @code{(continue)}. + +In this configuration one can interrupt a running Scheme program with +@key{C-c}, inspect or modify top-level values, trace or untrace +procedures, and continue execution with @code{(continue)}. + +@item STACK_LIMIT +If SCM is built with the @samp{STACK_LIMIT} flag, the interpreter will +check stack size periodically. If the size of stack exceeds a certain +amount (default is @code{HEAP_SEG_SIZE/2}), SCM generates a +@code{segment violation} interrupt. + +The usefulness of @samp{STACK_LIMIT} depends on the user. I don't use +it; but the user I added this feature for got primarily this type of +error. +@end table + +@noindent +There are several SLIB macros which so useful that SCM automatically +loads the appropriate module from SLIB if they are invoked. + +@defmac trace proc1 @dots{} +Traces the top-level named procedures given as arguments. +@defmacx trace +With no arguments, makes sure that all the currently traced identifiers +are traced (even if those identifiers have been redefined) and returns a +list of the traced identifiers. +@end defmac + +@defmac untrace proc1 @dots{} +Turns tracing off for its arguments. +@defmacx untrace +With no arguments, untraces all currently traced identifiers and returns +a list of these formerly traced identifiers. +@end defmac + +The routine I use most for debugging is: + +@deffn Procedure print arg1 ... +@code{Print} writes all its arguments, separated by spaces. +@code{Print} outputs a @code{newline} at the end and returns the value +of the last argument. + +One can just insert @samp{(print '<proc-name>} and @samp{)} around an +expression in order to see its value as a program operates. +@end deffn + +@noindent +Sometimes more elaborate measures are needed to print values in a useful +manner. When the values to be printed may have very large (or infinite) +external representations, @ref{Quick Print, , , slib, SLIB}, can be +used. + +When @code{trace} is not sufficient to find program flow problems, +@ifset html +<A HREF="http://www.cs.tut.fi/staff/pk/scheme/psd/article/article.html"> +@end ifset +SLIB-PSD, the Portable Scheme Debugger +@ifset html +</A> +@end ifset +offers source code debugging from +GNU Emacs. PSD runs slowly, so start by instrumenting only a few +functions at a time. +@lisp +ftp-swiss.ai.mit.edu:pub/scm/slib-psd1-3.tar.gz +prep.ai.mit.edu:pub/gnu/jacal/slib-psd1-3.tar.gz +ftp.maths.tcd.ie:pub/bosullvn/jacal/slib-psd1-3.tar.gz +ftp.cs.indiana.edu:/pub/scheme-repository/utl/slib-psd1-3.tar.gz +@end lisp + + +@node Installing SCM, The Language, Overview, Top +@chapter Installing SCM + +@menu +* File-System Habitat:: All the usual suspects. +* Executable Pathname:: Where did I come from? +* Making SCM:: +* Building SCM:: +* SLIB:: REQUIREd reading. +* Installing Dynamic Linking:: +* Saving Images:: Make Fast-Booting Executables +* Automatic C Preprocessor Definitions:: +* Problems Compiling:: +* Problems Linking:: +* Problems Running:: +* Testing:: +* Reporting Problems:: +@end menu + +@node File-System Habitat, Executable Pathname, Installing SCM, Installing SCM +@section File-System Habitat + +@noindent +Where should software reside? Although individually a minor annoyance, +cumulatively this question represents many thousands of frustrated user +hours spent trying to find support files or guessing where packages need +to be installed. Even simple programs require proper habitat; games +need to find their score files. + +@noindent +Aren't there standards for this? Some Operating Systems have devised +regimes of software habitats -- only to have them violated by large +software packages and imports from other OS varieties. + +@noindent +In some programs, the expected locations of support files are fixed at +time of compilation. This means that the program may not run on +configurations unanticipated by the authors. Compiling locations into a +program also can make it immovable -- necessitating recompilation to +install it. + +@quotation +Programs of the world unite! You have nothing to lose but loss itself. +@end quotation + +@noindent +The function @code{scm_find_impl_file} in @file{scm.c} is an attempt to +create a utility (for inclusion in programs) which will hide the details +of platform-dependent file habitat conventions. It takes as input the +pathname of the executable file which is running. If there are systems +for which this information is either not available or unrelated to the +locations of support files, then a higher level interface will be +needed. + +@deftypefun char *scm_find_impl_file(char *@var{exec_path}, char +*@var{generic_name}, char *@var{initname}, char *@var{sep}) Given the +pathname of this executable (@var{exec_path}), test for the existence of +@var{initname} in the implementation-vicinity of this program. Return a +newly allocated string of the path if successful, 0 if not. The +@var{sep} argument is a @emph{mull-terminated string} of the character +used to separate directory components. +@end deftypefun + +@itemize @bullet +@item +One convention is to install the support files for an executable program +in the same directory as the program. This possibility is tried first, +which satisfies not only programs using this convention, but also +uninstalled builds when testing new releases, etc. + +@item +Another convention is to install the executables in a directory named +@file{bin}, @file{BIN}, @file{exe}, or @file{EXE} and support files in a +directroy named @file{lib}, which is a peer the executable directory. +This arrangement allows multiple executables can be stored in a single +directory. For example, the executable might be in +@samp{/usr/local/bin/} and initialization file in +@samp{/usr/local/lib/}. + +If the executable directory name matches, the peer directroy @file{lib} +is tested for @var{initname}. + +@item +Sometimes @file{lib} directories become too crowded. So we look in any +subdirectories of @file{lib} or @file{src} having the name (sans type +suffix such as @samp{.EXE}) of the program we are running. For example, +the executable might be @samp{/usr/local/bin/foo} and initialization +file in @samp{/usr/local/lib/foo/}. + +@item +But the executable name may not be the usual program name; So also look +in any @var{generic_name} subdirectories of @file{lib} or @file{src} +peers. + +@item +Finally, if the name of the executable file being run has a (system +dependent) suffix which is not needed to invoke the program, then look +in a subdirectory (of the one containing the executable file) named for +the executable (without the suffix); And look in a @var{generic_name} +subdirectory. For example, the executable might be +@samp{C:\foo\bar.exe} and the initialization file in @samp{C:\foo\bar\}. +@end itemize + + +@node Executable Pathname, Making SCM, File-System Habitat, Installing SCM +@section Executable Pathname + +@noindent +When a program is executed by MS-DOS, the full pathname of that +executable is available in @code{argv[0]}. This value can be passed to +@code{dld_find_executable} (@pxref{File-System Habitat}). + +In order to find the habitat for a unix program, we first need to know +the full pathname for the associated executable file. + +@deftypefun char *dld_find_executable (const char *@var{command}) +@code{dld_find_executable} returns the absolute path name of the file +that would be executed if @var{command} were given as a command. It +looks up the environment variable @var{PATH}, searches in each of the +directory listed for @var{command}, and returns the absolute path name +for the first occurrence. Thus, it is advisable to invoke +@code{dld_init} as: + +@example +main (int argc, char **argv) +@{ + @dots{} + if (dld_init (dld_find_executable (argv[0]))) @{ + @dots{} + @} + @dots{} +@} +@end example + +@quotation +@strong{Note:} If the current process is executed using the +@code{execve} call without passing the correct path name as argument 0, +@code{dld_find_executable (argv[0]) } will also fail to locate the +executable file. +@end quotation + +@code{dld_find_executable} returns zero if @code{command} is not found +in any of the directories listed in @code{PATH}. +@end deftypefun + +@node Making SCM, Building SCM, Executable Pathname, Installing SCM +@section Making SCM + +The SCM distribution has @dfn{Makefile} which contains rules for making +@dfn{scmlit}, a ``bare-bones'' version of SCM sufficient for running +@file{build.scm}. @file{build.scm} is used to compile (or create +scripts to compile) full featured versions. + +Makefiles are not portable to the majority of platforms. If +@file{Makefile} works for you, good; If not, I don't want to hear about +it. If you need to compile SCM without build.scm, there are several +ways to proceed: + +@itemize @bullet +@item +Use SCM on a different platform to run @file{build.scm} to create a +script to build SCM; + +@item +Use another implementation of Scheme to run @file{build.scm} to create a +script to build SCM; + +@item +Create your own script or @file{Makefile}. + +@item +Buy a SCM executable from jaffer@@ai.mit.edu. See the end of the +@file{ANNOUNCE} file in the distribution for details. + +@item +Use scmconfig (From: bos@@scrg.cs.tcd.ie): + +Build and install scripts using GNU @dfn{autoconf} are available from +@file{scmconfig4e6.tar.gz} in the distribution directories. See +@file{README.unix} in @file{scmconfig4e6.tar.gz} for further +instructions. +@end itemize + + +@node Building SCM, SLIB, Making SCM, Installing SCM +@section Building SCM + +The file @dfn{build.scm} builds and runs a relational database of how to +compile and link SCM executables. It has information for most platforms +which SCM has been ported to (of which I have been notified). Some of +this information is old, incorrect, or incomplete. Send corrections and +additions to jaffer@@ai.mit.edu. + +@menu +* Invoking Build:: +* Build Options:: +@end menu + +@node Invoking Build, Build Options, Building SCM, Building SCM +@subsection Invoking Build + +The @emph{all} method will also work for MS-DOS and unix. Use +the @emph{all} method if you encounter problems with @file{build.scm}. + +@table @asis +@item MS-DOS +From the SCM source directory, type @samp{build} followed by up to 9 +command line arguments. + +@item unix +From the SCM source directory, type @samp{build.scm} followed by command +line arguments. + +@item @emph{all} +From the SCM source directory, start @samp{scm} or @samp{scmlit} and +type @code{(load "build.scm")}. Alternatively, start @samp{scm} or +@samp{scmlit} with the command line argument @samp{-ilbuild}. + +@end table + +@node Build Options, , Invoking Build, Building SCM +@subsection Build Options + +@noindent +The options to @dfn{build} specify what, where, and how to build a SCM +program or dynamically linked module. These options are unrelated to +the SCM command line options. + +@deffn {Build Option} -p @var{platform-name} +@deffnx {Build Option} ---platform=@var{platform-name} +specifies that the compilation should be for a computer/operating-system +combination called @var{platform-name}. @emph{Note:} The case of +@var{platform-name} is distinguised. The current @var{platform-name}s +are all lower-case. + +The platforms defined by table @dfn{platform} in @file{build.scm} are: +@end deffn +@example +name processor operating-system compiler +symbol processor-family operating-system symbol +symbol atom symbol symbol +================= ================= ================= ================= +*unknown* *unknown* unix *unknown* +acorn-unixlib acorn *unknown* *unknown* +aix powerpc aix *unknown* +amiga-aztec m68000 amiga aztec +amiga-dice-c m68000 amiga dice-c +amiga-sas/c-5.10 m68000 amiga sas/c +atari-st-gcc m68000 atari.st gcc +atari-st-turbo-c m68000 atari.st turbo-c +borland-c-3.1 8086 ms-dos borland-c +djgpp i386 ms-dos gcc +gcc *unknown* unix gcc +highc.31 i386 ms-dos highc +hp-ux hp-risc hp-ux *unknown* +linux i386 linux gcc +linux-elf i386 linux gcc +microsoft-c 8086 ms-dos microsoft-c +microsoft-c-nt i386 ms-dos microsoft-c +microsoft-quick-c 8086 ms-dos microsoft-quick-c +ms-dos 8086 ms-dos *unknown* +os/2-cset i386 os/2 c-set++ +os/2-emx i386 os/2 gcc +sun sparc sun-os *unknown* +svr4 *unknown* unix *unknown* +turbo-c-2 8086 ms-dos turbo-c +unicos cray unicos *unknown* +unix *unknown* unix *unknown* +vms vax vms *unknown* +vms-gcc vax vms gcc +watcom-9.0 i386 ms-dos watcom +@end example + +@deffn {Build Option} -o @var{filename} +@deffnx {Build Option} ---outname=@var{filename} +specifies that the compilation should produce an executable or object +name of @var{filename}. The default is @samp{scm}. Executable suffixes +will be added if neccessary, e.g. @samp{scm} @result{} @samp{scm.exe}. +@end deffn + +@deffn {Build Option} -l @var{libname} @dots{} +@deffnx {Build Option} ---libraries=@var{libname} +specifies that the @var{libname} should be linked with the executable +produced. If compile flags or include directories (@samp{-I}) are +needed, they are automatically supplied for compilations. The @samp{c} +library is always included. SCM @dfn{features} specify any libraries +they need; so you shouldn't need this option often. +@end deffn + +@deffn {Build Option} -D @var{definition} @dots{} +@deffnx {Build Option} ---defines=@var{definition} +specifies that the @var{definition} should be made in any C source +compilations. If compile flags or include directories (@samp{-I}) are +needed, they are automatically supplied for compilations. SCM +@dfn{features} specify any flags they need; so you shouldn't need this +option often. +@end deffn + +@deffn {Build Option} ---compiler-options=@var{flag} +specifies that that @var{flag} will be put on compiler command-lines. +@end deffn + +@deffn {Build Option} ---linker-options=@var{flag} +specifies that that @var{flag} will be put on linker command-lines. +@end deffn + +@deffn {Build Option} -s @var{pathname} +@deffnx {Build Option} ---scheme-initial=@var{pathname} +specifies that @var{pathname} should be the default location of the SCM +initialization file @file{Init.scm}. SCM tries several likely locations +before resorting to @var{pathname} (@pxref{File-System Habitat}). +If not specified, the current directory (where build is building) is +used. +@end deffn + +@deffn {Build Option} -c @var{pathname} @dots{} +@deffnx {Build Option} ---c-source-files=@var{pathname} +specifies that the C source files @var{pathname} @dots{} are to be +compiled. +@end deffn + +@deffn {Build Option} -j @var{pathname} @dots{} +@deffnx {Build Option} ---object-files=@var{pathname} +specifies that the object files @var{pathname} @dots{} are to be linked. +@end deffn + +@deffn {Build Option} -i @var{call} @dots{} +@deffnx {Build Option} ---initialization=@var{call} +specifies that the C functions @var{call} @dots{} are to be +invoked during initialization. +@end deffn + +@deffn {Build Option} -t @var{build-what} +@deffnx {Build Option} ---type=@var{build-what} +specifies in general terms what sort of thing to build. The choices +are: +@table @samp +@item exe +executable program. +@item lib +library module. +@item dlls +archived dynamically linked library object files. +@item dll +dynamically linked library object file. +@end table + +The default is to build an executable. +@end deffn + +@deffn {Build Option} -h @var{batch-syntax} +@deffnx {Build Option} --batch-dialect=@var{batch-syntax} +specifies how to build. The default is to create a batch file for the +host system. The SLIB file @file{batch.scm} knows how to create batch +files for: +@itemize @bullet +@item +unix +@item +dos +@item +vms +@item +system + +This option executes the compilation and linking commands through the +use of the @code{system} procedure. +@item +*unknown* + +This option outputs Scheme code. +@end itemize +@end deffn + +@deffn {Build Option} -w @var{batch-filename} +@deffnx {Build Option} --script-name=@var{batch-filename} +specifies where to write the build script. The default is to display it +on @code{(current-output-port)}. +@end deffn + +@deffn {Build Option} -F @var{feature} @dots{} +@deffnx {Build Option} ---features=@var{feature} +specifies to build the given features into the executable. The defined +features are: + +@table @dfn +@item lit +@itemx none +Lightweight -- no features + +@item cautious +Normally, the number of arguments arguments to interpreted closures + (from LAMBDA) are checked if the function part of a form is not a +symbol or only the first time the form is executed if the function part +is a symbol. defining @samp{reckless} disables any checking. If you +want to have SCM always check the number of arguments to interpreted +closures define feature @samp{cautious}. + +@item careful-interrupt-masking +Define this for extra checking of interrupt masking. This is for +debugging C code in @file{sys.c} and @file{repl.c}. + +@item debug +Turns on features @samp{cautious} @samp{careful-interrupt-masking} +@samp{stack-limit} and uses @code{-g} flags for debugging SCM source +code. + +@item reckless +If your scheme code runs without any errors you can disable almost all +error checking by compiling all files with @samp{reckless}. + +@item stack-limit +Use to enable checking for stack overflow. Define value of the C +preprocessor variable @var{STACK_LIMIT} to be the size to which SCM +should allow the stack to grow. STACK_LIMIT should be less than the +maximum size the hardware can support, as not every routine checks the +stack. + +@item bignums +Large precision integers. + +@item arrays +Use if you want arrays, uniform-arrays and uniform-vectors. + +@item array-for-each +array-map! and array-for-each (arrays must also be defined). + +@item inexact +Use if you want floating point numbers. + +@item engineering-notation +Use if you want floats to display in engineering notation (exponents +always multiples of 3) instead of scientific notation. + +@item single-precision-only +Use if you want all inexact real numbers to be single precision. This +only has an effect if SINGLES is also defined (which is the default). +This does not affect complex numbers. + +@item sicp +Use if you want to run code from: + +H. Abelson, G. J. Sussman, and J. Sussman, +Structure and Interpretation of Computer Programs, +The MIT Press, Cambridge, Massachusetts, USA + +@code{(eq? '() '#f)} is the major difference. + +@item rev2-procedures +These procedures were specified in the @cite{Revised^2 Report on Scheme} +but not in @cite{R4RS}. + +@item record +The Record package provides a facility for user to define their own +record data types. See SLIB for documentation. + +@item compiled-closure +Use if you want to use compiled closures. + +@item generalized-c-arguments +@code{make_gsubr} for arbitrary (< 11) arguments to C functions. + +@item tick-interrupts +Use if you want the ticks and ticks-interrupt functions. + +@item i/o-extensions +Commonly available I/O extensions: @dfn{exec}, line I/O, file +positioning, file delete and rename, and directory functions. + +@item turtlegr +@dfn{Turtle} graphics calls for both Borland-C and X11 from +sjm@@ee.tut.fi. + +@item curses +For the @dfn{curses} screen management package. + +@item edit-line +interface to the editline or GNU readline library. + +@item regex +String regular expression matching. + +@item socket +BSD @dfn{socket} interface. + +@item posix +Posix functions available on all @dfn{Unix-like} systems. fork and +process functions, user and group IDs, file permissions, and @dfn{link}. + +@item unix +Those unix features which have not made it into the Posix specs: nice, +acct, lstat, readlink, symlink, mknod and sync. + +@item windows +Microsoft Windows executable. + +@item dynamic-linking +Be able to load compiled files while running. + +@item dump +Convert a running scheme program into an executable file. + +@item heap-can-shrink +Use if you want segments of unused heap to not be freed up after garbage +collection. This may reduce time in GC for *very* large working sets. + +@item cheap-continuations +If you only need straight stack continuations, executables compile with +this feature will run faster and use less storage than not having it. +Machines with unusual stacks @emph{need} this. Also, if you incorporate +new C code into scm which uses VMS system services or library routines +(which need to unwind the stack in an ordrly manner) you may need to +use this feature. + +@item memoize-local-bindings +Saves the interpeter from having to look up local bindings for every +identifier reference + +@end table +@end deffn + +@node SLIB, Installing Dynamic Linking, Building SCM, Installing SCM +@section SLIB + +@noindent +[SLIB] is a portable Scheme library meant to provide compatibility and +utility functions for all standard Scheme implementations. Although +SLIB is not @emph{neccessary} to run SCM, I strongly suggest you obtain +and install it. Bug reports about running SCM without SLIB have very +low priority. SLIB is available from the same sites as SCM: + +@ifclear html +@itemize @bullet +@item +ftp-swiss.ai.mit.edu:/pub/scm/slib2a6.tar.gz +@item +prep.ai.mit.edu:/pub/gnu/jacal/slib2a6.tar.gz +@item +ftp.maths.tcd.ie:pub/bosullvn/jacal/slib2a6.tar.gz +@item +ftp.cs.indiana.edu:/pub/scheme-repository/imp/slib2a6.tar.gz +@end itemize +@end ifclear + +@ifset html +<A HREF="file://ftp-swiss.ai.mit.edu/pub/scm/slib2a6.tar.gz"> +ftp-swiss.ai.mit.edu:/pub/scm/slib2a6.tar.gz +</A> +<A HREF="file://prep.ai.mit.edu/pub/gnu/jacal/slib2a6.tar.gz"> +prep.ai.mit.edu:/pub/gnu/jacal/slib2a6.tar.gz +</A> +<A HREF="file://ftp.maths.tcd.ie/pub/bosullvn/jacal/slib2a6.tar.gz"> +ftp.maths.tcd.ie:pub/bosullvn/jacal/slib2a6.tar.gz +</A> +<A HREF="file://ftp.cs.indiana.edu/pub/scheme-repository/code/lib/slib2a6.tar.gz"> +ftp.cs.indiana.edu:/pub/scheme-repository/code/lib/slib2a6.tar.gz +</A> +@end ifset + +@noindent +Unpack SLIB (@samp{tar xzf slib2a6.tar.gz} or @samp{unzip -ao +slib2a6.zip}) in an appropriate directory for your system; both +@code{tar} and @code{unzip} will create the directory @file{slib}. + +@noindent +Then create a file @file{require.scm} in the SCM +@dfn{implementation-vicinity} (this is the same directory as where the +file @file{Init.scm} is installed). @file{require.scm} should have the +contents: + +@example +(define (library-vicinity) "/usr/local/lib/slib/") +(load (in-vicinity (library-vicinity) "require")) +@end example + +@noindent +where the pathname string @file{/usr/local/lib/slib/} is to be replaced +by the pathname into which you installed SLIB. Absolute pathnames are +recommended here; if you use a relative pathname, SLIB can get confused +when the working directory is changed (@pxref{I/O-Extensions, chmod}). +The way to specify a relative pathname is to append it to the +implementation-vicinity, which is absolute: + +@example +(define library-vicinity + (let ((lv (string-append (implementation-vicinity) "../slib/"))) + (lambda () lv))) +(load (in-vicinity (library-vicinity) "require")) +@end example + +@noindent +Alternatively, you can set the (shell) environment variable +@code{SCHEME_LIBRARY_PATH} to the pathname of the SLIB directory +(@pxref{SCM Variables, SCHEME_LIBRARY_PATH, Environment Variables}). If +set, the environment variable overrides @file{require.scm}. Again, +absolute pathnames are recommended. + + +@node Installing Dynamic Linking, Saving Images, SLIB, Installing SCM +@section Installing Dynamic Linking + +@noindent +Dynamic linking has not been ported to all platforms. Operating systems +in the BSD family (a.out binary format) can usually be ported to +@dfn{DLD}. The @dfn{dl} library (@code{#define SUN_DL} for SCM) was a +proposed POSIX standard and may be available on other machines with +@dfn{COFF} binary format. For notes about porting to MS-Windows and +finishing the port to VMS @ref{Finishing Dynamic Linking}. + +@noindent +@dfn{DLD} is a library package of C functions that performs @dfn{dynamic +link editing} on Linux, VAX (Ultrix), Sun 3 (SunOS 3.4 and 4.0), +SPARCstation (SunOS 4.0), Sequent Symmetry (Dynix), and Atari ST. It is +available from: + +@ifclear html +@itemize @bullet +@item +prep.ai.mit.edu:pub/gnu/dld-3.3.tar.gz +@end itemize +@end ifclear + +@ifset html +<A HREF="ftp://prep.ai.mit.edu/pub/gnu/dld-3.3.tar.gz"> +prep.ai.mit.edu:pub/gnu/dld-3.3.tar.gz +</A> +@end ifset + +@noindent +These notes about using libdl on SunOS are from @file{gcc.info}: + +@quotation +On a Sun, linking using GNU CC fails to find a shared library and +reports that the library doesn't exist at all. + +This happens if you are using the GNU linker, because it does only +static linking and looks only for unshared libraries. If you have +a shared library with no unshared counterpart, the GNU linker +won't find anything. + +We hope to make a linker which supports Sun shared libraries, but +please don't ask when it will be finished--we don't know. + +Sun forgot to include a static version of @file{libdl.a} with some +versions of SunOS (mainly 4.1). This results in undefined symbols when +linking static binaries (that is, if you use @samp{-static}). If you +see undefined symbols @samp{_dlclose}, @samp{_dlsym} or @samp{_dlopen} +when linking, compile and link against the file +@file{mit/util/misc/dlsym.c} from the MIT version of X windows. +@end quotation + + +@node Saving Images, Automatic C Preprocessor Definitions, Installing Dynamic Linking, Installing SCM +@section Saving Images + +@noindent +In SCM, the ability to save running program images is called @dfn{dump} +(@pxref{Dump}). In order to make @code{dump} available to SCM, build +with feature @samp{dump}. @code{dump}ed executables are compatible with +dynamic linking. + +@noindent +Most of the code for @dfn{dump} is taken from +@file{emacs-19.34/src/unex*.c}. No modifications to the emacs source +code were required to use @file{unexelf.c}. Dump has not been ported to +all platforms. If @file{unexec.c} or @file{unexelf.c} don't work for +you, try using the appropriate @file{unex*.c} file from emacs. + + + +@node Automatic C Preprocessor Definitions, Problems Compiling, Saving Images, Installing SCM +@section Automatic C Preprocessor Definitions + +These @samp{#defines} are automatically provided by preprocessors of +various C compilers. SCM uses the presence or absence of these +definitions to configure @dfn{include file} locations and aliases for +library functions. If the definition(s) corresponding to your system +type is missing as your system is configured, add @code{-D@var{flag}} to +the compilation command lines or add a @code{#define @var{flag}} line to +@file{scmfig.h} or the beginning of @file{scmfig.h}. + +@example +#define Platforms: +------- ---------- +ARM_ULIB Huw Rogers free unix library for acorn archimedes +AZTEC_C Aztec_C 5.2a +_DCC Dice C on AMIGA +__GNUC__ Gnu CC (and DJGPP) +__EMX__ Gnu C port (gcc/emx 0.8e) to OS/2 2.0 +__HIGHC__ MetaWare High C +__IBMC__ C-Set++ on OS/2 2.1 +_MSC_VER MS VisualC++ 4.2 +MWC Mark Williams C on COHERENT +_QC Microsoft QuickC +__STDC__ ANSI C compliant +__TURBOC__ Turbo C and Borland C +__WATCOMC__ Watcom C on MS-DOS +__ZTC__ Zortech C + +_AIX AIX operating system +AMIGA SAS/C 5.10 or Dice C on AMIGA +atarist ATARI-ST under Gnu CC +GNUDOS DJGPP (obsolete in version 1.08) +__GO32__ DJGPP (future?) +hpux HP-UX +linux Linux +MCH_AMIGA Aztec_c 5.2a on AMIGA +MSDOS Microsoft C 5.10 and 6.00A +__MSDOS__ Turbo C, Borland C, and DJGPP +nosve Control Data NOS/VE +SVR2 System V Revision 2. +THINK_C developement environment for the Macintosh +ultrix VAX with ULTRIX operating system. +unix most Unix and similar systems and DJGPP (!?) +__unix__ Gnu CC and DJGPP +_UNICOS Cray operating system +_Windows Borland C 3.1 compiling for Windows +_WIN32 MS VisualC++ 4.2 under Windows-NT +vms (and VMS) VAX-11 C under VMS. + +hp9000s800 HP RISC processor +__i386__ DJGPP +i386 DJGPP +MULTIMAX Encore computer +pyr Pyramid 9810 processor +sparc SPARC processor +sequent Sequent computer +tahoe CCI Tahoe processor +@end example + +@node Problems Compiling, Problems Linking, Automatic C Preprocessor Definitions, Installing SCM +@section Problems Compiling + +@table @asis +@item FILE: PROBLEM +HOW TO FIX +@item *.c: include file not found +Correct the status of STDC_HEADERS in @file{scmfig.h} + +fix #include statement or add #define for system type to +@file{scmfig.h}. +@item *.c: Function should return a value in @dots{} +@itemx *.c: Parameter '@dots{}' is never used in @dots{} +@itemx *.c: Condition is always false in @dots{} +@itemx *.c: Unreachable code in function @dots{} +Ignore. +@item scm.c: assignment between incompatible types +change SIGRETTYPE in @file{scm.c}. +@item time.c: CLK_TCK redefined +incompatablility between <stdlib.h> and <sys/types.h>. remove +STDC_HEADERS in @file{scmfig.h}. + +edit <sys/types.h> to remove incompatability. +@item subr.c: Possibly incorrect assignment in function lgcd +Ignore. +@item sys.c: statement not reached +@itemx sys.c: constant in conditional expression +ignore +@item sys.c: `???' undeclared, outside of functions +#undef STDC_HEADERS in @file{scmfig.h}. +@item scl.c: syntax error +#define SYSTNAME to your system type in @file{scl.c} (softtype) +@end table + +@node Problems Linking, Problems Running, Problems Compiling, Installing SCM +@section Problems Linking + +@table @asis +@item PROBLEM +HOW TO FIX +@item _sin etc. missing. +uncomment LIBS in makefile +@end table + +@node Problems Running, Testing, Problems Linking, Installing SCM +@section Problems Running + +@table @asis +@item PROBLEM +HOW TO FIX +@item Opening message and then machine crashes. +Change memory model option to C compiler (or makefile). + +Make sure @code{sizet} definition is correct in @file{scmfig.h}. + +Reduce size of HEAP_SEG_SIZE in @file{setjump.h}. +@item Input hangs +#define NOSETBUF +@item ERROR: heap: need larger initial +Need to increase the initial heap allocation using -a<kb> or +INIT_HEAP_SIZE. +@item ERROR: Could not allocate @dots{} +Check @code{sizet} definition. + +Use 32 bit compiler mode. + +Don't try to run as subproccess +@item remove @dots{} in scmfig.h and recompile scm +@itemx add @dots{} in scmfig.h and recompile scm +Do it and recompile files. +@item ERROR: @file{Init.scm} not found +Assign correct IMPLINIT in makefile or @file{scmfig.h} or define +environment variable @code{SCM_INIT_PATH} to be the full pathname of +@file{Init.scm} (@pxref{Installing SCM}). +@item WARNING: require.scm not found +define environment variable @code{SCHEME_LIBRARY_PATH} to be the full +pathname of the scheme library [SLIB] or change @code{library-vicinity} in +@file{Init.scm} to point to library or remove. @xref{Installation, , , slib, +SLIB}. + +Make sure the value of @code{(library-vicinity)} has a trailing file +separator (like @key{/} or @key{\}). +@end table + +@node Testing, Reporting Problems, Problems Running, Installing SCM +@section Testing + +@noindent +Loading @file{r4rstest.scm} in the distribution will run an [R4RS] +conformance test on @code{scm}. + +@example +> (load "r4rstest.scm") +@print{} +;loading "r4rstest.scm" +SECTION(2 1) +SECTION(3 4) + #<primitive-procedure boolean?> + #<primitive-procedure char?> + #<primitive-procedure null?> + #<primitive-procedure number?> +@dots{} +@end example + +@noindent +Loading @file{pi.scm} in the distribution will enable you to compute +digits of pi. + +@example +> (load "pi") +;loading "pi" +;done loading "pi.scm" +;Evaluation took 20 mSec (0 in gc) 767 cells work, 233 bytes other +#<unspecified> +> (pi 100 5) +00003 14159 26535 89793 23846 26433 83279 50288 41971 69399 +37510 58209 74944 59230 78164 06286 20899 86280 34825 34211 +70679 +;Evaluation took 550 mSec (60 in gc) 36976 cells work, 1548 bytes other +#<unspecified> +@end example + +@noindent +Loading @file{bench.scm} will compute and display performance statistics +of SCM running @file{pi.scm}. @samp{make bench} or @samp{make benchlit} +appends the performance report to the file @file{BenchLog}, facilitating +tracking effects of changes to SCM on performance. + +@table @asis +@item PROBLEM +HOW TO FIX +@item Runs some and then machine crashes. +See above under machine crashes. +@item Runs some and then ERROR: @dots{} (after a GC has happened) +Remove optimization option to C compiler and recompile. + +@code{#define SHORT_ALIGN} in @file{scmfig.h}. +@item Some symbol names print incorrectly. +Change memory model option to C compiler (or makefile). + +Check that @code{HEAP_SEG_SIZE} fits within @code{sizet}. + +Increase size of @code{HEAP_SEG_SIZE} (or @code{INIT_HEAP_SIZE} if it is +smaller than @code{HEAP_SEG_SIZE}). +@item ERROR: Rogue pointer in Heap. +See above under machine crashes. +@item Newlines don't appear correctly in output files. +Check file mode (define OPEN_@dots{} in @file{Init.scm} +@item Spaces or control characters appear in symbol names +Check character defines in @file{scmfig.h}. +@item Negative numbers turn positive. +Check SRS in @file{scmfig.h}. +@item VMS: Couldn't unwind stack +@itemx VAX: botched longjmp +@code{#define CHEAP_CONTIUATIONS} in @file{scmfig.h}. +@item Sparc(SUN-4) heap is growing out of control +You are experiencing a GC problem peculiar to the Sparc. The problem is +that SCM doesn't know how to clear register windows. Every location +which is not reused still gets marked at GC time. This causes lots of +stuff which should be collected to not be. This will be a problem with +any @emph{conservative} GC until we find what instruction will clear the +register windows. This problem is exacerbated by using lots of +call-with-current-continuations. +@end table + +@node Reporting Problems, , Testing, Installing SCM +@section Reporting Problems + +@noindent +Reported problems and solutions are grouped under Compiling, Linking, +Running, and Testing. If you don't find your problem listed there, you +can send a bug report to @code{jaffer@@ai.mit.edu}. The bug report +should include: + +@enumerate +@item +The version of SCM (printed when SCM is invoked with no arguments). +@item +The type of computer you are using. +@item +The name and version of your computer's operating system. +@item +The values of the environment variables @code{SCM_INIT_PATH} and +@code{SCHEME_LIBRARY_PATH}. +@item +The name and version of your C compiler. +@item +If you are using an executable from a distribution, the name, vendor, +and date of that distribution. In this case, corresponding with the +vendor is recommended. +@end enumerate + +@node The Language, Packages, Installing SCM, Top +@chapter The Language + +This section describes features which are either present in all builds +of SCM or which must be enabled when SCM is compiled. + +@menu +* Standards Compliance:: Links to sections in [R4RS] and [SLIB] +* System Interface:: Like how to exit +* Errors:: +* Memoized Expressions:: What #@@0+1 and #@@? mean +* Internal State:: GC, errors, and diagnostics +* Miscellaneous Procedures:: +* Time:: Both real time and processor time +* Interrupts:: and exceptions +* Process Synchronization:: Because interrupts are preemptive +* Files and Ports:: +* Soft Ports:: Emulate I/O devices +* Syntax Extensions:: and how to Define New Syntax +* Low Level Syntactic Hooks:: +@end menu + +@node Standards Compliance, System Interface, The Language, The Language +@section Standards Compliance + +@noindent +Scm conforms to the +@ifset html +[IEEE], +@end ifset +@cite{IEEE Standard 1178-1990. IEEE Standard for the Scheme Programming +Language.} +@ifclear html +(@pxref{Bibliography}), +@end ifclear +and +@ifset html +[R4RS], <A HREF="r4rs_toc.html"> +@end ifset +@cite{Revised(4) Report on the Algorithmic Language Scheme}. +@ifset html +</A> +@end ifset +@ifinfo +@ref{Top, , , r4rs, Revised(4) Report on the Algorithmic Language +Scheme}. +@end ifinfo +All the required features of these specifications are supported. +Many of the optional features are supported as well. + +@subheading Optionals of [R4RS] Supported by SCM + +@table @asis +@item two clause @code{if}: @code{(if <test> <consequent>)} +@xref{Conditionals, , , r4rs, Revised(4) Scheme}. +@item @code{let*} +@itemx named @code{let} +@xref{Binding constructs, , , r4rs, Revised(4) Scheme}. +@item @code{do} +@xref{Iteration, , , r4rs, Revised(4) Scheme}. +@item All varieties of @code{define} +@xref{Definitions, , , r4rs, Revised(4) Scheme}. +@item @code{list-tail} +@xref{Pairs and lists, , , r4rs, Revised(4) Scheme}. +@item @code{string-copy} +@itemx @code{string-fill!} +@xref{Strings, , , r4rs, Revised(4) Scheme}. +@item @code{make-vector} of two arguments +@itemx @code{vector-fill!} +@xref{Vectors, , , r4rs, Revised(4) Scheme}. +@item @code{apply} of more than 2 arguments +@xref{Control features, , , r4rs, Revised(4) Scheme}. +@item @code{-} and @code{/} of more than 2 arguments +@itemx @code{exp} +@itemx @code{log} +@itemx @code{sin} +@itemx @code{cos} +@itemx @code{tan} +@itemx @code{asin} +@itemx @code{acos} +@itemx @code{atan} +@itemx @code{sqrt} +@itemx @code{expt} +@itemx @code{make-rectangular} +@itemx @code{make-polar} +@itemx @code{real-part} +@itemx @code{imag-part} +@itemx @code{magnitude} +@itemx @code{angle} +@itemx @code{exact->inexact} +@itemx @code{inexact->exact} +@xref{Numerical operations, , , r4rs, Revised(4) Scheme}. +@item @code{delay} +@itemx @code{force} +@xref{Control features, , , r4rs, Revised(4) Scheme}. +@itemx @code{with-input-from-file} +@itemx @code{with-output-to-file} +@xref{Ports, , , r4rs, Revised(4) Scheme}. +@itemx @code{char-ready?} +@xref{Input, , , r4rs, Revised(4) Scheme}. +@itemx @code{transcript-on} +@itemx @code{transcript-off} +@xref{System interface, , , r4rs, Revised(4) Scheme}. +@end table + +@subheading Optionals of [R4RS] not Supported by SCM + +@table @asis +@item @code{numerator} +@itemx @code{denominator} +@itemx @code{rationalize} +@xref{Numerical operations, , , r4rs, Revised(4) Scheme}. +@item [R4RS] appendix Macros +@xref{Macros, , , r4rs, Revised(4) Scheme}. +@end table + +@subheading [SLIB] Features of SCM and SCMLIT + +@table @code +@item delay +@itemx full-continuation +@itemx ieee-p1178 +@itemx object-hash +@itemx rev4-report +@itemx source +See SLIB file @file{Template.scm}. +@item current-time +@xref{Time, , , slib, SLIB}. +@item defmacro +@xref{Defmacro, , , slib, SLIB}. +@item dynamic-wind +@xref{Dynamic-Wind, , , slib, SLIB}. +@item eval +@xref{System, , , slib, SLIB}. +@item getenv +@itemx system +@xref{System Interface, , , slib, SLIB}. +@item hash +@xref{Hashing, , , slib, SLIB}. +@item logical +@xref{Bit-Twiddling, , , slib, SLIB}. +@item multiarg-apply +@xref{Multi-argument Apply, , , slib, SLIB}. +@item multiarg/and- +@xref{Multi-argument / and -, , , slib, SLIB}. +@item rev4-optional-procedures +@xref{Rev4 Optional Procedures, , , slib, SLIB}. +@item string-port +@xref{String Ports, , , slib, SLIB}. +@item tmpnam +@xref{Input/Output, , , slib, SLIB}. +@item transcript +@xref{Transcripts, , , slib, SLIB}. +@item vicinity +@xref{Vicinity, , , slib, SLIB}. +@item with-file +@xref{With-File, , , slib, SLIB}. +@end table + +@subheading [SLIB] Features of SCM + +@table @code +@item array +@xref{Arrays, , , slib, SLIB}. +@item array-for-each +@xref{Array Mapping, , , slib, SLIB}. +@item bignum +@itemx complex +@itemx inexact +@itemx rational +@itemx real +@xref{Require, , , slib, SLIB}. +@end table + +@node System Interface, Errors, Standards Compliance, The Language +@section System Interface + +@noindent +For documentation of the procedures @code{getenv} and @code{system} +@xref{System Interface, , , slib, SLIB}. + +@defun quit +@defunx quit n +@defunx exit +@defunx exit n +Aliases for @code{exit} (@pxref{System, exit, , slib, SLIB}). On many +systems, SCM can also tail-call another program. @xref{I/O-Extensions, +execp}. +@end defun + +@defun vms-debug +If SCM is compiled under VMS these commands will invoke the editor or +debugger respectively. +@end defun + +@defun ed filename +If SCM is compiled under VMS @code{ed} will invoke the editor with a +single the single argument @var{filename}. + +@defunx ed arg1 @dots{} +Otherwise, the value of the environment variable @code{EDITOR} (or just +@code{ed} if it isn't defined) is invoked as a command with arguments +@var{arg1} @dots{}. +@end defun + +@defun program-arguments +Returns a list of strings of the arguments scm was called with. +@end defun + +@defun errno +@defunx errno n +With no argument returns the current value of the system variable +@code{errno}. When given an argument, @code{errno} sets the system +variable @code{errno} to @var{n} and returns the previous value of +@code{errno}. @code{(errno 0)} will clear outstanding errors. This is +recommended after @code{try-load} returns @code{#f} since this occurs +when the file could not be opened. +@end defun + +@defun perror string +Prints on standard error output the argument @var{string}, a colon, +followed by a space, the error message corresponding to the current +value of @code{errno} and a newline. The value returned is unspecified. +@end defun + +@node Errors, Memoized Expressions, System Interface, The Language +@section Errors + +@noindent +A computer-language implementation designer faces choices of how +reflexive to make the implementation in handling exceptions and errors; +that is, how much of the error and exception routines should be written +in the language itself. The design of a portable implementation is +further constrained by the need to have (almost) all errors print +meaningful messages, even when the implementation itself is not +functioning correctly. Therefore, SCM implements much of its error +response code in C. + +@noindent +The following common error and conditions are handled by C code. Those +with callback names after them can also be handled by Scheme code +(@pxref{Interrupts}). If the callback identifier is not defined at top +level, the default error handler (C code) is invoked. There are many +other error messages which are not treated specially. + +@enumerate 0 +@item +Wrong type in arg 0 +@item +Wrong type in arg 1 +@item +Wrong type in arg 2 +@item +Wrong type in arg 3 +@item +Wrong type in arg 4 +@item +Wrong type in arg 5 +@item +Wrong number of args +@item +numerical overflow +@item +Argument out of range +@item +Could not allocate @code{(out-of-storage)} +@item +EXIT @code{(end-of-program)} +@item +hang up @code{(hang-up)} +@item +user interrupt @code{(user-interrupt)} +@item +arithmetic error @code{(arithmetic-error)} +@item +bus error +@item +segment violation +@item +alarm @code{(alarm-interrupt)} +@end enumerate + +@defvar errobj +If SCM encounters a non-fatal error it aborts evaluation of the current +form, prints a message explaining the error, and resumes the top level +read-eval-print loop. The value of @var{errobj} is the offending object +if appropriate. The builtin procedure @code{error} does @emph{not} set +@var{errobj}. +@end defvar + +@defun error arg1 arg2 arg3 @dots{} +Alias for @ref{System, error, , slib, SLIB}. Outputs an error message +containing the arguments, aborts evaluation of the current form and +resumes the top level read-eval-print loop. Error is defined in +@file{Init.scm}; Feel free to redefine it to suit your purposes. +@end defun + +@subsection CAUTIOUS enhancements + +@noindent +If SCM is built with the @samp{CAUTIOUS} flag, then when an error +occurs, a @dfn{stack trace} of certain pending calls are printed as part +of the default error response. A (memoized) expression and newline are +printed for each partially evaluated combination whose procedure is not +builtin. @xref{Memoized Expressions} for how to read memoized +expressions. + +@noindent +Also as the result of the @samp{CAUTIOUS} flag, both @code{error} and +@code{user-interrupt} (invoked by @key{C-c}) are defined to print stack +traces and conclude by calling @code{breakpoint} (@pxref{Breakpoints, , +, slib, SLIB}). This allows the user to interract with SCM as with Lisp +systems. + +@defun stack-trace +Prints information describing the stack of partially evaluated +expressions. @code{stack-trace} returns @code{#t} if any lines were +printed and @code{#f} otherwise. See @file{Init.scm} for an example of +the use of @code{stack-trace}. +@end defun + +@node Memoized Expressions, Internal State, Errors, The Language +@section Memoized Expressions + +@noindent +SCM memoizes the address of each occurence of an identifier's value when +first encountering it in a source expression. Subsequent executions of +that memoized expression is faster because the memoized reference +encodes where in the top-level or local environment its value is. + +@noindent +When procedures are displayed, the memoized locations appear in a format +different from references which have not yet been executed. I find this +a convenient aid to locating bugs and untested expressions. + +@itemize @bullet +@item +The names of memoized lexically bound identifiers are replaced with +@r{#@@}@i{<m>}@r{-}@i{<n>}, where @i{<m>} is the number of binding +contours back and @i{<n>} is the index of the value in that +binding countour. +@item +The names of identifiers which are not lexiallly bound but defined at +top-level have @r{#@@} prepended. +@end itemize + +@noindent +For instance, @code{open-input-file} is defined as follows in +@file{Init.scm}: + +@example +(define (open-input-file str) + (or (open-file str OPEN_READ) + (and (procedure? could-not-open) (could-not-open) #f) + (error "OPEN-INPUT-FILE couldn't open file " str))) +@end example + +@noindent +If @code{open-input-file} has not yet been used, the displayed procedure +is similar to the original definition (lines wrapped for readability): + +@example +open-input-file @result{} +#<CLOSURE (str) (or (open-file str open_read) + (and (procedure? could-not-open) (could-not-open) #f) + (error "OPEN-INPUT-FILE couldn't open file " str))> +@end example + +@noindent +If we open a file using @code{open-input-file}, the sections of code +used become memoized: + +@example +(open-input-file "r4rstest.scm") @result{} #<input-port 3> +open-input-file @result{} +#<CLOSURE (str) (#@@or (#@@open-file #@@0+0 #@@open_read) + (and (procedure? could-not-open) (could-not-open) #f) + (error "OPEN-INPUT-FILE couldn't open file " str))> +@end example + +@noindent +If we cause @code{open-input-file} to execute other sections of code, +they too become memoized: + +@example +(open-input-file "foo.scm") @result{} + +ERROR: No such file or directory +ERROR: OPEN-INPUT-FILE couldn't open file "foo.scm" + +open-input-file @result{} +#<CLOSURE (str) (#@@or (#@@open-file #@@0+0 #@@open_read) + (#@@and (#@@procedure? #@@could-not-open) (could-not-open) #f) + (#@@error "OPEN-INPUT-FILE couldn't open file " #@@0+0))> +@end example + + +@node Internal State, Miscellaneous Procedures, Memoized Expressions, The Language +@section Internal State + +@defvar *interactive* +The variable @var{*interactive*} determines whether the SCM session is +interactive, or should quit after the command line is processed. +@var{*interactive*} is controlled directly by the command-line options +@samp{-b}, @samp{-i}, and @samp{-s} (@pxref{Invoking SCM}). If none of +these options are specified, the rules to determine interactivity are +more complicated; see @file{Init.scm} for details. +@end defvar + +@defun abort +Resumes the top level Read-Eval-Print loop. +@end defun + +@defun restart +Restarts the SCM program with the same arguments as it was originally +invoked. All @samp{-l} loaded files are loaded again; If those files +have changed, those changes will be reflected in the new session. + +@emph{Note:} When running a saved executable (@pxref{Dump}), +@code{restart} is redefined to be @code{exec-self}. +@end defun + +@defun exec-self +Exits and immediately re-invokes the same executable with the same +arguments. If the executable file has been changed or replaced since +the beginning of the current session, the @emph{new} executable will be +invoked. This differentiates @code{exec-self} from @code{restart}. +@end defun + +@defun verbose n +Controls how much monitoring information is printed. +If @var{n} is: + +@table @asis +@item 0 +no prompt or information is printed. +@item >= 1 +a prompt is printed. +@item >= 2 +the CPU time is printed after each top level form evaluated. +@item >= 3 +messages about heap growth are printed. +@item >= 4 +garbage collection (@pxref{Garbage Collection}) messages are printed. +@item >= 5 +a warning will be printed for each top-level symbol which is defined +more than one time. +@end table +@end defun + +@defun gc +Scans all of SCM objects and reclaims for further use those that are +no longer accessible. +@end defun + +@defun room +@defunx room #t +Prints out statistics about SCM's current use of storage. @code{(room #t)} +also gives the hexadecimal heap segment and stack bounds. +@end defun + +@defvr Constant *scm-version* +Contains the version string (e.g. @file{4e6}) of SCM. +@end defvr + +@noindent +For other configuration constants and procedures @xref{Configuration, , +, slib, SLIB}. + +@node Miscellaneous Procedures, Time, Internal State, The Language +@section Miscellaneous Procedures + +@defun try-load filename +If the string @var{filename} names an existing file, the try-load +procedure reads Scheme source code expressions and definitions from the +file and evaluates them sequentially and returns @code{#t}. If not, +try-load returns @code{#f}. The try-load procedure does not affect the +values returned by @code{current-input-port} and +@code{current-output-port}. +@end defun + +@defvar *load-pathname* +Is set to the pathname given as argument to @code{load}, +@code{try-load}, and @code{dyn:link} (@pxref{Compiling And Linking}). +@code{*load-pathname*} is used to compute the value of @ref{Vicinity, +program-vicinity, , slib, SLIB}. +@end defvar + +@defun line-number +Returns the current line number of the file currently being loaded. +@end defun + +@defun eval obj +Alias for @ref{System, eval, , slib, SLIB}. +@end defun + +@defun eval-string str +Returns the result of reading an expression from @var{str} and +evaluating it. @code{eval-string} does not change +@code{*load-pathname*} or @code{line-number}. +@end defun + +@defun load-string str +Reads and evaluates all the expressions from @var{str}. As with +@code{load}, the value returned is unspecified. @code{eval-string} does +not change @code{*load-pathname*} or @code{line-number}. +@end defun + +@defun vector-set-length! object length +Change the length of string, vector, bit-vector, or uniform-array +@var{object} to @var{length}. If this shortens @var{object} then the +remaining contents are lost. If it enlarges @var{object} then the +contents of the extended part are undefined but the original part is +unchanged. It is an error to change the length of literal datums. The +new object is returned. +@end defun + +@defun copy-tree obj +@xref{Tree Operations, copy-tree, , slib, SLIB}. This extends the SLIB +version by also copying vectors. +@end defun + +@defun acons obj1 obj2 obj3 +Returns (cons (cons obj1 obj2) obj3). The expression (set! a-list +(acons key datum a-list)) adds a new association to a-list. +@end defun + +@defun terms +This command displays the GNU General Public License. +@end defun + +@defun list-file filename +Displays the text contents of @var{filename}. +@end defun + +@deffn Procedure print arg1 ... +@code{Print} writes all its arguments, separated by spaces. +@code{Print} outputs a @code{newline} at the end and returns the value +of the last argument. +@end deffn + +@node Time, Interrupts, Miscellaneous Procedures, The Language +@section Time + +@defvr Constant internal-time-units-per-second + +Is the integer number of internal time units in a second. +@end defvr + +@defun get-internal-run-time +Returns the integer run time in internal time units from an unspecified +starting time. The difference of two calls to +@code{get-internal-run-time} divided by +@code{internal-time-units-per-second} will give elapsed run time in +seconds. +@end defun + +@defun get-internal-real-time +Returns the integer time in internal time units from an unspecified +starting time. The difference of two calls to +@code{get-internal-real-time} divided by +@code{interal-time-units-per-second} will give elapsed real time in +seconds. +@end defun + +@defun current-time +Returns the time since 00:00:00 GMT, January 1, 1970, measured in +seconds. @xref{Time, current-time, , slib, SLIB}. @code{current-time} is +used in @ref{Time, , , slib, SLIB}. +@end defun + +@node Interrupts, Process Synchronization, Time, The Language +@section Interrupts + +@defun ticks n +Returns the number of ticks remaining till the next tick interrupt. +Ticks are an arbitrary unit of evaluation. Ticks can vary greatly in +the amount of time they represent. + +If @var{n} is 0, any ticks request is canceled. Otherwise a +@code{ticks-interrupt} will be signaled @var{n} from the current time. +@code{ticks} is supported if SCM is compiled with the @code{ticks} flag +defined. +@end defun + +@deffn {Callback procedure} ticks-interrupt @dots{} +Establishes a response for tick interrupts. Another tick interrupt will +not occur unless @code{ticks} is called again. Program execution will +resume if the handler returns. This procedure should (abort) or some +other action which does not return if it does not want processing to +continue. +@end deffn + +@defun alarm secs +Returns the number of seconds remaining till the next alarm interrupt. +If @var{secs} is 0, any alarm request is canceled. Otherwise an +@code{alarm-interrupt} will be signaled @var{secs} from the current +time. ALARM is not supported on all systems. +@end defun + +@deffn {Callback procedure} user-interrupt @dots{} +@deffnx {Callback procedure} alarm-interrupt @dots{} +Establishes a response for @code{SIGINT} (control-C interrupt) and +@code{SIGALRM} interrupts. Program execution will resume if the handler +returns. This procedure should @code{(abort)} or some other action +which does not return if it does not want processing to continue after +it returns. + +Interrupt handlers are disabled during execution @code{system} and +@code{ed} procedures. + +To unestablish a response for an interrupt set the handler symbol to +@code{#f}. For instance, @code{(set! user-interrupt #f)}. +@end deffn + +@deffn {Callback procedure} out-of-storage @dots{} +@deffnx {Callback procedure} could-not-open @dots{} +@deffnx {Callback procedure} end-of-program @dots{} +@deffnx {Callback procedure} hang-up @dots{} +@deffnx {Callback procedure} arithmetic-error @dots{} +Establishes a response for storage allocation error, file opening +error, end of program, SIGHUP (hang up interrupt) and arithmetic +errors respectively. This procedure should (abort) or some other +action which does not return if it does not want the default error +message to also be displayed. If no procedure is defined for @var{hang-up} +then @var{end-of-program} (if defined) will be called. + +To unestablish a response for an error set the handler symbol to +@code{#f}. For instance, @code{(set! could-not-open #f)}. +@end deffn + +@node Process Synchronization, Files and Ports, Interrupts, The Language +@section Process Synchronization + +@defun make-arbiter name + +Returns an object of type arbiter and name @var{name}. Its state is +initially unlocked. +@end defun + +@defun try-arbiter arbiter + +Returns @code{#t} and locks @var{arbiter} if @var{arbiter} was unlocked. +Otherwise, returns @code{#f}. +@end defun + +@defun release-arbiter arbiter + +Returns @code{#t} and unlocks @var{arbiter} if @var{arbiter} was locked. +Otherwise, returns @code{#f}. +@end defun + +@node Files and Ports, Soft Ports, Process Synchronization, The Language +@section Files and Ports + +@noindent +These procedures generalize and extend the standard capabilities in +@ref{Ports, , ,r4rs, Revised(4) Scheme}. + +@defun open-file string modes +Returns a port capable of receiving or delivering characters as +specified by the @var{modes} string. If a file cannot be opened +@code{#f} is returned. +@end defun + +@defvr Constant open_read +@defvrx Constant open_write +@defvrx Constant open_both +Contain modes strings specifying that a file is to be opened for +reading, writing, and both reading and writing respectively. +@end defvr + +@defun _ionbf modestr +Returns a version of modestr which when open-file is called with it as +the second argument will return an unbuffered port. A non-file +input-port must be unbuffered in order for char-ready? to work correctly +on it. The initial value of (current-input-port) is unbuffered if the +platform supports it. +@end defun + +@defun close-port port +Closes @var{port}. The same as close-input-port and close-output-port. +@end defun + +@defun open-io-file filename +@defunx close-io-port port +These functions are analogous to the standard scheme file functions. +The ports are open to @var{filename} in read/write mode. Both input and +output functions can be used with io-ports. An end of file must be read +or a file-set-position done on the port between a read operation and a +write operation or vice-versa. +@end defun + +@defun current-error-port +Returns the current port to which diagnostic output is directed. +@end defun + +@defun with-error-to-file string thunk +@var{thunk} must be a procedure of no arguments, and string must be a +string naming a file. The file is opened for output, an output port +connected to it is made the default value returned by +current-error-port, and the @var{thunk} is called with no arguments. When +the thunk returns, the port is closed and the previous default is +restored. With-error-to-file returns the value yielded by @var{thunk}. +@end defun + +@defun with-input-from-port port thunk +@defunx with-output-to-port port thunk +@defunx with-error-to-port port thunk +These routines differ from with-input-from-file, with-output-to-file, +and with-error-to-file in that the first argument is a port, rather +than a string naming a file. +@end defun + +@deffn {procedure} char-ready? +@deffnx {procedure} char-ready? port + +Returns @code{#t} if a character is ready on the input @var{port} and +returns @code{#f} otherwise. If @code{char-ready?} returns @code{#t} +then +@findex char-ready +the next @code{read-char} operation on the given @var{port} is +guaranteed +@findex read-char +not to hang. If the @var{port} is at end of file then +@code{char-ready?} returns @code{#t}. +@findex char-ready? +@var{Port} may be omitted, in which case it defaults to +the value returned by @code{current-input-port}. +@findex current-input-port + +@emph{Rationale:} @code{Char-ready?} exists to make it possible for a program to +@findex char-ready? +accept characters from interactive ports without getting stuck waiting +for input. Any input editors associated with such ports must ensure +that characters whose existence has been asserted by @code{char-ready?} +@findex char-ready? +cannot be rubbed out. If @code{char-ready?} were to return @code{#f} at +end of file, a port at end of file would be indistinguishable from an +interactive port that has no ready characters. +@c end rationale +@end deffn + + +@node Soft Ports, Syntax Extensions, Files and Ports, The Language +@section Soft Ports + +@noindent +A @dfn{soft-port} is a port based on a vector of procedures capable of +accepting or delivering characters. It allows emulation of I/O ports. + +@defun make-soft-port vector modes +Returns a port capable of receiving or delivering characters as +specified by the @var{modes} string (@pxref{Files and Ports, +open-file}). @var{vector} must be a vector of length 6. Its components +are as follows: + +@enumerate 0 +@item +procedure accepting one character for output +@item +procedure accepting a string for output +@item +thunk for flushing output +@item +thunk for getting one character +@item +thunk for closing port (not by garbage collection) +@end enumerate + +For an output-only port only elements 0, 1, 2, and 4 need be +procedures. For an input-only port only elements 3 and 4 need be +procedures. Thunks 2 and 4 can instead be @code{#f} if there is no useful +operation for them to perform. + +If thunk 3 returns @code{#f} or an @code{eof-object} (@pxref{Input, +eof-object?, ,r4rs, Revised(4) Scheme}) it indicates that the port has +reached end-of-file. For example: + +@example +(define stdout (current-output-port)) +(define p (make-soft-port + (vector + (lambda (c) (write c stdout)) + (lambda (s) (display s stdout)) + (lambda () (display "." stdout)) + (lambda () (char-upcase (read-char))) + (lambda () (display "@@" stdout))) + "rw")) + +(write p p) @result{} #<input-output-soft#\space45d10#\> +@end example +@end defun + +@node Syntax Extensions, Low Level Syntactic Hooks, Soft Ports, The Language +@section Syntax Extensions + +@deffn {Read syntax} #. expression +Is read as the object resulting from the evaluation of @var{expression}. +This substitution occurs even inside quoted structure. + +In order to allow compiled code to work with @code{#.} it is good +practice to define those symbols used inside of @var{expression} with +@code{#.(define @dots{})}. For example: + +@example +#.(define foo 9) @result{} #<unspecified> +'(#.foo #.(+ foo foo)) @result{} (9 18) +@end example +@end deffn + +@deffn {Read syntax} #+ feature form +If feature is @code{provided?} (by @code{*features*}) then @var{form} is +read as a scheme expression. If not, then @var{form} is treated as +whitespace. + +Feature is a boolean expression composed of symbols and @code{and}, +@code{or}, and @code{not} of boolean expressions. + +For more information on @code{provided?} and @code{*features*}, +@xref{Require, , , slib, SLIB}. +@end deffn + +@deffn {Read syntax} #- feature form +is equivalent to @code{#+(not feature) expression}. +@end deffn + +@deffn {Read syntax} #' form +is equivalent to @var{form} (for compatibility with common-lisp). +@end deffn + +@deffn {Read syntax} #| any thing |# +Is a balanced comment. Everything up to the matching @code{|#} is +ignored by the @code{read}. Nested @code{#|@dots{}|#} can occur inside +@var{any thing}. +@end deffn + +@deffn {Read syntax} #! any thing +On the first line of a file will be ignored when loaded by SCM. This +makes SCM files usable as POSIX shell scripts if the first line is: + +@example +#!/usr/local/bin/scm +@end example + +When such a file is invoked it executes /usr/local/bin/scm with the +name of this file as the first argument. The following shell script +will print factorial of its argument: +@example +#!/usr/local/bin/scm +;;; -*-scheme-*- tells emacs this is a scheme file. +(define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n))))) +(display (fact (string->number (caddr (program-arguments))))) +(newline) +(quit) +@end example + +This technique has some drawbacks: +@itemize @bullet +@item +Some Unixes limit the length of the @samp{#!} interpreter line to the +size of an object file header, which can be as small as 32 bytes. +@item +A full, explicit pathname must be specified, perhaps requiring more than +32 bytes and making scripts vulnerable to programs being moved. +@end itemize + +The following approach solves both problems -- at the expense of +slightly slower startup. @code{type;} should appear on every line to be +executed by the shell. These lines do not have the length restriction +mentioned above. Also, @code{/bin/sh} searches the directories listed +in the `PATH' environment variable for @samp{scm}, eliminating the need +to know absolute locations in order to invoke a program. +@example +#!/bin/sh +type;exec scm $0 $* +;;; -*-scheme-*- tells emacs this is a scheme file. +(define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n))))) +(display (fact (string->number (caddr (program-arguments))))) +(newline) +(quit) +@end example +@end deffn + +@defspec defined? symbol +Equivalent to @code{#t} if @var{symbol} is a syntactic keyword (such as +@code{if}) or a symbol with a value in the top level environment +(@pxref{Variables and regions, , ,r4rs, Revised(4) Scheme}). Otherwise +equivalent to @code{#f}. +@end defspec + +@defspec defvar identifier initial-value +If @var{identifier} is unbound in the top level environment, then +@var{identifier} is @code{define}d to the result of evaluating the form +@var{initial-value} as if the @code{defvar} form were instead the form +@code{(define identifier initial-value)} . If @var{identifier} already +has a value, then @var{initial-value} is @emph{not} evaluated and +@var{identifier}'s value is not changed. +@end defspec + +@noindent +SCM also supports the following constructs from Common Lisp: +@code{defmacro}, @code{macroexpand}, @code{macroexpand-1}, and +@code{gentemp}. @xref{Defmacro, , , slib, SLIB}. + + +@node Low Level Syntactic Hooks, , Syntax Extensions, The Language +@section Low Level Syntactic Hooks + +@deffn {Callback procedure} read:sharp c port +If a @key{#} followed by a character (for a non-standard syntax) is +encountered by @code{read}, @code{read} will call the value of the +symbol @code{read:sharp} with arguments the character and the port being +read from. The value returned by this function will be the value of +@code{read} for this expression unless the function returns +@code{#<unspecified>} in which case the expression will be treated as +whitespace. @code{#<unspecified>} is the value returned by the +expression @code{(if #f #f)}. + +@emph{Note:} When adding new @key{#} syntaxes, have your code save the +previous value of @code{read:sharp} when defining it. Call this saved +value if an invocation's syntax is not recognized. This will allow +@code{#+}, @code{#-}, @code{#!}, and @ref{Uniform Array}s to still be +supported (as they use @code{read:sharp}). +@end deffn + +@defun procedure->syntax proc +Returns a @dfn{macro} which, when a symbol defined to this value appears +as the first symbol in an expression, returns the result of applying +@var{proc} to the expression and the environment. +@end defun + +@defun procedure->macro proc +@defunx procedure->memoizing-macro proc +Returns a @dfn{macro} which, when a symbol defined to this value appears +as the first symbol in an expression, evaluates the result of applying +@var{proc} to the expression and the environment. The value returned +from @var{proc} which has been passed to +@code{PROCEDURE->MEMOIZING-MACRO} replaces the form passed to +@var{proc}. For example: + +@example +(define trace + (procedure->macro + (lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x)))))) + +(trace @i{foo}) @equiv{} (set! @i{foo} (tracef @i{foo} '@i{foo})). +@end example + +An @dfn{environment} is a list of @dfn{environment frames}. There are 2 +types of environment frames: + +@table @code +@item ((lambda (variable1 @dots{}) @dots{}) value1 @dots{}) +@itemx (let ((variable1 value1) (variable2 value2) @dots{}) @dots{}) +@itemx (letrec ((variable1 value1) @dots{}) @dots{}) +result in a single enviroment frame: +@example +((variable1 @dots{}) value1 @dots{}) +@end example + +@item (let ((variable1 value1)) @dots{}) +@itemx (let* ((variable1 value1) @dots{}) @dots{}) +result in an environment frame for each variable: +@example +(variable1 . value1) (variable2 . value2) @dots{} +@end example +@end table +@end defun + +@defspec @@apply procedure argument-list +Returns the result of applying procedure to argument-list. (apply +procedure argument-list) will produce the same result. +@end defspec + +@defspec @@call-with-current-continuation procedure) +Returns the result of applying @var{procedure} to the current +continuation. A @dfn{continuation} is a SCM object of type +@code{contin} (@pxref{Continuations}). The procedure +@code{(call-with-current-continuation @var{procedure})} is defined to +have the same effect as @code{(@@call-with-current-continuation +procedure)}. +@end defspec + + +@node Packages, The Implementation, The Language, Top +@chapter Packages + +@menu +* Executable path:: +* Compiling And Linking:: Hobbit and Dynamic Linking +* Dynamic Linking:: +* Dump:: Create Fast-Booting Executables +* Numeric:: Numeric Language Extensions +* Arrays:: As in APL +* I/O-Extensions:: 'i/o-extensions +* Posix Extensions:: 'posix +* Regular Expression Pattern Matching:: 'regex +* Line Editing:: 'edit-line +* Curses:: Screen Control +* Sockets:: Cruise the Net +@end menu + +@node Executable path, Compiling And Linking, Packages, Packages +@section Executable path + +In order to dump a saved executable or to dynamically-link using DLD, +SCM must know where its executable file is. Sometimes SCM +(@pxref{Executable Pathname}) guesses incorrectly the location of the +currently running executable. In that case, the correct path can be set +by calling @code{execpath} with the pathname. + +@defun execpath +Returns the path (string) which SCM uses to find the executable file +whose invocation the currently running session is, or #f if the path is +not set. +@defunx execpath #f +@defunx execpath newpath +Sets the path to @code{#f} or @var{newpath}, respectively. The old path +is returned. +@end defun + +@node Compiling And Linking, Dynamic Linking, Executable path, Packages +@section Compiling And Linking + +@defun compile-file name1 name2 @dots{} +If the HOBBIT compiler is installed in the +@code{(implementation-vicinity)}, compiles the files @var{name1} +@var{name2} @dots{} to an object file name @var{name1}<object-suffix>, +where <object-suffix> is the object file suffix for your computer (for +instance, @file{.o}). @var{name1} must be in the current directory; +@var{name2} @dots{} can be in other directories. +@end defun + +@defun link-named-scm name module1 @dots{} +Creates a new SCM executable with name @var{name}. @var{name} will +include the object modules @var{module1} @dots{} which can be produced +with @code{compile-file}. + +@example +cd ~/scm/ +scm -e'(link-named-scm"cute""cube")' +(delete-file "scmflags.h") +(call-with-output-file + "scmflags.h" + (lambda (fp) + (for-each + (lambda (string) (write-line string fp)) + '("#define IMPLINIT \"/home/jaffer/scm/Init.scm\"" + "#define COMPILED_INITS init_cube();" + "#define BIGNUMS" + "#define FLOATS" + "#define ARRAYS")))) +(system "gcc -Wall -O2 -c continue.c findexec.c time.c + repl.c scl.c eval.c sys.c subr.c unif.c rope.c scm.c") +@dots{} +scm.c: In function `scm_init_extensions': +scm.c:95: warning: implicit declaration of function `init_cube' +scm.c: In function `scm_cat_path': +scm.c:589: warning: implicit declaration of function `realloc' +scm.c:594: warning: implicit declaration of function `malloc' +scm.c: In function `scm_try_path': +scm.c:612: warning: implicit declaration of function `free' +(system "cc -o cute continue.o findexec.o time.o repl.o scl.o + eval.o sys.o subr.o unif.o rope.o scm.o cube.o -lm -lc") + +Compilation finished at Sun Jul 21 00:59:17 +@end example +@end defun + +@node Dynamic Linking, Dump, Compiling And Linking, Packages +@section Dynamic Linking + +@noindent +If SCM has been compiled with @file{dynl.c} then the additional +properties of load and require (from [SLIB]) specified here are +supported. The @code{require} forms are preferred. The variable +@code{*catalog*} can be extended to define other @code{require}-able +packages. See @file{Link.scm} for details. + +@defun load filename lib1 @dots{} +In addition to the [R4RS] requirement of loading Scheme expressions if +@var{filename} is a Scheme source file, @code{load} will also +dynamically load/link object files (produced by @code{compile-file}, for +instance). The object-suffix need not be given to load. For example, + +@example +(load (in-vicinity (implementation-vicinity) "sc2")) +or (load (in-vicinity (implementation-vicinity) "sc2.o")) +or (require 'rev2-procedures) +or (require 'rev3-procedures) +@end example + +will load/link @file{sc2.o} if it exists. + +The @var{lib1} @dots{} pathnames are for additional libraries which may be +needed for object files not produced by the Hobbit compiler. For +instance, crs is linked on Linux by + +@example +(load (in-vicinity (implementation-vicinity) "crs.o") + (usr:lib "ncurses") (usr:lib "c")) +or (require 'curses) +@end example + +Turtlegr graphics library is linked by: + +@example +(load (in-vicinity (implementation-vicinity) "turtlegr") + (usr:lib "X11") (usr:lib "c") (usr:lib "m")) +or (require 'turtle-graphics) +@end example + +And the string regular expression (@pxref{Regular Expression Pattern +Matching}) package is linked by: + +@example +(load (in-vicinity (implementation-vicinity) "rgx") (usr:lib "c")) +@end example +or +@example +(require 'regex) +@end example +@end defun + +@defun require 'db +@defunx require 'wb +Either form will dynamically load the WB database system from the +wb:vicinity (@file{../wb/}) specified in @file{Link.scm}. See +@file{scm/ANNOUNCE} for ftp sites where WB is available. +@end defun + +@noindent +The following functions comprise the low-level Scheme interface to +dynamic linking. See the file @file{Link.scm} in the SCM distribution +for an example of their use. + +@defun dyn:link filename +@var{filename} should be a string naming an @dfn{object} or +@dfn{archive} file, the result of C-compiling. The @code{dyn:link} +procedure links and loads @var{filename} into the current SCM session. +If successfull, @code{dyn:link} returns a @dfn{link-token} suitable for +passing as the second argument to @code{dyn:call}. If not successful, +@code{#f} is returned. +@end defun + +@defun dyn:call name link-token +@var{link-token} should be the value returned by a call to +@code{dyn:link}. @var{name} should be the name of C function of no +arguments defined in the file named @var{filename} which was succesfully +@code{dyn:link}ed in the current SCM session. The @code{dyn:call} +procedure calls the C function corresponding to @var{name}. If +successful, @code{dyn:call} returns @code{#t}; If not successful, +@code{#f} is returned. + +@code{dyn:call} is used to call the @dfn{init_@dots{}} function after +loading SCM object files. The init_@dots{} function then makes the +identifiers defined in the file accessible as Scheme procedures. +@end defun + +@defun dyn:main-call name link-token arg1 @dots{} +@var{link-token} should be the value returned by a call to +@code{dyn:link}. @var{name} should be the name of C function of 2 +arguments, @code{(int argc, char **argv)}, defined in the file named +@var{filename} which was succesfully @code{dyn:link}ed in the current +SCM session. The @code{dyn:main-call} procedure calls the C function +corresponding to @var{name} with @code{argv} style arguments, such as +are given to C @code{main} functions. If successful, +@code{dyn:main-call} returns the integer returned from the call to +@var{name}. + +@code{dyn:main-call} can be used to call a @code{main} procedure from +SCM. For example, I link in and @code{dyn:main-call} a large C program, +the low level routines of which callback (@pxref{Callbacks}) into SCM +(which emulates PCI hardware). +@end defun + +@defun dyn:unlink link-token +@var{link-token} should be the value returned by a call to +@code{dyn:link}. The @code{dyn:unlink} procedure removes the previously +loaded file from the current SCM session. If successful, +@code{dyn:unlink} returns @code{#t}; If not successful, @code{#f} is +returned. +@end defun + +@defun usr:lib lib +Returns the pathname of the C library named lib. For example: +@code{(usr:lib "m")} could return @code{"/usr/lib/libm.a"}, the path of +the C math library. +@end defun + +@node Dump, Numeric, Dynamic Linking, Packages +@section Dump + +@dfn{Dump}, (also known as @dfn{unexec}), saves the continuation of an +entire SCM session to an executable file, which can then be invoked as a +program. Dumped executables start very quickly, since no Scheme code +has to be loaded. + +@noindent +There are constraints on which sessions are savable using @code{dump} + +@itemize @bullet +@item +Saved continuations are invalid in subsequent invocations; they cause +segmentation faults and other unpleasant side effects. +@item +Although DLD (@pxref{Dynamic Linking}) can be used to load compiled +modules both before and after dumping, @samp{SUN_DL} ELF systems can +load compiled modules only after dumping. This can be worked around by +compiling in those features you wish to @code{dump}. +@item +Ports (other than @code{current-input-port}, @code{current-output-port}, +@code{current-error-port}), X windows, etc. are invalid in subsequent +invocations. + +This restriction could be removed; @xref{Improvements To Make}. +@item +@code{Dump} should only be called from a loading file when the call to +dump is the last expression in that file. +@item +@code{Dump} can be called from the command line. +@end itemize + +@defun dump newpath +@defunx dump newpath #f +@defunx dump newpath #t +@defunx dump newpath thunk +@itemize @bullet +@item +Calls @code{gc}. +@item +Creates an executable program named @var{newpath} which continues the +state of the current SCM session when invoked. The optional argument +@var{thunk}, if provided, should be a procedure of no arguments. This +procedure will be called in the restored executable. + +If the optional argument is missing or a boolean, SCM's standard command +line processing will be called in the restored executable. + +If the second argument to @code{dump} is @code{#t}, argument processing +will continue from the command line passed to the dumping session. If +the second argument is missing or @code{#f} then the command line +arguments of the restoring invocation will be processed. +@item +Resumes the top level Read-Eval-Print loop. This is done instead of +continuing normally to avoid creating a saved continuation in the dumped +executable. +@end itemize + +@code{dump} may set the values of @code{boot-tail}, @code{*argv*}, +@code{restart}, and @var{*interactive*}. @code{dump} returns an +unspecified value. +@end defun + +When a dumped executable is invoked, the variable @var{*interactive*} +(@pxref{System Interface}) has the value it possessed when @code{dump} +created it. Calling @code{dump} with a single argument sets +@var{*interactive*} to @code{#f}, which is the state it has at the +beginning of command line processing. + +The procedure @code{program-arguments} returns the command line +arguments for the curent invocation. More specifically, +@code{program-arguments} for the restored session are @emph{not} saved +from the dumping session. Command line processing is done on +the value of the identifier @code{*argv*}. + +The thunk @code{boot-tail} is called by SCM to process command line +arguments. @code{dump} sets @code{boot-tail} to the @var{thunk} it is +called with. + +The following example shows how to create @samp{rscm}, which is like +regular scm, but which loads faster and has the @samp{random} package +alreadly provided. + +@example +bash$ scm -rrandom +> (dump "rscm") +#<unspecified> +> (quit) +bash$ ./rscm -lpi.scm -e"(pi (random 200) 5)" +00003 14159 26535 89793 23846 26433 83279 50288 41971 69399 +37510 58209 74944 59230 78164 06286 20899 86280 34825 34211 +70679 82148 08651 32823 06647 09384 46095 50582 23172 53594 +08128 48111 74502 84102 70193 85211 05559 64462 29489 +bash$ +@end example + +This task can also be accomplished using the @samp{-o} command line +option (@pxref{SCM Options}). + +@example +bash$ scm -rrandom -o rscm +> (quit) +bash$ ./rscm -lpi.scm -e"(pi (random 200) 5)" +00003 14159 26535 89793 23846 26433 83279 50288 41971 69399 +37510 58209 74944 59230 78164 06286 20899 86280 34825 34211 +70679 82148 08651 32823 06647 09384 46095 50582 23172 53594 +08128 48111 74502 84102 70193 85211 05559 64462 29489 +bash$ +@end example + +@node Numeric, Arrays, Dump, Packages +@section Numeric + +@defvr Constant most-positive-fixnum +The immediate integer closest to positive infinity. +@xref{Configuration, , , slib, SLIB}. +@end defvr + +@defvr Constant most-negative-fixnum +The immediate integer closest to negative infinity. +@end defvr + +@noindent +These procedures augment the standard capabilities in @ref{Numerical +operations, , ,r4rs, Revised(4) Scheme}. + +@defun sinh z +@defunx cosh z +@defunx tanh z +Return the hyperbolic sine, cosine, and tangent of @var{z} +@end defun + +@defun asinh z +@defunx acosh z +@defunx atanh z +Return the inverse hyperbolic sine, cosine, and tangent of @var{z} +@end defun + +@defun $sqrt x +@defunx $abs x +@defunx $exp x +@defunx $log x +@defunx $sin x +@defunx $cos x +@defunx $tan x +@defunx $asin x +@defunx $acos x +@defunx $atan x + +@defunx $sinh x +@defunx $cosh x +@defunx $tanh x +@defunx $asinh x +@defunx $acosh x +@defunx $atanh x +Real-only versions of these popular functions. The argument @var{x} +must be a real number. It is an error if the value which should be +returned by a call to these procedures is @emph{not} real. +@end defun + +@defun $atan2 y x +Computes @code{(angle (make-rectangular x y))} for real numbers @var{y} +and @var{x}. +@end defun + +@defun $expt x1 x2 +Returns real number @var{x1} raised to the real power @var{x2}. It is +an error if the value which should be returned by a call to @code{$expt} +is not real. +@end defun + +@node Arrays, I/O-Extensions, Numeric, Packages +@section Arrays + +@menu +* Conventional Arrays:: +* Array Mapping:: +* Uniform Array:: +* Bit Vectors:: +@end menu + +@node Conventional Arrays, Array Mapping, Arrays, Arrays +@subsection Conventional Arrays + +@dfn{Arrays} read and write as a @code{#} followed by the @dfn{rank} +(number of dimensions) followed by what appear as lists (of lists) of +elements. The lists must be nested to the depth of the rank. For each +depth, all lists must be the same length. +@example +(make-array 'ho 3 3) @result{} +#2((ho ho ho) (ho ho ho) (ho ho ho)) +@end example + +Unshared conventional (not uniform) 0-based arrays of rank 1 (dimension) +are equivalent to (and can't be distinguished from) vectors. +@example +(make-array 'ho 3) @result{} (ho ho ho) +@end example + +When constructing an array, @var{bound} is either an inclusive range of +indices expressed as a two element list, or an upper bound expressed +as a single integer. So +@example +(make-array 'foo 3 3) @equiv{} (make-array 'foo '(0 2) '(0 2)) +@end example + +@defun array? obj +Returns @code{#t} if the @var{obj} is an array, and @code{#f} if not. +@end defun + +@defun make-array initial-value bound1 bound2 @dots{} +Creates and returns an array that has as many dimensions as there are +@var{bound}s and fills it with @var{initial-value}. +@end defun + +@defun array-ref array index1 index2 @dots{} +Returns the @var{index1}, @var{index2}, @dots{}'th element of +@var{array}. +@end defun + +@defun array-in-bounds? array index1 index2 @dots{} +Returns @code{#t} if its arguments would be acceptable to @var{array-ref}. +@end defun + +@defun array-set! array new-value index1 index2 @dots{} +Sets the @var{index1}, @var{index2}, @dots{}'th element of @var{array} +to @var{new-value}. The value returned by @code{array-set!} is +unspecified. +@end defun + +@defun make-shared-array array mapper bound1 bound2 @dots{} +@code{make-shared-array} can be used to create shared subarrays of other +arrays. The @var{mapper} is a function that translates coordinates in +the new array into coordinates in the old array. A @var{mapper} must be +linear, and its range must stay within the bounds of the old array, but +it can be otherwise arbitrary. A simple example: +@example +(define fred (make-array #f 8 8)) +(define freds-diagonal + (make-shared-array fred (lambda (i) (list i i)) 8)) +(array-set! freds-diagonal 'foo 3) +(array-ref fred 3 3) @result{} foo +(define freds-center + (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2)) +(array-ref freds-center 0 0) @result{} foo +@end example +@end defun + +@defun transpose-array array dim0 dim1 @dots{} +Returns an array sharing contents with @var{array}, but with dimensions +arranged in a different order. There must be one @var{dim} argument for +each dimension of @var{array}. @var{dim0}, @var{dim1}, @dots{} should +be integers between 0 and the rank of the array to be returned. Each +integer in that range must appear at least once in the argument list. + +The values of @var{dim0}, @var{dim1}, @dots{} correspond to dimensions +in the array to be returned, their positions in the argument list to +dimensions of @var{array}. Several @var{dim}s may have the same value, +in which case the returned array will have smaller rank than +@var{array}. + +examples: +@example +(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d)) +(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d) +(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{} + #2((a 4) (b 5) (c 6)) +@end example +@end defun + +@defun enclose-array array dim0 dim1 @dots{} +@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than +the rank of @var{array}. @var{enclose-array} returns an array +resembling an array of shared arrays. The dimensions of each shared +array are the same as the @var{dim}th dimensions of the original array, +the dimensions of the outer array are the same as those of the original +array that did not match a @var{dim}. + +An enclosed array is not a general Scheme array. Its elements may not +be set using @code{array-set!}. Two references to the same element of +an enclosed array will be @code{equal?} but will not in general be +@code{eq?}. The value returned by @var{array-prototype} when given an +enclosed array is unspecified. + +examples: +@example +(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) @result{} + #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))> + +(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{} + #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))> +@end example +@end defun + +@defun array-shape array +Returns a list of inclusive bounds of integers. +@example +(array-shape (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) (0 4)) +@end example +@end defun + +@defun array-dimensions array +@code{Array-dimensions} is similar to @code{array-shape} but replaces +elements with a @code{0} minimum with one greater than the maximum. So: +@example +(array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5) +@end example +@end defun + +@defun array-rank obj +Returns the number of dimensions of @var{obj}. If @var{obj} is not an +array, @code{0} is returned. +@end defun + +@defun array->list array +Returns a list consisting of all the elements, in order, of @var{array}. +@end defun + +@defun array-copy! source destination +Copies every element from vector or array @var{source} to the +corresponding element of @var{destination}. @var{destination} must have +the same rank as @var{source}, and be at least as large in each +dimension. The order of copying is unspecified. +@end defun + +@defun serial-array-copy! source destination +Same as @code{array-copy!} but guaranteed to copy in row-major order. +@end defun + +@defun array-fill! array fill +Stores @var{fill} in every element of @var{array}. The value returned +is unspecified. +@end defun + +@defun array-equal? array0 array1 @dots{} +Returns @code{#t} iff all arguments are arrays with the same shape, the +same type, and have corresponding elements which are either +@code{equal?} or @code{array-equal?}. This function differs from +@code{equal?} in that a one dimensional shared array may be +@var{array-equal?} but not @var{equal?} to a vector or uniform vector. +@end defun + +@defun array-contents array +@defunx array-contents array strict +If @var{array} may be @dfn{unrolled} into a one dimensional shared array +without changing their order (last subscript changing fastest), then +@code{array-contents} returns that shared array, otherwise it returns +@code{#f}. All arrays made by @var{make-array} and +@var{make-uniform-array} may be unrolled, some arrays made by +@var{make-shared-array} may not be. + +If the optional argument @var{strict} is provided, a shared array will +be returned only if its elements are stored internally contiguous in +memory. +@end defun + +@node Array Mapping, Uniform Array, Conventional Arrays, Arrays +@subsection Array Mapping + +@defun array-map! array0 proc array1 @dots{} + +If @var{array1}, @dots{} are arrays, they must have the same number of +dimensions as @var{array0} and have a range for each index which +includes the range for the corresponding index in @var{array0}. +If they are scalars, that is, not arrays, vectors, or strings, then +they will be converted internally to arrays of the appropriate shape. +@var{proc} is applied to each tuple of elements of @var{array1} @dots{} +and the result is stored as the corresponding element in @var{array0}. +The value returned is unspecified. The order of application is +unspecified. + +@end defun + +@defun serial-array-map! array0 proc array1 @dots{} +Same as @var{array-map!}, but guaranteed to apply @var{proc} in +row-major order. +@end defun + +@defun array-for-each proc array0 @dots{} +@var{proc} is applied to each tuple of elements of @var{array0} @dots{} +in row-major order. The value returned is unspecified. +@end defun + +@defun array-index-map! array proc +applies @var{proc} to the indices of each element of @var{array} in +turn, storing the result in the corresponding element. The value +returned and the order of application are unspecified. + +One can implement @var{array-indexes} as +@example +(define (array-indexes array) + (let ((ra (apply make-array #f (array-shape array)))) + (array-index-map! ra (lambda x x)) + ra)) +@end example +Another example: +@example +(define (apl:index-generator n) + (let ((v (make-uniform-vector n 1))) + (array-index-map! v (lambda (i) i)) + v)) +@end example +@end defun + +@defun scalar->array scalar array prototype +Returns a uniform array of the same shape as @var{array}, having only +one shared element, which is @code{eqv?} to @var{scalar}. +If the optional argument @var{prototype} is supplied it will be used +as the prototype for the returned array. Otherwise the returned array +will be of the same type as @code{array} if that is possible, and +a conventional array if it is not. This function is used internally +by @code{array-map!} and friends to handle scalar arguments. +@end defun + +@node Uniform Array, Bit Vectors, Array Mapping, Arrays +@subsection Uniform Array + +@noindent +@dfn{Uniform Arrays} and vectors are arrays whose elements are all of +the same type. Uniform vectors occupy less storage than conventional +vectors. Uniform Array procedures also work on vectors, +uniform-vectors, bit-vectors, and strings. + +@noindent +@var{prototype} arguments in the following procedures are interpreted +according to the table: + +@example +prototype type display prefix + +#t boolean (bit-vector) #b +#\a char (string) #a +integer >0 unsigned integer #u +integer <0 signed integer #e +1.0 float (single precision) #s +1/3 double (double precision float) #i ++i complex (double precision) #c +() conventional vector # +@end example + +@noindent +Unshared uniform character 0-based arrays of rank 1 (dimension) +are equivalent to (and can't be distinguished from) strings. +@example +(make-uniform-array #\a 3) @result{} "$q2" +@end example + +@noindent +Unshared uniform boolean 0-based arrays of rank 1 (dimension) are +equivalent to (and can't be distinguished from) @ref{Bit Vectors, +bit-vectors}. +@example +(make-uniform-array #t 3) @result{} #*000 +@equiv{} +#b(#f #f #f) @result{} #*000 +@equiv{} +#1b(#f #f #f) @result{} #*000 +@end example + +@noindent +Other uniform vectors are written in a form similar to that of vectors, +except that a single character from the above table is put between +@code{#} and @code{(}. For example, @code{'#e(3 5 9)} returns a uniform +vector of signed integers. + +@defun uniform-vector-ref uve index +Returns the element at the @var{index} element in @var{uve}. +@end defun + +@defun uniform-vector-set! uve index new-value +Sets the element at the @var{index} element in @var{uve} to +@var{new-value}. The value returned by @code{uniform-vector-set!} is +unspecified. +@end defun + +@defun array? obj prototype +Returns @code{#t} if the @var{obj} is an array of type corresponding to +@var{prototype}, and @code{#f} if not. +@end defun + +@defun make-uniform-array prototype bound1 bound2 @dots{} +Creates and returns a uniform array of type corresponding to +@var{prototype} that has as many dimensions as there are @var{bound}s +and fills it with @var{prototype}. +@end defun + +@defun array-prototype array +Returns an object that would produce an array of the same type as +@var{array}, if used as the @var{prototype} for +@code{make-uniform-array}. +@end defun + +@defun list->uniform-array rank prot lst +@defunx list->uniform-vector prot lst +Returns a uniform array of the type indicated by prototype @var{prot} +with elements the same as those of @var{lst}. Elements must be of the +appropriate type, no coercions are done. +@end defun + +@defun uniform-vector-fill! uve fill +Stores @var{fill} in every element of @var{uve}. The value returned is +unspecified. +@end defun + +@defun uniform-vector-length uve +Returns the number of elements in @var{uve}. +@end defun + +@defun dimensions->uniform-array dims prototype fill +@defunx dimensions->uniform-array dims prototype +@defunx make-uniform-vector length prototype fill +@defunx make-uniform-vector length prototype +Creates and returns a uniform array or vector of type corresponding to +@var{prototype} with dimensions @var{dims} or length @var{length}. If +the @var{fill} argument is supplied, the returned array is filled with +this value. +@end defun + +@defun uniform-array-read! ura +@defunx uniform-array-read! ura port +@defunx uniform-vector-read! uve +@defunx uniform-vector-read! uve port +Attempts to read all elements of @var{ura}, in lexicographic order, as +binary objects from @var{port}. If an end of file is encountered during +uniform-array-read! the objects up to that point only are put into @var{ura} +(starting at the beginning) and the remainder of the array is +unchanged. + +@code{uniform-array-read!} returns the number of objects read. +@var{port} may be omitted, in which case it defaults to the value +returned by @code{(current-input-port)}. +@end defun + +@defun uniform-array-write ura +@defunx uniform-array-write ura port +@defunx uniform-vector-write uve +@defunx uniform-vector-write uve port +Writes all elements of @var{ura} as binary objects to @var{port}. The +number of of objects actually written is returned. @var{port} may be +omitted, in which case it defaults to the value returned by +@code{(current-output-port)}. +@end defun + +@node Bit Vectors, , Uniform Array, Arrays +@subsection Bit Vectors + +@noindent +Bit vectors can be written and read as a sequence of @code{0}s and +@code{1}s prefixed by @code{#*}. + +@example +#b(#f #f #f #t #f #t #f) @result{} #*0001010 +@end example + +@noindent +Some of these operations will eventually be generalized to other +uniform-arrays. + +@defun bit-count bool bv +Returns the number occurrences of @var{bool} in @var{bv}. +@end defun + +@defun bit-position bool bv k +Returns the minimum index of an occurrence of @var{bool} in @var{bv} +which is at least @var{k}. If no @var{bool} occurs within the specified +range @code{#f} is returned. +@end defun + +@defun bit-invert! bv +Modifies @var{bv} by replacing each element with its negation. +@end defun + +@defun bit-set*! bv uve bool +If uve is a bit-vector @var{bv} and uve must be of the same length. If +@var{bool} is @code{#t}, uve is OR'ed into @var{bv}; If @var{bool} is @code{#f}, the +inversion of uve is AND'ed into @var{bv}. + +If uve is a unsigned integer vector all the elements of uve must be +between 0 and the @code{LENGTH} of @var{bv}. The bits of @var{bv} +corresponding to the indexes in uve are set to @var{bool}. + +The return value is unspecified. +@end defun + +@defun bit-count* bv uve bool +Returns +@example +(bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t). +@end example +@var{bv} is not modified. +@end defun + + +@node I/O-Extensions, Posix Extensions, Arrays, Packages +@section I/O-Extensions + +@noindent +If @code{'i/o-extensions} is provided (by linking in @file{ioext.o}), +@ref{Line I/O, , , slib, SLIB}, and the following functions are defined: + +@defun isatty? port +Returns @code{#t} if @var{port} is input or output to a serial non-file device. +@end defun + +@defun stat <port-or-string> +Returns a vector of integers describing the argument. The argument +can be either a string or an open input port. If the argument is an +open port then the returned vector describes the file to which the +port is opened; If the argument is a string then the returned vector +describes the file named by that string. If there exists no file with +the name string, or if the file cannot be accessed @code{#f} is returned. +The elements of the returned vector are as follows: + + +@table @r +@item 0 st_dev +ID of device containing a directory entry for this file +@item 1 st_ino +Inode number +@item 2 st_mode +File type, attributes, and access control summary +@item 3 st_nlink +Number of links +@item 4 st_uid +User ID of file owner +@item 5 st_gid +Group ID of file group +@item 6 st_rdev +Device ID; this entry defined only for char or blk spec files +@item 7 st_size +File size (bytes) +@item 8 st_atime +Time of last access +@item 9 st_mtime +Last modification time +@item 10 st_ctime +Last file status change time +@end table +@end defun + +@defun getpid +Returns the process ID of the current process. +@end defun + +@defun file-position port +Returns the current position of the character in @var{port} which will +next be read or written. If @var{port} is not open to a file the result +is unspecified. +@end defun + +@defun file-set-position port integer +Sets the current position in @var{port} which will next be read or +written. If @var{port} is not open to a file the action of +@code{file-set-position} is unspecified. The result of +@code{file-set-position} is unspecified. +@end defun + +@defun reopen-file filename modes port +Closes port @var{port} and reopens it with @var{filename} and +@var{modes}. @code{reopen-file} returns @code{#t} if successful, +@code{#f} if not. +@end defun + +@defun duplicate-port port modes +Creates and returns a @dfn{duplicate} port from @var{port}. Duplicate +@emph{unbuffered} ports share one file position. @var{modes} are as for +@ref{Files and Ports, open-file}. +@end defun + +@defun redirect-port! from-port to-port +Closes @var{to-port} and makes @var{to-port} be a duplicate of +@var{from-port}. @code{redirect-port!} returns @var{to-port} if +successful, @code{#f} if not. If unsuccessful, @var{to-port} is not +closed. +@end defun + +@defun opendir dirname +Returns a @dfn{directory} object corresponding to the file system +directory named @var{dirname}. If unsuccessful, returns @code{#f}. +@end defun + +@defun readdir dir +Returns the string name of the next entry from the directory @var{dir}. +If there are no more entries in the directory, @code{readdir} returns a +@code{#f}. +@end defun + +@defun rewinddir dir +Reinitializes @var{dir} so that the next call to @code{readdir} with +@var{dir} will return the first entry in the directory again. +@end defun + +@defun closedir dir +Closes @var{dir} and returns @code{#t}. If @var{dir} is already +closed,, @code{closedir} returns a @code{#f}. +@end defun + +@defun mkdir path mode +The @code{mkdir} function creates a new, empty directory whose name is +@var{path}. The integer argument @var{mode} specifies the file +permissions for the new directory. @xref{The Mode Bits for Access +Permission, , , libc, Gnu C Library}, for more information about this. + +@code{mkdir} returns if successful, @code{#f} if not. +@end defun + +@defun rmdir path +The @code{rmdir} function deletes the directory @var{path}. The +directory must be empty before it can be removed. @code{rmdir} returns +if successful, @code{#f} if not. +@end defun + +@defun chdir filename +Changes the current directory to @var{filename}. If @var{filename} does not +exist or is not a directory, @code{#f} is returned. Otherwise, @code{#t} is +returned. +@end defun + +@defun getcwd +The function @code{getcwd} returns a string containing the absolute file +name representing the current working directory. If this string cannot +be obtained, @code{#f} is returned. +@end defun + +@defun rename-file oldfilename newfilename +Renames the file specified by @var{oldfilename} to @var{newfilename}. +If the renaming is successful, @code{#t} is returned. Otherwise, +@code{#f} is returned. +@end defun + +@defun chmod file mode +The function @code{chmod} sets the access permission bits for the file +named by @var{file} to @var{mode}. The @var{file} argument may be a +string containing the filename or a port open to the file. + +@code{chmod} returns if successful, @code{#f} if not. +@end defun + +@defun utime pathname acctime modtime +Sets the file times associated with the file named @var{pathname} to +have access time @var{acctime} and modification time @var{modtime}. +@code{utime} returns if successful, @code{#f} if not. +@end defun + +@defun umask mode +The function @code{umask} sets the file creation mask of the current +process to @var{mask}, and returns the previous value of the file +creation mask. +@end defun + +@defun fileno port +Returns the integer file descriptor associated with the port @var{port}. +If an error is detected, @code{#f} is returned. +@end defun + +@defun access pathname how +Returns @code{#t} if the file named by @var{pathname} can be accessed in +the way specified by the @var{how} argument. The @var{how} argument can +be the @code{logior} of the flags: + +@enumerate 0 +@item +File-exists? +@item +File-is-executable? +@item +File-is-writable? +@end enumerate +@enumerate 4 +@item +File-is-readable? +@end enumerate + +Or the @var{how} argument can be a string of 0 to 3 of the following +characters in any order. The test performed is the @code{and} of the +associated tests and @code{file-exists?}. + +@table @key +@item x +File-is-executable? +@item w +File-is-writable? +@item r +File-is-readable? +@end table +@end defun + +@defun execl command arg0 @dots{} +@defunx execlp command arg0 @dots{} +Transfers control to program @var{command} called with arguments +@var{arg0} @dots{}. For @code{execl}, @var{command} must be an exact +pathname of an executable file. @code{execlp} searches for +@var{command} in the list of directories specified by the environment +variable @var{PATH}. The convention is that @var{arg0} is the same name +as @var{command}. + +If successful, this procedure does not return. Otherwise an error +message is printed and the integer @code{errno} is returned. + +@defunx execv command arglist +@defunx execvp command arglist +Like @code{execl} and @code{execlp} except that the set of arguments to +@var{command} is @var{arglist}. +@end defun + +@defun putenv string +adds or removes definitions from the @dfn{environment}. If the +@var{string} is of the form @samp{NAME=VALUE}, the definition is added +to the environment. Otherwise, the @var{string} is interpreted as the +name of an environment variable, and any definition for this variable in +the environment is removed. + +Names of environment variables are case-sensitive and must not contain +the character @code{=}. System-defined environment variables are +invariably uppercase. + +@code{Putenv} is used to set up the environment before calls to +@code{execl}, @code{execlp}, @code{execv}, @code{execvp}, @code{system}, +or @code{open-pipe} (@pxref{I/O-Extensions, open-pipe}). + +To access environment variables, use @code{getenv} (@pxref{System +Interface, getenv, , slib, SLIB}). +@end defun + +@node Posix Extensions, Regular Expression Pattern Matching, I/O-Extensions, Packages +@section Posix Extensions + +@noindent +If @code{'posix} is provided (by linking in @file{posix.o}), the +following functions are defined: + +@defun open-pipe string modes +If the string @var{modes} contains an @key{r}, returns an input port +capable of delivering characters from the standard output of the system +command @var{string}. Otherwise, returns an output port capable of +receiving characters which become the standard input of the system +command @var{string}. If a pipe cannot be created @code{#f} is +returned. +@end defun + +@defun open-input-pipe string +Returns an input port capable of delivering characters from the +standard output of the system command @var{string}. If a pipe cannot be +created @code{#f} is returned. +@end defun + +@defun open-output-pipe string +Returns an output port capable of receiving characters which become +the standard input of the system command @var{string}. If a pipe cannot +be created @code{#f} is returned. +@end defun + +@defun close-port pipe +Closes the @var{pipe}, rendering it incapable of delivering or accepting +characters. This routine has no effect if the pipe has already been +closed. The value returned is unspecified. +@end defun + +@defun pipe +Returns @code{(cons @var{rd} @var{wd})} where @var{rd} and @var{wd} are +the read and write (port) ends of a @dfn{pipe} respectively. +@end defun + +@defun fork +Creates a copy of the process calling @code{fork}. Both processes +return from @code{fork}, but the calling (@dfn{parent}) process's +@code{fork} returns the @dfn{child} process's ID whereas the child +process's @code{fork} returns 0. +@end defun + +@noindent +For a discussion of @dfn{ID}s @xref{Process Persona, , , GNU C Library, +libc}. + +@defun getppid +Returns the process ID of the parent of the current process. +For a process's own ID @xref{I/O-Extensions, getpid}. +@end defun + +@defun getuid +Returns the real user ID of this process. +@end defun + +@defun getgid +Returns the real group ID of this process. +@end defun + +@defun getegid +Returns the effective group ID of this process. +@end defun + +@defun geteuid +Returns the effective user ID of this process. +@end defun + +@defun setuid id +Sets the real user ID of this process to @var{id}. +Returns @code{#t} if successful, @code{#f} if not. +@end defun + +@defun setgid id +Sets the real group ID of this process to @var{id}. +Returns @code{#t} if successful, @code{#f} if not. +@end defun + +@defun setegid id +Sets the effective group ID of this process to @var{id}. +Returns @code{#t} if successful, @code{#f} if not. +@end defun + +@defun seteuid id +Sets the effective user ID of this process to @var{id}. +Returns @code{#t} if successful, @code{#f} if not. +@end defun + +@defun kill pid sig +The @code{kill} function sends the signal @var{signum} to the process or +process group specified by @var{pid}. Besides the signals listed in +@ref{Standard Signals, , ,libc , GNU C Library}, @var{signum} can also +have a value of zero to check the validity of the @var{pid}. + +The @var{pid} specifies the process or process group to receive the +signal: + +@table @asis +@item > 0 +The process whose identifier is @var{pid}. + +@item 0 +All processes in the same process group as the sender. The +sender itself does not receive the signal. + +@item -1 +If the process is privileged, send the signal to all +processes except for some special system processes. +Otherwise, send the signal to all processes with the same +effective user ID. + +@item < -1 +The process group whose identifier is @code{(abs @var{pid})}. +@end table + +A process can send a signal to itself with @code{(kill (getpid) +@var{signum})}. If @code{kill} is used by a process to send a signal to +itself, and the signal is not blocked, then @code{kill} delivers at +least one signal (which might be some other pending unblocked signal +instead of the signal @var{signum}) to that process before it returns. + +The return value from @code{kill} is zero if the signal can be sent +successfully. Otherwise, no signal is sent, and a value of @code{-1} is +returned. If @var{pid} specifies sending a signal to several processes, +@code{kill} succeeds if it can send the signal to at least one of them. +There's no way you can tell which of the processes got the signal or +whether all of them did. +@end defun + +@defun waitpid pid options + +The @code{waitpid} function suspends execution of the current process +until a child as specified by the @var{pid} argument has exited, or until a +signal is deliverd whose action is to terminate the current process or +to call a signal handling function. If a child as requested by @var{pid} has +already exited by the time of the call (a so-called @dfn{zombie} +process), the function returns immediately. Any system resources used +by the child are freed. + +The value of @var{pid} can be one of: + +@table @asis +@item < -1 +which means to wait for any child process whose process group ID is +equal to the absolute value of + +@item -1 +which means to wait for any child process whose process group ID is +equal to the @code{(abs @var{pid})}. + +@item -1 +which means to wait for any child process; this is the same behaviour +which wait exhibits. + +@item 0 +which means to wait for any child process whose process group ID is +equal to that of the calling process. + +@item > 0 +which means to wait for the child whose process ID is equal to the value +of @var{pid}. +@end table + +The value of @var{options} is one of the following: + +@enumerate 0 +@item +Nothing special. + +@item +(@code{WNOHANG}) which means to return immediately if no child is there +to be waited for. + +@item +(@code{WUNTRACED}) which means to also return for children which are +stopped, and whose status has not been reported. + +@item +Which means both of the above. +@end enumerate + +The return value is normally the process ID of the child process whose +status is reported. If the @code{WNOHANG} option was specified and no +child process is waiting to be noticed, the value is zero. A value of +@code{#f} is returned in case of error and @code{errno} is set. For +information about the @code{errno} codes @xref{Process Completion, , , +GNU C Library, libc}. +@end defun + +@defun uname +You can use the @code{uname} procedure to find out some information +about the type of computer your program is running on. + +Returns a vector of strings. These strings are: + +@enumerate 0 +@item +The name of the operating system in use. +@item +The network name of this particular computer. +@item +The current release level of the operating system implementation. +@item +The current version level within the release of the operating system. +@item +Description of the type of hardware that is in use. + +Some examples are @samp{"i386-ANYTHING"}, @samp{"m68k-hp"}, +@samp{"sparc-sun"}, @samp{"m68k-sun"}, @samp{"m68k-sony"} and @samp{"mips-dec"}. +@end enumerate +@end defun + +@defun getpw name +@defunx getpw uid +@defunx getpw +Returns a vector of information for the entry for @code{NAME}, +@code{UID}, or the next entry if no argument is given. The +information is: + +@enumerate 0 +@item +The user's login name. +@item +The encrypted password string. +@item +The user ID number. +@item +The user's default group ID number. +@item +A string typically containing the user's real name, and +possibly other information such as a phone number. +@item +The user's home directory, initial working directory, or @code{#f}, in +which case the interpretation is system-dependent. +@item +The user's default shell, the initial program run when the user logs in, +or @code{#f}, indicating that the system default should be used. +@end enumerate +@end defun + +@defun setpwent #t +Rewinds the pw entry table back to the begining. + +@defunx setpwent #f +@defunx setpwent +Closes the pw table. +@end defun + + +@defun getgr name +@defunx getgr uid +@defunx getgr +Returns a vector of information for the entry for @code{NAME}, +@code{UID}, or the next entry if no argument is given. The +information is: + +@enumerate 0 +@item +The name of the group. +@item +The encrypted password string. +@item +The group ID number. +@item +A list of (string) names of users in the group. +@end enumerate +@end defun + +@defun setgrent #t +Rewinds the group entry table back to the begining. + +@defunx setgrent #f +@defunx setgrent +Closes the group table. +@end defun + +@defun getgroups +Returns a vector of all the supplementary group IDs of the process. +@end defun + + +@defun link oldname newname +The @code{link} function makes a new link to the existing file named by +@var{oldname}, under the new name @var{newname}. + +@code{link} returns a value of @code{#t} if it is successful and +@code{#f} on failure. +@end defun + +@defun chown filename owner group +The @code{chown} function changes the owner of the file @var{filename} +to @var{owner}, and its group owner to @var{group}. + +@code{chown} returns a value of @code{#t} if it is successful and +@code{#f} on failure. +@end defun + +@defun ttyname port +If port @var{port} is associated with a terminal device, returns a +string containing the file name of termainal device; otherwise +@code{#f}. +@end defun + +@section Unix Extensions + +@noindent +If @code{'unix} is provided (by linking in @file{unix.o}), the following +functions are defined: + +@noindent +These @dfn{priveledged} and symbolic link functions are not in Posix: + +@defun symlink oldname newname +The @code{symlink} function makes a symbolic link to @var{oldname} named +@var{newname}. + +@code{symlink} returns a value of @code{#t} if it is successful and +@code{#f} on failure. +@end defun + +@defun readlink filename +Returns the value of the symbolic link @var{filename} or @code{#f} for +failure. +@end defun + +@defun lstat filename +The @code{lstat} function is like @code{stat}, except that it does not +follow symbolic links. If @var{filename} is the name of a symbolic +link, @code{lstat} returns information about the link itself; otherwise, +@code{lstat} works like @code{stat}. @xref{I/O-Extensions}. +@end defun + +@defun nice increment +Increment the priority of the current process by @var{increment}. +@code{chown} returns a value of @code{#t} if it is successful and +@code{#f} on failure. +@end defun + +@defun acct filename +When called with the name of an exisitng file as argument, accounting is +turned on, records for each terminating pro-cess are appended to +@var{filename} as it terminates. An argument of @code{#f} causes +accounting to be turned off. + +@code{acct} returns a value of @code{#t} if it is successful and +@code{#f} on failure. +@end defun + +@defun mknod filename mode dev +The @code{mknod} function makes a special file with name @var{filename} +and modes @var{mode} for device number @var{dev}. + +@code{mknod} returns a value of @code{#t} if it is successful and +@code{#f} on failure. +@end defun + +@defun sync +@code{sync} first commits inodes to buffers, and then buffers to disk. +sync() only schedules the writes, so it may return before the actual +writing is done. The value returned is unspecified. +@end defun + +@node Regular Expression Pattern Matching, Line Editing, Posix Extensions, Packages +@section Regular Expression Pattern Matching + +These functions are defined in @file{rgx.c} using a POSIX or GNU +@dfn{regex} library. If your computer does not support regex, a package +is available via ftp from +@file{prep.ai.mit.edu:/pub/gnu/regex-0.12.tar.gz}. For a description of +regular expressions, @xref{syntax, , , regex, "regex" regular expression +matching library}. + +@defun regcomp @var{pattern} [@var{flags}] +Compile a @dfn{regular expression}. Return a compiled regular +expression, or an integer error code suitable as an argument to +@code{regerror}. + +@var{flags} in @code{regcomp} is a string of option letters used to +control the compilation of the regular expression. The letters may +consist of: + +@table @samp +@item n +newlines won't be matched by @code{.} or hat lists; ( @code{[^...]} ) +@item i +ignore case. +@exdent only when compiled with @var{_GNU_SOURCE}: +@item 0 +allows dot to match a null character. +@item f +enable GNU fastmaps. +@end table +@end defun + +@defun regerror @var{errno} +Returns a string describing the integer @var{errno} returned when +@code{regcomp} fails. +@end defun + +@defun regexec @var{re} @var{string} +Returns @code{#f} or a vector of integers. These integers are in +doublets. The first of each doublet is the index of @var{string} of +the start of the matching expression or sub-expression (delimited by +parentheses in the pattern). The last of each doublet is index of +@var{string} of the end of that expression. @code{#f} is returned if +the string does not match. +@end defun + +@defun regmatch? @var{re} @var{string} +Returns @code{#t} if the @var{pattern} such that @var{regexp} = (regcomp +@var{pattern}) matches @var{string} as a POSIX extended regular +expressions. Returns @code{#f} otherwise. +@end defun + +@defun regsearch @var{re} @var{string} [@var{start} [@var{len}]] +@defunx regsearchv @var{re} @var{string} [@var{start} [@var{len}]] +@defunx regmatch @var{re} @var{string} [@var{start} [@var{len}]] +@defunx regmatchv @var{re} @var{string} [@var{start} [@var{len}]] +@code{Regsearch} searches for the pattern within the string. + +@code{Regmatch} anchors the pattern and begins matching it against +string. + +@code{Regsearch} returns the character position where @var{re} starts, +or @code{#f} if not found. + +@code{Regmatch} returns the number of characters matched, @code{#f} if +not matched. + +@code{Regsearchv} and @code{regmatchv} return the match vector is +returned if @var{re} is found, @code{#f} otherwise. + +@table @var +@item re +may be either: +@enumerate +@item +a compiled regular expression returned by @code{regcomp}; +@item +a string representing a regular expression; +@item +a list of a string and a set of option letters. +@end enumerate +@item string +The string to be operated upon. +@item start +The character position at which to begin the search or match. If absent, +the default is zero. + +@exdent @emph{Compiled _GNU_SOURCE and using GNU libregex only:} + +When searching, if @var{start} is negative, the absolute value of +@var{start} will be used as the start location and reverse searching +will be performed. + +@item len +The search is allowed to examine only the first @var{len} characters of +@var{string}. If absent, the entire string may be examined. +@end table +@end defun + +@defun string-split @var{re} @var{string} +@defunx string-splitv @var{re} @var{string} +@code{String-split} splits a string into substrings that are separated +by @var{re}, returning a vector of substrings. + +@code{String-splitv} returns a vector of string positions that indicate +where the substrings are located. +@end defun + +@defun string-edit @var{re} @var{edit-spec} @var{string} [@var{count}] +Returns the edited string. + +@table @var +@item edit-spec +Is a string used to replace occurances of @var{re}. Backquoted integers +in the range of 1-9 may be used to insert subexpressions in @var{re}, as +in @code{sed}. +@item count +The number of substitutions for @code{string-edit} to perform. If +@code{#t}, all occurances of @var{re} will be replaced. The default is +to perform one substitution. +@end table +@end defun + +@node Line Editing, Curses, Regular Expression Pattern Matching, Packages +@section Line Editing + +@noindent +These procedures provide input line editing and recall. + +@noindent +These functions are defined in @file{edline.c} and @file{Iedline.scm} +using the @dfn{editline} or GNU @dfn{readline} (@pxref{Top, , Overview +,readline ,GNU Readline Library}) libraries available from: + +@itemize @bullet +@item +@ifset html +<A HREF="ftp://ftp.sys.toronto.edu/pub/rc/editline.shar"> +@end ifset +@code{ftp.sys.toronto.edu:/pub/rc/editline.shar} +@ifset html +</A> +@end ifset +@item +@ifset html +<A HREF="ftp://prep.ai.mit.edu/pub/gnu/readline-2.0.tar.gz"> +@end ifset +@code{prep.ai.mit.edu:/pub/gnu/readline-2.0.tar.gz} +@ifset html +</A> +@end ifset +@end itemize + +@noindent +When @file{Iedline.scm} is loaded, if the current input port is the +default input port and the environment variable @var{EMACS} is not +defined, line-editing mode will be entered. + +@defun default-input-port +Returns the initial @code{current-input-port} SCM was invoked with +(stdin). +@end defun + +@defun default-output-port +Returns the initial @code{current-output-port} SCM was invoked with +(stdout). +@end defun + +@defun make-edited-line-port +Returns an input/output port that allows command line editing and +retrieval of history. +@end defun + +@defun line-editing +Returns the current edited line port or @code{#f}. + +@defunx line-editing bool +If @var{bool} is false, exits line-editing mode and returns the previous +value of @code{(line-editing)}. If @var{bool} is true, sets the current +input and output ports to an edited line port and returns the previous +value of @code{(line-editing)}. +@end defun + +@node Curses, Sockets, Line Editing, Packages +@section Curses + +@noindent +These functions are defined in @file{crs.c} using the @dfn{curses} +library. Unless otherwise noted these routines return @code{#t} for +successful completion and @code{#f} for failure. + +@defun initscr +Returns a port for a full screen window. This routine must be called to +initialize curses. +@end defun + +@defun endwin +A program should call @code{endwin} before exiting or escaping from +curses mode temporarily, to do a system call, for example. This routine +will restore termio modes, move the cursor to the lower left corner of +the screen and reset the terminal into the proper non-visual mode. To +resume after a temporary escape, call @ref{Window Manipulation, +refresh}. +@end defun + +@menu +* Output Options Setting:: +* Terminal Mode Setting:: +* Window Manipulation:: +* Output:: +* Input:: +* Curses Miscellany:: +@end menu + +@node Output Options Setting, Terminal Mode Setting, Curses, Curses +@subsection Output Options Setting + +@noindent +These routines set options within curses that deal with output. All +options are initially @code{#f}, unless otherwise stated. It is not +necessary to turn these options off before calling @code{endwin}. + +@defun clearok win bf +If enabled (@var{bf} is @code{#t}), the next call to @code{force-output} +or @code{refresh} with @var{win} will clear the screen completely and +redraw the entire screen from scratch. This is useful when the contents +of the screen are uncertain, or in some cases for a more pleasing visual +effect. +@end defun + +@defun idlok win bf +If enabled (@var{bf} is @code{#t}), curses will consider using the +hardware ``insert/delete-line'' feature of terminals so equipped. If +disabled (@var{bf} is @code{#f}), curses will very seldom use this +feature. The ``insert/delete-character'' feature is always considered. +This option should be enabled only if your application needs +``insert/delete-line'', for example, for a screen editor. It is +disabled by default because + +``insert/delete-line'' tends to be visually annoying when used in +applications where it is not really needed. If ``insert/delete-line'' +cannot be used, curses will redraw the changed portions of all lines. +@end defun + +@defun leaveok win bf +Normally, the hardware cursor is left at the location of the window +cursor being refreshed. This option allows the cursor to be left +wherever the update happens to leave it. It is useful for +applications where the cursor is not used, since it reduces the need +for cursor motions. If possible, the cursor is made invisible when +this option is enabled. +@end defun + +@defun scrollok win bf +This option controls what happens when the cursor of window @var{win} is +moved off the edge of the window or scrolling region, either from a +newline on the bottom line, or typing the last character of the last +line. If disabled (@var{bf} is @code{#f}), the cursor is left on the +bottom line at the location where the offending character was entered. +If enabled (@var{bf} is @code{#t}), @code{force-output} is called on the +window @var{win}, and then the physical terminal and window @var{win} +are scrolled up one line. + +@emph{Note:} in order to get the physical scrolling effect on the +terminal, it is also necessary to call @code{idlok}. +@end defun + +@defun nodelay win bf +This option causes wgetch to be a non-blocking call. If no input is +ready, wgetch will return an eof-object. If disabled, wgetch will hang +until a key is pressed. +@end defun + +@node Terminal Mode Setting, Window Manipulation, Output Options Setting, Curses +@subsection Terminal Mode Setting + +@noindent +These routines set options within curses that deal with input. The +options involve using ioctl(2) and therefore interact with curses +routines. It is not necessary to turn these options off before +calling @code{endwin}. The routines in this section all return an +unspecified value. + +@defun cbreak +@defunx nocbreak +These two routines put the terminal into and out of @code{CBREAK} mode, +respectively. In @code{CBREAK} mode, characters typed by the user are +immediately available to the program and erase/kill character +processing is not performed. When in @code{NOCBREAK} mode, the tty driver +will buffer characters typed until a @key{LFD} or @key{RET} is typed. +Interrupt and flowcontrol characters are unaffected by this mode. +Initially the terminal may or may not be in @code{CBREAK} mode, as it is +inherited, therefore, a program should call @code{cbreak} or @code{nocbreak} +explicitly. Most interactive programs using curses will set @code{CBREAK} +mode. + +@emph{Note:} @code{cbreak} overrides @code{raw}. For a discussion of +how these routines interact with @code{echo} and @code{noecho} +@xref{Input, read-char}. +@end defun + +@defun raw +@defunx noraw +The terminal is placed into or out of @code{RAW} mode. @code{RAW} mode +is similar to @code{CBREAK} mode, in that characters typed are +immediately passed through to the user program. The differences are +that in @code{RAW} mode, the interrupt, quit, suspend, and flow control +characters are passed through uninterpreted, instead of generating a +signal. @code{RAW} mode also causes 8-bit input and output. The +behavior of the @code{BREAK} key depends on other bits in the terminal +driver that are not set by curses. +@end defun + +@defun echo +@defunx noecho +These routines control whether characters typed by the user are echoed +by @code{read-char} as they are typed. Echoing by the tty driver is +always disabled, but initially @code{read-char} is in @code{ECHO} mode, +so characters typed are echoed. Authors of most interactive programs +prefer to do their own echoing in a controlled area of the screen, or +not to echo at all, so they disable echoing by calling @code{noecho}. +For a discussion of how these routines interact with @code{echo} and +@code{noecho} @xref{Input, read-char}. +@end defun + +@defun nl +@defunx nonl +These routines control whether @key{LFD} is translated into @key{RET} +and @code{LFD} on output, and whether @key{RET} is translated into +@key{LFD} on input. Initially, the translations do occur. By disabling +these translations using @code{nonl}, curses is able to make better use +of the linefeed capability, resulting in faster cursor motion. +@end defun + +@defun resetty +@defunx savetty +These routines save and restore the state of the terminal modes. +@code{savetty} saves the current state of the terminal in a buffer and +@code{resetty} restores the state to what it was at the last call to +@code{savetty}. +@end defun + +@node Window Manipulation, Output, Terminal Mode Setting, Curses +@subsection Window Manipulation + +@defun newwin nlines ncols begy begx +Create and return a new window with the given number of lines (or rows), +@var{nlines}, and columns, @var{ncols}. The upper left corner of the +window is at line @var{begy}, column @var{begx}. If either @var{nlines} +or @var{ncols} is 0, they will be set to the value of +@code{LINES}-@var{begy} and @code{COLS}-@var{begx}. A new full-screen +window is created by calling @code{newwin(0,0,0,0)}. +@end defun + +@defun subwin orig nlines ncols begy begx +Create and return a pointer to a new window with the given number of +lines (or rows), @var{nlines}, and columns, @var{ncols}. The window is +at position (@var{begy}, @var{begx}) on the screen. This position is +relative to the screen, and not to the window @var{orig}. The window is +made in the middle of the window @var{orig}, so that changes made to one +window will affect both windows. When using this routine, often it will +be necessary to call @code{touchwin} or @code{touchline} on @var{orig} +before calling @code{force-output}. +@end defun + +@defun close-port win +Deletes the window @var{win}, freeing up all memory associated with it. +In the case of sub-windows, they should be deleted before the main +window @var{win}. +@end defun + +@defun refresh +@defunx force-output win +These routines are called to write output to the terminal, as most other +routines merely manipulate data structures. @code{force-output} copies +the window @var{win} to the physical terminal screen, taking into +account what is already there in order to minimize the amount of +information that's sent to the terminal (called optimization). Unless +@code{leaveok} has been enabled, the physical cursor of the terminal is +left at the location of window @var{win}'s cursor. With @code{refresh}, +the number of characters output to the terminal is returned. +@end defun + +@defun mvwin win y x +Move the window @var{win} so that the upper left corner will be at position +(@var{y}, @var{x}). If the move would cause the window @var{win} to be off the +screen, it is an error and the window @var{win} is not moved. +@end defun + +@defun overlay srcwin dstwin +@defunx overwrite srcwin dstwin + +These routines overlay @var{srcwin} on top of @var{dstwin}; that is, all +text in @var{srcwin} is copied into @var{dstwin}. @var{srcwin} and +@var{dstwin} need not be the same size; only text where the two windows +overlap is copied. The difference is that @code{overlay} is +non-destructive (blanks are not copied), while @code{overwrite} is +destructive. +@end defun + +@defun touchwin win +@defunx touchline win start count +Throw away all optimization information about which parts of the window +@var{win} have been touched, by pretending that the entire window +@var{win} has been drawn on. This is sometimes necessary when using +overlapping windows, since a change to one window will affect the other +window, but the records of which lines have been changed in the other +window will not reflect the change. @code{touchline} only pretends that +@var{count} lines have been changed, beginning with line @var{start}. +@end defun + +@defun wmove win y x +The cursor associated with the window @var{win} is moved to line (row) @var{y}, +column @var{x}. This does not move the physical cursor of the terminal +until @code{refresh} (or @code{force-output}) is called. The position +specified is relative to the upper left corner of the window @var{win}, +which is (0, 0). +@end defun + +@node Output, Input, Window Manipulation, Curses +@subsection Output + +@noindent +These routines are used to @dfn{draw} text on windows + +@defun display ch win +@defunx display str win +@defunx wadd win ch +@defunx wadd win str +The character @var{ch} or characters in @var{str} are put into the +window @var{win} at the current cursor position of the window and the +position of @var{win}'s cursor is advanced. At the right margin, an +automatic newline is performed. At the bottom of the scrolling region, +if scrollok is enabled, the scrolling region will be scrolled up one +line. + +If @var{ch} is a @key{TAB}, @key{LFD}, or backspace, the cursor will be +moved appropriately within the window @var{win}. A @key{LFD} also does a +@code{wclrtoeol} before moving. @key{TAB} characters are considered to +be at every eighth column. If @var{ch} is another control character, it +will be drawn in the @kbd{C-x} notation. (Calling @code{winch} after +adding a control character will not return the control character, but +instead will return the representation of the control character.) + +Video attributes can be combined with a character by or-ing them into +the parameter. This will result in these attributes also being set. +The intent here is that text, including attributes, can be copied from +one place to another using inch and display. See @code{standout}, +below. + +@emph{Note:} For @code{wadd} @var{ch} can be an integer and will insert +the character of the corresponding value. +@end defun + +@defun werase win +This routine copies blanks to every position in the window @var{win}. +@end defun + +@defun wclear win +This routine is like @code{werase}, but it also calls @ref{Output +Options Setting, clearok}, arranging that the screen will be cleared +completely on the next call to @code{refresh} or @code{force-output} for +window @var{win}, and repainted from scratch. +@end defun + +@defun wclrtobot win +All lines below the cursor in window @var{win} are erased. Also, the +current line to the right of the cursor, inclusive, is erased. +@end defun + +@defun wclrtoeol win +The current line to the right of the cursor, inclusive, is erased. +@end defun + +@defun wdelch win +The character under the cursor in the window @var{win} is deleted. All +characters to the right on the same line are moved to the left one +position and the last character on the line is filled with a blank. The +cursor position does not change. This does not imply use of the +hardware ``delete-character'' feature. +@end defun + +@defun wdeleteln win +The line under the cursor in the window @var{win} is deleted. All lines +below the current line are moved up one line. The bottom line @var{win} +is cleared. The cursor position does not change. This does not imply +use of the hardware ``deleteline'' feature. +@end defun + +@defun winsch win ch +The character @var{ch} is inserted before the character under the +cursor. All characters to the right are moved one @key{SPC} to the +right, possibly losing the rightmost character of the line. The cursor +position does not change . This does not imply use of the hardware +``insertcharacter'' feature. +@end defun + +@defun winsertln win +A blank line is inserted above the current line and the bottom line is +lost. This does not imply use of the hardware ``insert-line'' feature. +@end defun + +@defun scroll win +The window @var{win} is scrolled up one line. This involves moving the +lines in @var{win}'s data structure. As an optimization, if @var{win} +is stdscr and the scrolling region is the entire window, the physical +screen will be scrolled at the same time. +@end defun + +@node Input, Curses Miscellany, Output, Curses +@subsection Input + +@defun read-char win +A character is read from the terminal associated with the window +@var{win}. Depending on the setting of @code{cbreak}, this will be +after one character (@code{CBREAK} mode), or after the first newline +(@code{NOCBREAK} mode). Unless @code{noecho} has been set, the +character will also be echoed into @var{win}. + +When using @code{read-char}, do not set both @code{NOCBREAK} mode +(@code{nocbreak}) and @code{ECHO} mode (@code{echo}) at the same time. +Depending on the state of the terminal driver when each character is +typed, the program may produce undesirable results. +@end defun + +@defun winch win +The character, of type chtype, at the current position in window +@var{win} is returned. If any attributes are set for that position, +their values will be OR'ed into the value returned. +@end defun + +@defun getyx win +A list of the y and x coordinates of the cursor position of the window +@var{win} is returned +@end defun + +@node Curses Miscellany, , Input, Curses +@subsection Curses Miscellany + +@defun wstandout win +@defunx wstandend win + +These functions set the current attributes of the window @var{win}. The +current attributes of @var{win} are applied to all characters that are +written into it. Attributes are a property of the character, and move +with the character through any scrolling and insert/delete +line/character operations. To the extent possible on the particular +terminal, they will be displayed as the graphic rendition of characters +put on the screen. + +@code{wstandout} sets the current attributes of the window @var{win} to +be visibly different from other text. @code{wstandend} turns off the +attributes. +@end defun + +@defun box win vertch horch +A box is drawn around the edge of the window @var{win}. @var{vertch} +and @var{horch} are the characters the box is to be drawn with. If +@var{vertch} and @var{horch} are 0, then appropriate default characters, +@code{ACS_VLINE} and @code{ACS_HLINE}, will be used. + +@emph{Note:} @var{vertch} and @var{horch} can be an integers and will +insert the character (with attributes) of the corresponding values. +@end defun + +@defun unctrl c +This macro expands to a character string which is a printable +representation of the character @var{c}. Control characters are +displayed in the @kbd{C-x} notation. Printing characters are displayed +as is. +@end defun + +@node Sockets, , Curses, Packages +@section Sockets + +@noindent +These procedures (defined in @file{socket.c}) provide a Scheme interface +to most of the C @dfn{socket} library. For more information on sockets, +@xref{Sockets, , , libc, The GNU C Library Reference Manual}. + +@menu +* Host Data:: +* Internet Addresses and Socket Names:: +* Socket:: +@end menu + +@node Host Data, Internet Addresses and Socket Names, Sockets, Sockets +@subsection Host Data, Network, Protocol, and Service Inquiries + +@defvr Constant af_inet +@defvrx Constant af_unix +Integer family codes for Internet and Unix sockets, respectively. +@end defvr + +@defun gethost host-spec +@defunx gethost +Returns a vector of information for the entry for @code{HOST-SPEC} or the +next entry if @code{HOST-SPEC} isn't given. The information is: + +@enumerate 0 +@item +host name string +@item +list of host aliases strings +@item +integer address type (@code{AF_INET}) +@item +integer size of address entries (in bytes) +@item +list of integer addresses +@end enumerate +@end defun + +@defun sethostent stay-open +@defunx sethostent +Rewinds the host entry table back to the begining if given an argument. +If the argument @var{stay-open} is @code{#f} queries will be be done +using @code{UDP} datagrams. Otherwise, a connected @code{TCP} socket +will be used. When called without an argument, the host table is +closed. +@end defun + +@defun getnet name-or-number +@defunx getnet +Returns a vector of information for the entry for @var{name-or-number} or +the next entry if an argument isn't given. The information is: + +@enumerate 0 +@item +official network name string +@item +list of network aliases strings +@item +integer network address type (@code{AF_INET}) +@item +integer network number +@end enumerate +@end defun + +@defun setnetent stay-open +@defunx setnetent +Rewinds the network entry table back to the begining if given an +argument. If the argument @var{stay-open} is @code{#f} the table will be closed +between calls to getnet. Otherwise, the table stays open. When +called without an argument, the network table is closed. +@end defun + +@defun getproto name-or-number +@defunx getproto +Returns a vector of information for the entry for @var{name-or-number} or +the next entry if an argument isn't given. The information is: + +@enumerate +@item +official protocol name string +@item +list of protocol aliases strings +@item +integer protocol number +@end enumerate +@end defun + +@defun setprotoent stay-open +@defunx setprotoent +Rewinds the protocol entry table back to the begining if given an +argument. If the argument @var{stay-open} is @code{#f} the table will be closed +between calls to getproto. Otherwise, the table stays open. When +called without an argument, the protocol table is closed. +@end defun + +@defun getserv name-or-port-number protocol +@defunx getserv +Returns a vector of information for the entry for @var{name-or-port-number} +and @var{protocol} or the next entry if arguments aren't given. The +information is: + +@enumerate 0 +@item +official service name string +@item +list of service aliases strings +@item +integer port number +@item +protocol +@end enumerate +@end defun + +@defun setservent stay-open +@defunx setservent +Rewinds the service entry table back to the begining if given an +argument. If the argument @var{stay-open} is @code{#f} the table will be closed +between calls to getserv. Otherwise, the table stays open. When +called without an argument, the service table is closed. +@end defun + +@node Internet Addresses and Socket Names, Socket, Host Data, Sockets +@subsection Internet Addresses and Socket Names + +@defun inet:string->address string +Returns the host address number (integer) for host @var{string} or +@code{#f} if not found. +@end defun + +@defun inet:address->string address +Converts an internet (integer) address to a string in numbers and dots +notation. This is an inverse function to inet:address. +@end defun + +@defun inet:network address +Returns the network number (integer) specified from @var{address} or +@code{#f} if not found. +@end defun + +@defun inet:local-network-address address +Returns the integer for the address of @var{address} within its local +network or @code{#f} if not found. +@end defun + +@defun inet:make-address network local-address +Returns the Internet address of @var{local-address} in @var{network}. +@end defun + +@noindent +The type @dfn{socket-name} is used for inquiries about open sockets in +the following procedures: + +@defun getsockname socket +Returns the socket-name of @var{socket}. Returns @code{#f} if +unsuccessful or @var{socket} is closed. +@end defun + +@defun getpeername socket +Returns the socket-name of the socket connected to @var{socket}. +Returns @code{#f} if unsuccessful or @var{socket} is closed. +@end defun + +@defun socket-name:family socket-name +Returns the integer code for the family of @var{socket-name}. +@end defun + +@defun socket-name:port-number socket-name +Returns the integer port number of @var{socket-name}. +@end defun + +@defun socket-name:address socket-name +Returns the integer Internet address for @var{socket-name}. +@end defun + + +@node Socket, , Internet Addresses and Socket Names, Sockets +@subsection Socket + +@noindent +When a port is returned from one of these calls it is unbuffered. +This allows both reading and writing to the same port to work. If you +want buffered ports you can (assuming sock-port is a socket i/o port): +@example +(require 'i/o-extensions) +(define i-port (duplicate-port sock-port "r")) +(define o-port (duplicate-port sock-port "w")) +@end example + +@defun make-stream-socket family +@defunx make-stream-socket family protocol + +Returns a @code{SOCK_STREAM} socket of type @var{family} using +@var{protocol}. If @var{family} has the value @code{AF_INET}, +@code{SO_REUSEADDR} will be set. The integer argument @var{protocol} +corresponds to the integer protocol numbers returned (as vector +elements) from @code{(getproto)}. If the @var{protocol} argument is not +supplied, the default (0) for the specified @var{family} is used. SCM +sockets look like ports opened for neither reading nor writing. +@end defun + +@defun make-stream-socketpair family +@defunx make-stream-socketpair family protocol + +Returns a pair (cons) of connected @code{SOCK_STREAM} (socket) ports of +type @var{family} using @var{protocol}. Many systems support only +socketpairs of the @code{af-unix} @var{family}. The integer argument +@var{protocol} corresponds to the integer protocol numbers returned (as +vector elements) from (getproto). If the @var{protocol} argument is +not supplied, the default (0) for the specified @var{family} is used. +@end defun + +@defun socket:shutdown socket how +Makes @var{socket} no longer respond to some or all operations depending on +the integer argument @var{how}: + +@enumerate 0 +@item +Further input is disallowed. +@item +Further output is disallowed. +@item +Further input or output is disallowed. +@end enumerate + +@code{Socket:shutdown} returns @var{socket} if successful, @code{#f} if +not. +@end defun + +@defun socket:connect inet-socket host-number port-number +@defunx socket:connect unix-socket pathname +Returns @var{socket} (changed to a read/write port) connected to the +Internet socket on host @var{host-number}, port @var{port-number} or +the Unix socket specified by @var{pathname}. Returns @code{#f} if not +successful. +@end defun + +@defun socket:bind inet-socket port-number +@defunx socket:bind unix-socket pathname +Returns @var{inet-socket} bound to the integer @var{port-number} or the +@var{unix-socket} bound to new socket in the file system at location +@var{pathname}. Returns @code{#f} if not successful. Binding a +@var{unix-socket} creates a socket in the file system that must be +deleted by the caller when it is no longer needed (using +@code{delete-file}). +@end defun + +@defun socket:listen socket backlog +The bound (@pxref{Socket, bind}) @var{socket} is readied to +accept connections. The positive integer @var{backlog} specifies how +many pending connections will be allowed before further connection +requests are refused. Returns @var{socket} (changed to a read-only +port) if successful, @code{#f} if not. +@end defun + +@defun char-ready? listen-socket +The input port returned by a successful call to @code{socket:listen} can +be polled for connections by @code{char-ready?} (@pxref{Files and Ports, +char-ready?}). This avoids blocking on connections by +@code{socket:accept}. +@end defun + +@defun socket:accept socket +Accepts a connection on a bound, listening @var{socket}. Returns an +input/output port for the connection. +@end defun + +@noindent +The following example is not too complicated, yet shows the use of +sockets for multiple connections without input blocking. + +@example +;;;; Scheme chat server + +;;; This program implements a simple `chat' server which accepts +;;; connections from multiple clients, and sends to all clients any +;;; characters received from any client. + +;;; To connect to chat `telnet localhost 8001' + +(require 'socket) +(require 'i/o-extensions) + +(let ((listener-socket (socket:bind (make-stream-socket af_inet) 8001)) + (connections '())) + (socket:listen listener-socket 5) + (do () (#f) + (cond ((char-ready? listener-socket) + (let ((con (socket:accept listener-socket))) + (display "accepting connection from ") + (display (getpeername con)) + (newline) + (set! connections (cons con connections)) + (display "connected" con) + (newline con)))) + (set! connections + (let next ((con-list connections)) + (cond ((null? con-list) '()) + (else + (let ((con (car con-list))) + (cond ((char-ready? con) + (let ((c (read-char con))) + (cond ((eof-object? c) + (display "closing connection from ") + (display (getpeername con)) + (newline) + (close-port con) + (next (cdr con-list))) + (else + (for-each (lambda (con) + (file-set-position con 0) + (write-char c con) + (file-set-position con 0)) + connections) + (cons con (next (cdr con-list))))))) + (else (cons con (next (cdr con-list)))))))))))) +@end example + +@noindent +You can use @samp{telnet localhost 8001} to connect to the chat server, +or you can use a client written in scheme: + +@example +;;;; Scheme chat client + +;;; this program connects to socket 8001. It then sends all +;;; characters from current-input-port to the socket and sends all +;;; characters from the socket to current-output-port. + +(require 'socket) +(require 'i/o-extensions) + +(define con (make-stream-socket af_inet)) +(set! con (socket:connect con (inet:string->address "localhost") 8001)) + +(do ((cs #f (and (char-ready? con) (read-char con))) + (ct #f (and (char-ready?) (read-char)))) + ((or (eof-object? cs) (eof-object? ct)) + (close-port con)) + (cond (cs (display cs))) + (cond (ct (file-set-position con 0) + (display ct con) + (file-set-position con 0)))) +@end example + + +@node The Implementation, Procedure and Macro Index, Packages, Top +@chapter The Implementation + +@menu +* Data Types:: +* Operations:: +* Improvements To Make:: +* Finishing Dynamic Linking:: +@end menu + +@node Data Types, Operations, The Implementation, The Implementation +@section Data Types + +@noindent +In the descriptions below it is assumed that @code{long int}s are 32 +bits in length. Acutally, SCM is written to work with any @code{long +int} size larger than 31 bits. With some modification, SCM could work +with word sizes as small as 24 bits. + +@noindent +All SCM objects are represented by type @dfn{SCM}. Type @code{SCM} come +in 2 basic flavors, Immediates and Cells: + +@menu +* Immediates:: +* Cells:: Non-Immediate types +* Header Cells:: Malloc objects +* Subr Cells:: Built-in and Compiled Procedures +* Ptob Cells:: I/O ports +* Smob Cells:: Miscellaneous datatypes +* Data Type Representations:: How they all fit together +@end menu + +@node Immediates, Cells, Data Types, Data Types +@subsection Immediates + +@noindent +An @dfn{immediate} is a data type contained in type @code{SCM} +(@code{long int}). The type codes distinguishing immediate types from +each other vary in length, but reside in the low order bits. + +@defmac IMP x +@defmacx NIMP x +Return non-zero if the @code{SCM} object @var{x} is an immediate or +non-immediate type, respectively. +@end defmac + +@deftp Immediate inum +immediate 30 bit signed integer. An INUM is flagged by a @code{1} in +the second to low order bit position. The high order 30 bits are used +for the integer's value. + +@defmac INUMP x +@defmacx NINUMP x +Return non-zero if the @code{SCM} @var{x} is an immediate integer or not +an immediate integer, respectively. +@end defmac + +@defmac INUM x +Returns the C @code{long integer} corresponding to @code{SCM} @var{x}. +@end defmac + +@defmac MAKINUM x +Returns the @code{SCM} inum corresponding to C @code{long integer} x. +@end defmac + +@defvr {Immediate Constant} INUM0 +is equivalent to @code{MAKINUM(0)}. +@end defvr + +Computations on INUMs are performed by converting the arguments to C +integers (by a shift), operating on the integers, and converting the +result to an inum. The result is checked for overflow by converting +back to integer and checking the reverse operation. + +The shifts used for conversion need to be signed shifts. If the C +implementation does not support signed right shift this fact is detected +in a #if statement in @file{scmfig.h} and a signed right shift, +@code{SRS}, is constructed in terms of unsigned right shift. +@end deftp + +@deftp Immediate ichr +characters. + +@defmac ICHRP x +Return non-zero if the @code{SCM} object @var{x} is a character. +@end defmac + +@defmac ICHR x +Returns corresponding @code{unsigned char}. +@end defmac + +@defmac MAKICHR x +Given @code{char} @var{x}, returns @code{SCM} character. +@end defmac + +@end deftp + +@deftp Immediate iflags +These are frequently used immediate constants. +@deftypevr {Immediate Constant} SCM BOOL_T +@code{#t} +@end deftypevr +@deftypevr {Immediate Constant} SCM BOOL_F +@code{#f} +@end deftypevr +@deftypevr {Immediate Constant} SCM EOL +@code{()}. If @code{SICP} is @code{#define}d, @code{EOL} is +@code{#define}d to be identical with @code{BOOL_F}. In this case, both +print as @code{#f}. +@end deftypevr +@deftypevr {Immediate Constant} SCM EOF_VAL +end of file token, @code{#<eof>}. +@end deftypevr +@deftypevr {Immediate Constant} SCM UNDEFINED +@code{#<undefined>} used for variables which have not been defined and +absent optional arguments. +@end deftypevr +@deftypevr {Immediate Constant} SCM UNSPECIFIED +@code{#<unspecified>} is returned for those procedures whose return +values are not specified. +@end deftypevr + +@end deftp + +@defmac IFLAGP n +Returns non-zero if @var{n} is an ispcsym, isym or iflag. +@end defmac + +@defmac ISYMP n +Returns non-zero if @var{n} is an ispcsym or isym. +@end defmac + +@defmac ISYMNUM n +Given ispcsym, isym, or iflag @var{n}, returns its index in the C array +@code{isymnames[]}. +@end defmac + +@defmac ISYMCHARS n +Given ispcsym, isym, or iflag @var{n}, returns its @code{char *} +representation (from @code{isymnames[]}). +@end defmac + +@defmac MAKSPCSYM n +Returns @code{SCM} ispcsym @var{n}. +@end defmac + +@defmac MAKISYM n +Returns @code{SCM} iisym @var{n}. +@end defmac + +@defmac MAKIFLAG n +Returns @code{SCM} iflag @var{n}. +@end defmac + +@defvar isymnames +An array of strings containing the external representations of all the +ispcsym, isym, and iflag immediates. Defined in @file{repl.c}. +@end defvar + +@defvr Constant NUM_ISPCSYM +@defvrx Constant NUM_ISYMS +The number of ispcsyms and ispcsyms+isyms, respectively. Defined in +@file{scm.h}. +@end defvr + +@deftp Immediate isym +@code{and}, @code{begin}, @code{case}, @code{cond}, @code{define}, +@code{do}, @code{if}, @code{lambda}, @code{let}, @code{let*}, +@code{letrec}, @code{or}, @code{quote}, @code{set!}, @code{#f}, +@code{#t}, @code{#<undefined>}, @code{#<eof>}, @code{()}, and +@code{#<unspecified>}. + +@deftpx {CAR Immediate} ispcsym +special symbols: syntax-checked versions of first 14 isyms +@end deftp + +@deftp {CAR Immediate} iloc +indexes to a variable's location in environment +@end deftp + +@deftp {CAR Immediate} gloc +pointer to a symbol's value cell +@end deftp + +@deftp Immediate CELLPTR +pointer to a cell (not really an immediate type, but here for +completeness). Since cells are always 8 byte aligned, a pointer to a +cell has the low order 3 bits @code{0}. + +There is one exception to this rule, @emph{CAR Immediate}s, described +next. +@end deftp + +@noindent +A @dfn{CAR Immediate} is an Immediate point which can only occur in the +@code{CAR}s of evaluated code (as a result of @code{ceval}'s memoization +process). + +@node Cells, Header Cells, Immediates, Data Types +@subsection Cells + +@noindent +@dfn{Cell}s represent all SCM objects other than immediates. A cell has +a @code{CAR} and a @code{CDR}. Low-order bits in @code{CAR} identify +the type of object. The rest of @code{CAR} and @code{CDR} hold object +data. The number after @code{tc} specifies how many bits are in the +type code. For instance, @code{tc7} indicates that the type code is 7 +bits. + +@defmac NEWCELL x +Allocates a new cell and stores a pointer to it in @code{SCM} local +variable @var{x}. + +Care needs to be taken that stores into the new cell pointed to by +@var{x} do not create an inconsistent object. @xref{Signals}. +@end defmac + +@noindent +All of the C macros decribed in this section assume that their argument +is of type @code{SCM} and points to a cell (@code{CELLPTR}). + +@defmac CAR x +@defmacx CDR x +Returns the @code{car} and @code{cdr} of cell @var{x}, respectively. +@end defmac + +@defmac TYP3 x +@defmacx TYP7 x +@defmacx TYP16 x +Returns the 3, 7, and 16 bit type code of a cell. +@end defmac + +@deftp Cell tc3_cons +scheme cons-cell returned by (cons arg1 arg2). + +@defmac CONSP x +@defmacx NCONSP x +Returns non-zero if @var{x} is a @code{tc3_cons} or isn't, respectively. +@end defmac +@end deftp + +@deftp Cell tc3_closure +applicable object returned by (lambda (args) @dots{}). +@code{tc3_closure}s have a pointer to other the body of the procedure in +the @code{CAR} and a pointer to the environment in the @code{CDR}. + +@defmac CLOSUREP x +Returns non-zero if @var{x} is a @code{tc3_closure}. +@end defmac + +@defmac CODE x +@defmacx ENV x +Returns the code body or environment of closure @var{x}, respectively. +@end defmac + +@end deftp + +@node Header Cells, Subr Cells, Cells, Data Types +@subsection Header Cells + +@noindent +@dfn{Header}s are Cells whose @code{CDR}s point elsewhere in memory, +such as to memory allocated by @code{malloc}. + +@deftp Header spare +spare @code{tc7} type code +@end deftp + +@deftp Header tc7_vector +scheme vector. + +@defmac VECTORP x +@defmacx NVECTORP x +Returns non-zero if @var{x} is a @code{tc7_vector} or if not, respectively. +@end defmac + +@defmac VELTS x +@defmacx LENGTH x +Returns the C array of @code{SCM}s holding the elements of vector +@var{x} or its length, respectively. +@end defmac +@end deftp + +@deftp Header tc7_ssymbol +static scheme symbol (part of initial system) + +@deftpx Header tc7_msymbol +@code{malloc}ed scheme symbol (can be GCed) + +@defmac SYMBOLP x +Returns non-zero if @var{x} is a @code{tc7_ssymbol} or +@code{tc7_msymbol}. +@end defmac + +@defmac CHARS x +@defmacx UCHARS x +@defmacx LENGTH x +Returns the C array of @code{char}s or as @code{unsigned char}s holding +the elements of symbol @var{x} or its length, respectively. +@end defmac +@end deftp + +@deftp Header tc7_string +scheme string + +@defmac STRINGP x +@defmacx NSTRINGP x +Returns non-zero if @var{x} is a @code{tc7_string} or isn't, +respectively. +@end defmac + +@defmac CHARS x +@defmacx UCHARS x +@defmacx LENGTH x +Returns the C array of @code{char}s or as @code{unsigned char}s holding +the elements of string @var{x} or its length, respectively. +@end defmac +@end deftp + +@deftp Header tc7_bvect +uniform vector of booleans (bit-vector) +@end deftp + +@deftp Header tc7_ivect +uniform vector of integers +@end deftp + +@deftp Header tc7_uvect +uniform vector of non-negative integers +@end deftp + +@deftp Header tc7_fvect +uniform vector of short inexact real numbers +@end deftp + +@deftp Header tc7_dvect +uniform vector of double precision inexact real numbers +@end deftp + +@deftp Header tc7_cvect +uniform vector of double precision inexact complex numbers +@end deftp + +@deftp Header tc7_contin +applicable object produced by call-with-current-continuation +@end deftp + +@deftp Header tc7_cclo +Subr and environment for compiled closure + +A cclo is similar to a vector (and is GCed like one), but can be applied +as a function: + +@enumerate +@item +the cclo itself is consed onto the head of the argument list +@item +the first element of the cclo is applied to that list. Cclo invocation +is currently not tail recursive when given 2 or more arguments. +@end enumerate + +@defun makcclo proc len +makes a closure from the @emph{subr} @var{proc} with @var{len}-1 extra +locations for @code{SCM} data. Elements of a @var{cclo} are referenced +using @code{VELTS(cclo)[n]} just as for vectors. +@end defun +@end deftp + +@node Subr Cells, Ptob Cells, Header Cells, Data Types +@subsection Subr Cells + +@noindent +A @dfn{Subr} is a header whose @code{CDR} points to a C code procedure. +Scheme primitive procedures are subrs. Except for the arithmetic +@code{tc7_cxr}s, the C code procedures will be passed arguments (and +return results) of type @code{SCM}. + +@deftp Subr tc7_asubr +associative C function of 2 arguments. Examples are @code{+}, @code{-}, +@code{*}, @code{/}, @code{max}, and @code{min}. +@end deftp + +@deftp Subr tc7_subr_0 +C function of no arguments. +@end deftp + +@deftp Subr tc7_subr_1 +C function of one argument. +@end deftp + +@deftp Subr tc7_cxr +These subrs are handled specially. If inexact numbers are enabled, the +@code{CDR} should be a function which takes and returns type +@code{double}. Conversions are handled in the interpreter. + +@code{floor}, @code{ceiling}, @code{truncate}, @code{round}, +@code{$sqrt}, @code{$abs}, @code{$exp}, @code{$log}, @code{$sin}, +@code{$cos}, @code{$tan}, @code{$asin}, @code{$acos}, @code{$atan}, +@code{$sinh}, @code{$cosh}, @code{$tanh}, @code{$asinh}, @code{$acosh}, +@code{$atanh}, and @code{exact->inexact} are defined this way. + +If the @code{CDR} is @code{0} (@code{NULL}), the name string of the +procedure is used to control traversal of its list structure argument. + +@code{car}, @code{cdr}, @code{caar}, @code{cadr}, @code{cdar}, +@code{cddr}, @code{caaar}, @code{caadr}, @code{cadar}, @code{caddr}, +@code{cdaar}, @code{cdadr}, @code{cddar}, @code{cdddr}, @code{caaaar}, +@code{caaadr}, @code{caadar}, @code{caaddr}, @code{cadaar}, +@code{cadadr}, @code{caddar}, @code{cadddr}, @code{cdaaar}, +@code{cdaadr}, @code{cdadar}, @code{cdaddr}, @code{cddaar}, +@code{cddadr}, @code{cdddar}, and @code{cddddr} are defined this way. +@end deftp + +@deftp Subr tc7_subr_3 +C function of 3 arguments. +@end deftp + +@deftp Subr tc7_subr_2 +C function of 2 arguments. +@end deftp + +@deftp Subr tc7_rpsubr +transitive relational predicate C function of 2 arguments. The C +function should return either @code{BOOL_T} or @code{BOOL_F}. +@end deftp + +@deftp Subr tc7_subr_1o +C function of one optional argument. If the optional argument is not +present, @code{UNDEFINED} is passed in its place. +@end deftp + +@deftp Subr tc7_subr_2o +C function of 1 required and 1 optional argument. If the optional +argument is not present, @code{UNDEFINED} is passed in its place. +@end deftp + +@deftp Subr tc7_lsubr_2 +C function of 2 arguments and a list of (rest of) @code{SCM} arguments. +@end deftp + +@deftp Subr tc7_lsubr +C function of list of @code{SCM} arguments. +@end deftp + +@node Ptob Cells, Smob Cells, Subr Cells, Data Types +@subsection Ptob Cells + +@noindent +A @dfn{ptob} is a port object, capable of delivering or accepting +characters. @xref{Ports, , , r4rs, Revised(4) Report on the Algorithmic +Language Scheme}. Unlike the types described so far, new varieties of +ptobs can be defined dynamically (@pxref{Defining Ptobs}). These are +the initial ptobs: + +@deftp ptob tc16_inport +input port. +@end deftp + +@deftp ptob tc16_outport +output port. +@end deftp + +@deftp ptob tc16_ioport +input-output port. +@end deftp + +@deftp ptob tc16_inpipe +input pipe created by @code{popen()}. +@end deftp + +@deftp ptob tc16_outpipe +output pipe created by @code{popen()}. +@end deftp + +@deftp ptob tc16_strport +String port created by @code{cwos()} or @code{cwis()}. +@end deftp + +@deftp ptob tc16_sfport +Software (virtual) port created by @code{mksfpt()} (@pxref{Soft Ports}). +@end deftp + +@defmac PORTP x +@defmacx OPPORTP x +@defmacx OPINPORTP x +@defmacx OPOUTPORTP x +@defmacx INPORTP x +@defmacx OUTPORTP x +Returns non-zero if @var{x} is a port, open port, open input-port, open +output-port, input-port, or output-port, respectively. +@end defmac + +@defmac OPENP x +@defmacx CLOSEDP x +Returns non-zero if port @var{x} is open or closed, respectively. +@end defmac + +@defmac STREAM x +Returns the @code{FILE *} stream for port @var{x}. +@end defmac + +@noindent +Ports which are particularly well behaved are called @dfn{fport}s. +Advanced operations like @code{file-position} and @code{reopen-file} +only work for fports. + +@defmac FPORTP x +@defmacx OPFPORTP x +@defmacx OPINFPORTP x +@defmacx OPOUTFPORTP x +Returns non-zero if @var{x} is a port, open port, open input-port, or +open output-port, respectively. +@end defmac + +@node Smob Cells, Data Type Representations, Ptob Cells, Data Types +@subsection Smob Cells + +@noindent +A @dfn{smob} is a miscellaneous datatype. The type code and GCMARK bit +occupy the lower order 16 bits of the @code{CAR} half of the cell. The +rest of the @code{CAR} can be used for sub-type or other information. +The @code{CDR} contains data of size long and is often a pointer to +allocated memory. + +@noindent +Like ptobs, new varieties of smobs can be defined dynamically +(@pxref{Defining Smobs}). These are the initial smobs: + +@deftp smob tc_free_cell +unused cell on the freelist. +@end deftp + +@deftp smob tc16_flo +single-precision float. + +Inexact number data types are subtypes of type @code{tc16_flo}. If the +sub-type is: + +@enumerate 0 +@item +a single precision float is contained in the @code{CDR}. +@item +@code{CDR} is a pointer to a @code{malloc}ed double. +@end enumerate +@enumerate 3 +@item +@code{CDR} is a pointer to a @code{malloc}ed pair of doubles. +@end enumerate + +@deftp smob tc_dblr +double-precision float. +@end deftp + +@deftp smob tc_dblc +double-precision complex. +@end deftp +@end deftp + +@deftp smob tc16_bigpos +@deftpx smob tc16_bigneg +positive and negative bignums, respectively. + +Scm has large precision integers called bignums. They are stored in +sign-magnitude form with the sign occuring in the type code of the SMOBs +bigpos and bigneg. The magnitude is stored as a @code{malloc}ed array +of type @code{BIGDIG} which must be an unsigned integral type with size +smaller than @code{long}. @code{BIGRAD} is the radix associated with +@code{BIGDIG}. +@end deftp + +@deftp smob tc16_promise +made by DELAY. @xref{Control features, , , r4rs, Revised(4) Scheme}. +@end deftp + +@deftp smob tc16_arbiter +synchronization object. @xref{Process Synchronization}. +@end deftp + +@deftp smob tc16_macro +macro expanding function. @xref{Low Level Syntactic Hooks}. +@end deftp + +@deftp smob tc16_array +multi-dimensional array. @xref{Arrays}. + +This type implements both conventional arrays (those with arbitrary data +as elements @pxref{Conventional Arrays}) and uniform arrays (those with +elements of a uniform type @pxref{Uniform Array}). + +Conventional Arrays have a pointer to a vector for their @code{CDR}. +Uniform Arrays have a pointer to a Uniform Vector type (string, bvect, +ivect, uvect, fvect, dvect, or cvect) in their @code{CDR}. +@end deftp + + +@node Data Type Representations, , Smob Cells, Data Types +@subsection Data Type Representations + +@format +@r{IMMEDIATE: B,D,E,F=data bit, C=flag code, P=pointer address bit} +@t{ ................................ +inum BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB10 +ichr BBBBBBBBBBBBBBBBBBBBBBBB11110100 +iflag CCCCCCC101110100 +isym CCCCCCC001110100} +@r{ IMCAR: only in car of evaluated code, cdr has cell's GC bit} +@t{ispcsym 000CCCC00CCCC100 +iloc 0DDDDDDDDDDDDDDDEFFFFFFF11111100 +pointer PPPPPPPPPPPPPPPPPPPPPPPPPPPPP000 +gloc PPPPPPPPPPPPPPPPPPPPPPPPPPPPP001} + +@r{ HEAP CELL: G=gc_mark; 1 during mark, 0 other times. + 1s and 0s here indicate type. G missing means sys (not GC'd) + SIMPLE:} +@t{cons ..........SCM car..............0 ...........SCM cdr.............G +closure ..........SCM code...........011 ...........SCM env.............G + HEADERs: +ssymbol .........long length....G0000101 ..........char *chars........... +msymbol .........long length....G0000111 ..........char *chars........... +string .........long length....G0001101 ..........char *chars........... +vector .........long length....G0001111 ...........SCM **elts........... +bvect .........long length....G0010101 ..........long *words........... + spare G0010111 +ivect .........long length....G0011101 ..........long *words........... +uvect .........long length....G0011111 ......unsigned long *words...... + spare G0100101 + spare G0100111 +fvect .........long length....G0101101 .........float *words........... +dvect .........long length....G0101111 ........double *words........... +cvect .........long length....G0110101 ........double *words........... + +contin .........long length....G0111101 .............*regs.............. +cclo .........long length....G0111111 ...........SCM **elts...........} +@r{ SUBRs:} +@t{ spare 010001x1 + spare 010011x1 +subr_0 ..........int hpoff.....01010101 ...........SCM (*f)()........... +subr_1 ..........int hpoff.....01010111 ...........SCM (*f)()........... +cxr ..........int hpoff.....01011101 .........double (*f)().......... +subr_3 ..........int hpoff.....01011111 ...........SCM (*f)()........... +subr_2 ..........int hpoff.....01100101 ...........SCM (*f)()........... +asubr ..........int hpoff.....01100111 ...........SCM (*f)()........... +subr_1o ..........int hpoff.....01101101 ...........SCM (*f)()........... +subr_2o ..........int hpoff.....01101111 ...........SCM (*f)()........... +lsubr_2 ..........int hpoff.....01110101 ...........SCM (*f)()........... +lsubr_2n..........int hpoff.....01110111 ...........SCM (*f)()........... +rpsubr ..........int hpoff.....01111101 ...........SCM (*f)()...........} +@r{ PTOBs:} +@t{ port 0bwroxxxxxxxxG1110111 ..........FILE *stream.......... + socket ttttttt 00001xxxxxxxxG1110111 ..........FILE *stream.......... + inport uuuuuuuuuuU00011xxxxxxxxG1110111 ..........FILE *stream.......... +outport 0000000000000101xxxxxxxxG1110111 ..........FILE *stream.......... + ioport uuuuuuuuuuU00111xxxxxxxxG1110111 ..........FILE *stream.......... +fport 00 00000000G1110111 ..........FILE *stream.......... +pipe 00 00000001G1110111 ..........FILE *stream.......... +strport 00 00000010G1110111 ..........FILE *stream.......... +sfport 00 00000011G1110111 ..........FILE *stream..........} +@r{ SMOBs:} +@t{free_cell + 000000000000000000000000G1111111 ...........*free_cell........000 +flo 000000000000000000000001G1111111 ...........float num............ +dblr 000000000000000100000001G1111111 ..........double *real.......... +dblc 000000000000001100000001G1111111 .........complex *cmpx.......... +bignum ...int length...0000001 G1111111 .........short *digits.......... +bigpos ...int length...00000010G1111111 .........short *digits.......... +bigneg ...int length...00000011G1111111 .........short *digits.......... + xxxxxxxx = code assigned by newsmob(); +promise 000000000000000fxxxxxxxxG1111111 ...........SCM val.............. +arbiter 000000000000000lxxxxxxxxG1111111 ...........SCM name............. +macro 000000000000000mxxxxxxxxG1111111 ...........SCM name............. +array ...short rank..cxxxxxxxxG1111111 ............*array..............} +@end format + +@node Operations, Improvements To Make, Data Types, The Implementation +@section Operations + +@menu +* Garbage Collection:: Automatically reclaims unused storage +* Signals:: +* C Macros:: +* Changing Scm:: +* Defining Subrs:: +* Defining Smobs:: +* Defining Ptobs:: +* Calling Scheme From C:: +* Callbacks:: +* Type Conversions:: For use with C code. +* Continuations:: For C and SCM +* Evaluation:: Why SCM is fast +@end menu + +@node Garbage Collection, Signals, Operations, Operations +@subsection Garbage Collection + +The garbage collector is in the latter half of @file{sys.c}. The +primary goal of @dfn{garbage collection} (or @dfn{GC}) is to recycle +those cells no longer in use. Immediates always appear as parts of +other objects, so they are not subject to explicit garbage collection. + +All cells reside in the @dfn{heap} (composed of @dfn{heap segments}). +Note that this is different from what Computer Science usually defines +as a heap. + +@menu +* Marking Cells:: +* Sweeping the Heap:: +@end menu + +@node Marking Cells, Sweeping the Heap, Garbage Collection, Garbage Collection +@subsubsection Marking Cells + +The first step in garbage collection is to @dfn{mark} all heap objects +in use. Each heap cell has a bit reserved for this purpose. For pairs +(cons cells) the lowest order bit (0) of the CDR is used. For other +types, bit 8 of the CAR is used. The GC bits are never set except +during garbage collection. Special C macros are defined in @file{scm.h} +to allow easy manipulation when GC bits are possibly set. @code{CAR}, +@code{TYP3}, and @code{TYP7} can be used on GC marked cells as they are. + +@defmac GCCDR x +Returns the CDR of a cons cell, even if that cell has been GC marked. +@end defmac +@defmac GCTYP16 x +Returns the 16 bit type code of a cell. +@end defmac + +We need to (recursively) mark only a few objects in order to assure that +all accessible objects are marked. Those objects are +@code{sys_protects[]} (for example, @code{dynwinds}), the current +C-stack and the hash table for symbols, @dfn{symhash}. + +@deftypefun void gc_mark (SCM @var{obj}) +The function @code{gc_mark()} is used for marking SCM cells. If +@var{obj} is marked, @code{gc_mark()} returns. If @var{obj} is +unmarked, gc_mark sets the mark bit in @var{obj}, then calls +@code{gc_mark()} on any SCM components of @var{obj}. The last call to +@code{gc_mark()} is tail-called (looped). +@end deftypefun + +@deftypefun void mark_locations (STACKITEM @var{x[]}, sizet @var{len})) +The function @code{mark_locations} is used for marking segments of +C-stack or saved segments of C-stack (marked continuations). The +argument @var{len} is the size of the stack in units of size +@code{(STACKITEM)}. + +Each longword in the stack is tried to see if it is a valid cell pointer +into the heap. If it is, the object itself and any objects it points to +are marked using @code{gc_mark}. If the stack is word rather than +longword aligned @code{(#define WORD_ALIGN)}, both alignments are tried. +This arrangement will occasionally mark an object which is no longer +used. This has not been a problem in practice and the advantage of +using the c-stack far outweighs it. +@end deftypefun + +@node Sweeping the Heap, , Marking Cells, Garbage Collection +@subsubsection Sweeping the Heap + +After all found objects have been marked, the heap is swept. + +The storage for strings, vectors, continuations, doubles, complexes, and +bignums is managed by malloc. There is only one pointer to each malloc +object from its type-header cell in the heap. This allows malloc +objects to be freed when the associated heap object is garbage +collected. + +@deftypefun static void gc_sweep () +The function @code{gc_sweep} scans through all heap segments. The mark +bit is cleared from marked cells. Unmarked cells are spliced into +@var{freelist}, where they can again be returned by invocations of +@code{NEWCELL}. + +If a type-header cell pointing to malloc space is unmarked, the malloc +object is freed. If the type header of smob is collected, the smob's +@code{free} procedure is called to free its storage. +@end deftypefun + +@node Signals, C Macros, Garbage Collection, Operations +@subsection Signals + +@defun init_signals +(in @file{scm.c}) initializes handlers for @code{SIGINT} and +@code{SIGALRM} if they are supported by the C implementation. All of +the signal handlers immediately reestablish themselves by a call to +@code{signal()}. +@end defun + +@defun int_signal sig +@defunx alrm_signal sig +The low level handlers for @code{SIGINT} and @code{SIGALRM}. +@end defun + +If an interrupt handler is defined when the interrupt is received, the +code is interpreted. If the code returns, execution resumes from where +the interrupt happened. @code{Call-with-current-continuation} allows +the stack to be saved and restored. + +SCM does not use any signal masking system calls. These are not a +portable feature. However, code can run uninterrupted by use of the C +macros @code{DEFER_INTS} and @code{ALLOW_INTS}. + +@defmac DEFER_INTS +sets the global variable @code{ints_disabled} to 1. If an interrupt +occurs during a time when @code{ints_disabled} is 1 one of the global +variables @code{sig_deferred} or @code{alrm_deferred} is set to 1 and +the handler returns. + +@defmacx ALLOW_INTS +Checks the deferred variables and if set the appropriate handler is +called. + +Calls to @code{DEFER_INTS} can not be nested. An @code{ALLOW_INTS} must +happen before another @code{DEFER_INTS} can be done. In order to check +that this constraint is satisfied @code{#define CAREFUL_INTS} in +@file{scmfig.h}. +@end defmac + +@node C Macros, Changing Scm, Signals, Operations +@subsection C Macros + + +@defmac ASSERT cond arg pos subr +signals an error if the expression (@var{cond}) is 0. @var{arg} is the +offending object, @var{subr} is the string naming the subr, and +@var{pos} indicates the position or type of error. @var{pos} can be one +of + +@itemize @bullet +@item @code{ARGn} @i{(> 5 or unknown ARG number)} +@item @code{ARG1} +@item @code{ARG2} +@item @code{ARG3} +@item @code{ARG4} +@item @code{ARG5} +@item @code{WNA} @i{(wrong number of args)} +@item @code{OVFLOW} +@item @code{OUTOFRANGE} +@item @code{NALLOC} +@item @code{EXIT} +@item @code{HUP_SIGNAL} +@item @code{INT_SIGNAL} +@item @code{FPE_SIGNAL} +@item @code{BUS_SIGNAL} +@item @code{SEGV_SIGNAL} +@item @code{ALRM_SIGNAL} +@item a C string @code{(char *)} +@end itemize + +Error checking is not done by @code{ASSERT} if the flag @code{RECKLESS} +is defined. An error condition can still be signaled in this case with +a call to @code{wta(arg, pos, subr)}. +@end defmac + +@defmac ASRTGO cond label +@code{goto} @var{label} if the expression (@var{cond}) is 0. Like +@code{ASSERT}, @code{ASRTGO} does is not active if the flag +@code{RECKLESS} is defined. +@end defmac + + +@node Changing Scm, Defining Subrs, C Macros, Operations +@subsection Changing Scm + +@noindent +When writing C-code for SCM, a precaution is recommended. If your +routine allocates a non-cons cell which will @emph{not} be incorporated +into a @code{SCM} object which is returned, you need to make sure that a +@code{SCM} variable in your routine points to that cell as long as part +of it might be referenced by your code. + +@noindent +In order to make sure this @code{SCM} variable does not get optimized +out you can put this assignment after its last possible use: + +@example +SCM_dummy1 = @i{foo}; +@end example + +@noindent +or put this assignment somewhere in your routine: + +@example +SCM_dummy1 = (SCM) &@i{foo}; +@end example + +@noindent +@code{SCM_dummy} variables are not currently defined. Passing the +address of the local @code{SCM} variable to @emph{any} procedure also +protects it. + +@noindent +Also, if you maintain a static pointer to some (non-immediate) +@code{SCM} object, you must either make your pointer be the value cell +of a symbol (see @code{errobj} for an example) or make your pointer be +one of the @code{sys_protects} (see @code{dynwinds} for an example). +The former method is prefered since it does not require any changes to +the SCM distribution. + +@noindent +To add a C routine to scm: + +@enumerate +@item +choose the appropriate subr type from the type list. +@item +write the code and put into @file{scm.c}. +@item +add a @code{make_subr} or @code{make_gsubr} call to @code{init_scm}. Or +put an entry into the appropriate @code{iproc} structure. +@end enumerate + +To add a package of new procedures to scm (see @file{crs.c} for +example): + +@enumerate +@item +create a new C file (@file{@i{foo}.c}). +@item +at the front of @file{@i{foo}.c} put declarations for strings for your +procedure names. + +@example +static char s_twiddle_bits[]="twiddle-bits!"; +static char s_bitsp[]="bits?"; +@end example + +@item +choose the appropriate subr types from the type list in @file{code.doc}. +@item +write the code for the procedures and put into @file{@i{foo}.c} +@item +create one @code{iproc} structure for each subr type used in @file{@i{foo}.c} + +@example +static iproc subr3s[]= @{ + @{s_twiddle-bits,twiddle-bits@}, + @{s_bitsp,bitsp@}, + @{0,0@} @}; +@end example + +@item +create an @code{init_@i{<name of file>}} routine at the end of the file +which calls @code{init_iprocs} with the correct type for each of the +@code{iproc}s created in step 5. + +@example +void init_@i{foo}() +@{ + init_iprocs(subr1s, tc7_subr_1); + init_iprocs(subr3s, tc7_subr_3); +@} +@end example + +If your package needs to have a @dfn{finalization} routine called to +free up storage, close files, etc, then also have a line in +@code{init_@i{foo}} like: + +@example +add_final(final_@i{foo}); +@end example + +@code{final_@i{foo}} should be a (void) procedure of no arguments. The +finals will be called in opposite order from their definition. + +The line: + +@example +add_feature("@i{foo}"); +@end example + +will append a symbol @code{'@i{foo}} to the (list) value of +@code{*features*}. +@item +put any scheme code which needs to be run as part of your package into +@file{I@i{foo}.scm}. +@item +put an @code{if} into @file{Init.scm} which loads @file{I@i{foo}.scm} if +your package is included: + +@example +(if (defined? twiddle-bits!) + (load (in-vicinity (implementation-vicinity) + "I@i{foo}" + (scheme-file-suffix)))) +@end example + +or use @code{(provided? '@i{foo})} instead of @code{(defined? +twiddle-bits!)} if you have added the feature. +@item +put documentation of the new procedures into @file{@i{foo}.doc} +@item +add lines to your @file{Makefile} to compile and link SCM with your +object file. Add a @code{init_@i{foo}\(\)\;} to the @code{INITS=@dots{}} +line at the beginning of the makefile. +@end enumerate + +@noindent +These steps should allow your package to be linked into SCM with a +minimum of difficulty. Your package should also work with dynamic +linking if your SCM has this capability. + +Special forms (new syntax) can be added to scm. + +@enumerate +@item +define a new @code{MAKISYM} in @file{scm.h} and increment +@code{NUM_ISYMS}. +@item +add a string with the new name in the corresponding place in +@code{isymnames} in @file{repl.c}. +@item +add @code{case:} clause to @code{ceval()} near @code{i_quasiquote} (in +@file{eval.c}). +@end enumerate + +@noindent +New syntax can now be added without recompiling SCM by the use of the +@code{procedure->syntax}, @code{procedure->macro}, +@code{procedure->memoizing-macro}, and @code{defmacro}. For details, +@xref{Syntax Extensions}. + +@node Defining Subrs, Defining Smobs, Changing Scm, Operations +@subsection Defining Subrs + +@noindent +If @dfn{CCLO} is @code{#define}d when compiling, the compiled closure +feature will be enabled. It is automatically enabled if dynamic linking +is enabled. + +@noindent +The SCM interpreter directly recognizes subrs taking small numbers of +arguments. In order to create subrs taking larger numbers of arguments +use: + +@defun make_gsubr name req opt rest fcn +returns a cclo (compiled closure) object of name @code{char *} +@var{name} which takes @code{int} @var{req} required arguments, +@code{int} @var{opt} optional arguments, and a list of rest arguments if +@code{int} @var{rest} is 1 (0 for not). + +@code{SCM (*fcn)()} is a pointer to a C function to do the work. + +The C function will always be called with @var{req} + @var{opt} + +@var{rest} arguments, optional arguments not supplied will be passed +@code{UNDEFINED}. An error will be signaled if the subr is called with +too many or too few arguments. Currently a total of 10 arguments may be +specified, but increasing this limit should not be difficult. + +@example +/* A silly example, taking 2 required args, + 1 optional, and a list of rest args */ + +#include <scm.h> + +SCM gsubr_21l(req1,req2,opt,rst) + SCM req1,req2,opt,rst; +@{ + lputs("gsubr-2-1-l:\n req1: ", cur_outp); + display(req1,cur_outp); + lputs("\n req2: ", cur_outp); + display(req2,cur_outp); + lputs("\n opt: ", cur_outp); + display(opt,cur_outp); + lputs("\n rest: ", cur_outp); + display(rst,cur_outp); + newline(cur_outp); + return UNSPECIFIED; +@} + +void init_gsubr211() +@{ + make_gsubr("gsubr-2-1-l", 2, 1, 1, gsubr_21l); +@} +@end example +@end defun + +@node Defining Smobs, Defining Ptobs, Defining Subrs, Operations +@subsection Defining Smobs + +@noindent +Here is an example of how to add a new type named @code{@i{foo}} to SCM. +The following lines need to be added to your code: + +@table @code +@item long tc16_@i{foo}; +The type code which will be used to identify the new type. +@item static smobfuns @i{foo}smob = @{mark@i{foo},free@i{foo},print@i{foo},equalp@i{foo}@}; +smobfuns is a structure composed of 4 functions: + +@example +typedef struct @{ + SCM (*mark)P((SCM)); + sizet (*free)P((CELLPTR)); + int (*print)P((SCM exp, SCM port, int writing)); + SCM (*equalp)P((SCM, SCM)); +@} smobfuns; +@end example + +@table @code +@item smob.mark +is a function of one argument of type @code{SCM} (the cell to mark) and +returns type @code{SCM} which will then be marked. If no further +objects need to be marked then return an immediate object such as +@code{BOOL_F}. 2 functions are provided: + +@table @code +@item markcdr(ptr) +which marks the current cell and returns @code{CDR(ptr)}. +@item mark0(ptr) +which marks the current cell and returns @code{BOOL_F}. +@end table + +@item smob.free +is a function of one argument of type @code{CELLPTR} (the cell to +collected) and returns type @code{sizet} which is the number of +@code{malloc}ed bytes which were freed. @code{Smob.free} should free +any @code{malloc}ed storage associated with this object. The function +free0(ptr) is provided which does not free any storage and returns 0. +@item smob.print +is 0 or a function of 3 arguments. The first, of type @code{SCM}, is +the smob object. The second, of type @code{SCM}, is the stream on which +to write the result. The third, of type int, is 1 if the object should +be @code{write}n, 0 if it should be @code{display}ed. This function +should return non-zero if it printed, and zero otherwise (in which case +a hexadecimal number will be printed). +@item smob.equalp +is 0 or a function of 2 @code{SCM} arguments. Both of these arguments +will be of type @code{tc16@i{foo}}. This function should return +@code{BOOL_T} if the smobs are equal, @code{BOOL_F} if they are not. If +@code{smob.equalp} is 0, @code{equal?} will return @code{BOOL_F} if they +are not @code{eq?}. +@end table + +@item tc16_@i{foo} = newsmob(&@i{foo}smob); +Allocates the new type with the functions from @code{@i{foo}smob}. This +line goes in an @code{init_} routine. +@end table + +@noindent +Promises and macros in @file{eval.c} and arbiters in @file{repl.c} +provide examples of SMOBs. There are a maximum of 256 SMOBs. + +@node Defining Ptobs, Calling Scheme From C, Defining Smobs, Operations +@subsection Defining Ptobs + +@noindent +@dfn{ptob}s are similar to smobs but define new types of port to which +SCM procedures can read or write. The following functions are defined +in the @code{ptobfuns}: + +@example +typedef struct @{ + SCM (*mark)P((SCM ptr)); + int (*free)P((FILE *p)); + int (*print)P((SCM exp, SCM port, int writing)); + SCM (*equalp)P((SCM, SCM)); + int (*fputc)P((int c, FILE *p)); + int (*fputs)P((char *s, FILE *p)); + sizet (*fwrite)P((char *s, sizet siz, sizet num, FILE *p)); + int (*fflush)P((FILE *stream)); + int (*fgetc)P((FILE *p)); + int (*fclose)P((FILE *p)); +@} ptobfuns; +@end example + +@noindent +The @code{.free} component to the structure takes a @code{FILE *} or +other C construct as its argument, unlike @code{.free} in a smob, which +takes the whole smob cell. Often, @code{.free} and @code{.fclose} can be +the same function. See @code{fptob} and @code{pipob} in @file{sys.c} +for examples of how to define ptobs. + +@node Calling Scheme From C, Callbacks, Defining Ptobs, Operations +@subsection Calling Scheme From C + +@noindent +To use SCM as a whole from another program call @code{init_scm} or +@code{run_scm} as is done in @code{main()} in @file{scm.c}. + +@noindent +In order to call indivdual Scheme procedures from C code more is +required; SCM's storage system needs to be initialized. The simplest +way to do this for a statically linked single-thread program is to: + +@enumerate +@item +make a SCM procedure which calls your code's startup routine. +@item +use the @code{#define RTL} flag when compiling @file{scm.c} to elide +SCM's @code{main()}. +@item +In your @code{main()}, call @code{run_scm} with arguments (@code{argc} +and @code{argv}) to invoke your code's startup routine. +@item +link your code with SCM at compile time. +@end enumerate + +@noindent +For a dynamically linked single-thread program: + +@enumerate +@item +make an @code{init_} procedure for your code which will set up any Scheme +definitions you need and then call your startup routine +(@pxref{Changing Scm}). +@item +Start SCM with command line arguments to dynamically link your code. +After your module is linked, the @code{init_} procedure will be called, and +hence your startup routine. +@end enumerate + +@noindent +Now use @code{apply} (and perhaps @code{intern}) to call Scheme +procedures from your C code. For example: + +@example +/* If this apply fails, SCM will catch the error */ +apply(CDR(intern("srv:startup",sizeof("srv:startup")-1)), + mksproc(srvproc), + listofnull); + +func = CDR(intern(rpcname,strlen(rpcname))); +retval = apply(func, cons(mksproc(srvproc), args), EOL); +@end example + +@node Callbacks, Type Conversions, Calling Scheme From C, Operations +@subsection Callbacks + +@noindent +SCM now has routines to make calling back to Scheme procedures easier. +The source code for these routines are found in @file{rope.c}. + +@deftypefun int scm_ldfile (char *@var{file}) +Loads the Scheme source file @var{file}. Returns 0 if successful, non-0 +if not. This function is used to load SCM's initialization file +@file{Init.scm}. +@end deftypefun + +@deftypefun int scm_ldprog (char *@var{file}) +Loads the Scheme source file @code{(in-vicinity (program-vicinity) +@var{file})}. Returns 0 if successful, non-0 if not. + +This function is useful for compiled code init_ functions to load +non-compiled Scheme (source) files. @code{program-vicinity} is the +directory from which the calling code was loaded (@pxref{Vicinity, , , +slib, SLIB}). +@end deftypefun + +@deftypefun SCM scm_evstr (char *@var{str}) +Returns the result of reading an expression from @var{str} and +evaluating it. +@end deftypefun + +@deftypefun void scm_ldstr (char *@var{str}) +Reads and evaluates all the expressions from @var{str}. +@end deftypefun + +@noindent +If you wish to catch errors during execution of Scheme code, then you +can use a wrapper like this for your Scheme procedures: + +@example +(define (srv:protect proc) + (lambda args + (define result #f) ; put default value here + (call-with-current-continuation + (lambda (cont) + (dynamic-wind (lambda () #t) + (lambda () + (set! result (apply proc args)) + (set! cont #f)) + (lambda () + (if cont (cont #f)))))) + result)) +@end example + +@noindent +Calls to procedures so wrapped will return even if an error occurs. + +@node Type Conversions, Continuations, Callbacks, Operations +@subsection Type Conversions + +These type conversion functions are very useful for connecting SCM and C +code. Most are defined in @file{rope.c}. + +@deftypefun SCM long2num (long @var{n}) +@deftypefunx SCM ulong2num (unsigned long @var{n}) +Return an object of type @code{SCM} corresponding to the @code{long} or +@code{unsigned long} argument @var{n}. If @var{n} cannot be converted, +@code{BOOL_F} is returned. Which numbers can be converted depends on +whether SCM was compiled with the @code{BIGDIG} or @code{FLOATS} flags. + +To convert integer numbers of smaller types (@code{short} or +@code{char}), use the macro @code{MAKINUM(n)}. +@end deftypefun + +@deftypefun long num2long (SCM @var{num}, char *@var{pos}, char *@var{s_caller}) +@deftypefunx unsigned long num2ulong (SCM @var{num}, char *@var{pos}, char *@var{s_caller}) +@deftypefunx unsigned short num2ushort (SCM @var{num}, char *@var{pos}, char *@var{s_caller}) +@deftypefunx unsigned char num2uchar (SCM @var{num}, char *@var{pos}, char *@var{s_caller}) +These functions are used to check and convert @code{SCM} arguments to +the named C type. The first argument @var{num} is checked to see it it +is within the range of the destination type. If so, the converted +number is returned. If not, the @code{ASSERT} macro calls @code{wta} +with @var{num} and strings @var{pos} and @var{s_caller}. For a listing +of useful predefined @var{pos} macros, @xref{C Macros}. + +@emph{Note:} Inexact numbers are accepted only by @code{num2long} and +@code{num2ulong} (for when @code{SCM} is compiled without bignums). To +convert inexact numbers to exact numbers, @xref{Numerical operations, +inexact->exact, , r4rs, Revised(4) Scheme}. +@end deftypefun + +@deftypefun unsigned long scm_addr (SCM @var{args}, char *@var{s_name}) +Returns a pointer (cast to an @code{unsigned long}) to the storage +corresponding to the location accessed by +@code{aref(CAR(args),CDR(args))}. The string @var{s_name} is used in +any messages from error calls by @code{scm_addr}. + +@code{scm_addr} is useful for performing C operations on strings or +other uniform arrays (@pxref{Uniform Array}). + +@emph{Note:} While you use a pointer returned from @code{scm_addr} you +must keep a pointer to the associated @code{SCM} object in a stack +allocated variable or GC-protected location in order to assure that SCM +does not reuse that storage before you are done with it. +@end deftypefun + +@deftypefun SCM makfrom0str (char *@var{src}) +@deftypefunx SCM makfromstr (char *@var{src}, sizet @var{len}) +Return a newly allocated string @code{SCM} object copy of the +null-terminated string @var{src} or the string @var{src} of length +@var{len}, respectively. +@end deftypefun + +@deftypefun SCM makfromstrs (int @var{argc}, char **@var{argv}) +Returns a newly allocated @code{SCM} list of strings corresponding to +the @var{argc} length array of null-terminated strings @var{argv}. If +@var{argv} is less than @code{0}, @var{argv} is assumed to be +@code{NULL} terminated. @code{makfromstrs} is used by @code{run_scm} to +convert the arguments SCM was called with to a @code{SCM} list which is +the value of SCM procedure calls to @code{program-arguments} +(@pxref{System Interface, program-arguments}). +@end deftypefun + +@deftypefun char **makargvfrmstrs (SCM @var{args}, char *@var{s_name}) +Returns a @code{NULL} terminated list of null-terminated strings copied +from the @code{SCM} list of strings @var{args}. The string @var{s_name} +is used in messages from error calls by @code{makargvfrmstrs}. + +@code{makargvfrmstrs} is useful for constructing argument lists suitable +for passing to @code{main} functions. +@end deftypefun + +@deftypefun void must_free_argv (char **@var{argv}) +Frees the storage allocated to create @var{argv} by a call to +@code{makargvfrmstrs}. +@end deftypefun + +@node Continuations, Evaluation, Type Conversions, Operations +@subsection Continuations + +@noindent +The source files @file{continue.h} and @file{continue.c} are designed to +function as an independent resource for programs wishing to use +continuations, but without all the rest of the SCM machinery. The +concept of continuations is explained in @ref{Control features, +call-with-current-continuation, , r4rs, Revised(4) Scheme}. + +@deftp {Data type} CONTINUATION jmpbuf length stkbse other parent +is a @code{typedef}ed structure holding all the information needed to +represent a continuation. The @var{other} slot can be used to hold any +data the user wishes to put there by defining the macro +@code{CONTINUATION_OTHER}. +@end deftp + +@defmac SHORT_ALIGN +If @code{SHORT_ALIGN} is @code{#define}d (in @file{scmfig.h}), then the +it is assumed that pointers in the stack can be aligned on @code{short +int} boundaries. +@end defmac + +@deftp {Data type} STACKITEM +is a pointer to objects of the size specified by @code{SHORT_ALIGN} +being @code{#define}d or not. +@end deftp + +@defmac CHEAP_CONTINUATIONS +If @code{CHEAP_CONTINUATIONS} is @code{#define}d (in @file{scmfig.h}) +each @code{CONTINUATION} has size @code{sizeof CONTINUATION}. +Otherwise, all but @dfn{root} @code{CONTINUATION}s have additional +storage (immediately following) to contain a copy of part of the stack. + +@emph{Note:} On systems with nonlinear stack disciplines (multiple +stacks or non-contiguous stack frames) copying the stack will not work +properly. These systems need to #define @code{CHEAP_CONTINUATIONS} in +@file{scmfig.h}. +@end defmac + +@defmac STACK_GROWS_UP +Expresses which way the stack grows by its being @code{#define}d or not. +@end defmac + +@deftypevar long thrown_value +Gets set to the @var{value} passed to @code{throw_to_continuation}. +@end deftypevar + +@deftypefun long stack_size (STACKITEM *@var{start}) +Returns the number of units of size @code{STACKITEM} which fit between +@var{start} and the current top of stack. No check is done in this +routine to ensure that @var{start} is actually in the current stack +segment. +@end deftypefun + +@deftypefun CONTINUATION *make_root_continuation (STACKITEM *@var{stack_base}) +Allocates (@code{malloc}) storage for a @code{CONTINUATION} of the +current extent of stack. This newly allocated @code{CONTINUATION} is +returned if successful, @code{0} if not. After +@code{make_root_continuation} returns, the calling routine still needs +to @code{setjmp(@var{new_continuation}->jmpbuf)} in order to complete +the capture of this continuation. +@end deftypefun + +@deftypefun CONTINUATION *make_continuation (CONTINUATION *@var{parent_cont}) +Allocates storage for the current @code{CONTINUATION}, copying (or +encapsulating) the stack state from @code{@var{parent_cont}->stkbse} to +the current top of stack. The newly allocated @code{CONTINUATION} is +returned if successful, @code{0}q if not. After +@code{make_continuation} returns, the calling routine still needs to +@code{setjmp(@var{new_continuation}->jmpbuf)} in order to complete the +capture of this continuation. +@end deftypefun + +@deftypefun void free_continuation (CONTINUATION *@var{cont}) +Frees the storage pointed to by @var{cont}. Remember to free storage +pointed to by @code{@var{cont}->other}. +@end deftypefun + +@deftypefun void throw_to_continuation (CONTINUATION *@var{cont}, long @var{value}, CONTINUATION *@var{root_cont}) +Sets @code{thrown_value} to @var{value} and returns from the +continuation @var{cont}. + +If @code{CHEAP_CONTINUATIONS} is @code{#define}d, then +@code{throw_to_continuation} does @code{longjmp(@var{cont}->jmpbuf, val)}. + +If @code{CHEAP_CONTINUATIONS} is not @code{#define}d, the CONTINUATION +@var{cont} contains a copy of a portion of the C stack (whose bound must +be @code{CONT(@var{root_cont})->stkbse}). Then: + +@itemize @bullet +@item +the stack is grown larger than the saved stack, if neccessary. +@item +the saved stack is copied back into it's original position. +@item +@code{longjmp(@var{cont}->jmpbuf, val)}; +@end itemize +@end deftypefun + +@node Evaluation, , Continuations, Operations +@subsection Evaluation + +SCM uses its type representations to speed evaluation. All of the +@code{subr} types (@pxref{Subr Cells}) are @code{tc7} types. Since the +@code{tc7} field is in the low order bit position of the @code{CAR} it +can be retrieved and dispatched on quickly by dereferencing the SCM +pointer pointing to it and masking the result. + +All the SCM @dfn{Special Forms} get translated to immediate symbols +(@code{isym}) the first time they are encountered by the interpreter +(@code{ceval}). The representation of these immediate symbols is +engineered to occupy the same bits as @code{tc7}. All the @code{isym}s +occur only in the @code{CAR} of lists. + +If the @code{CAR} of a expression to evaluate is not immediate, then it +may be a symbol. If so, the first time it is encountered it will be +converted to an immediate type @code{ILOC} or @code{GLOC} +(@pxref{Immediates}). The codes for @code{ILOC} and @code{GLOC} lower 7 +bits distinguish them from all the other types we have discussed. + +Once it has determined that the expression to evaluate is not immediate, +@code{ceval} need only retrieve and dispatch on the low order 7 bits of +the @code{CAR} of that cell, regardless of whether that cell is a +closure, header, or subr, or a cons containing @code{ILOC} or +@code{GLOC}. + +In order to be able to convert a SCM symbol pointer to an immediate @code{ILOC} +or @code{GLOC}, the evaluator must be holding the pointer to the list in which +that symbol pointer occurs. Turning this requirement to an advantage, +@code{ceval} does not recursively call itself to evaluate symbols in +lists; It instead calls the macro @dfn{EVALCAR}. @code{EVALCAR} does +symbol lookup and memoization for symbols, retrieval of values for @code{ILOC}s +and @code{GLOC}s, returns other immediates, and otherwise recursively calls +itself with the @code{CAR} of the list. + +@code{ceval} inlines evaluation (using @code{EVALCAR}) of almost all +procedure call arguments. When @code{ceval} needs to evaluate a list of +more than length 3, the procedure @code{eval_args} is called. So +@code{ceval} can be said to have one level lookahead. The avoidance of +recursive invocations of @code{ceval} for the most common cases (special +forms and procedure calls) results in faster execution. The speed of +the interpreter is currently limited on most machines by interpreter +size, probably having to do with its cache footprint. In order to keep +the size down, certain @code{EVALCAR} calls which don't need to be fast +(because they rarely occur or because they are part of expensive +operations) are instead calls to the C function @code{evalcar}. + +There was some discussion a year ago about a "Forth" style Scheme +interpreter. This is the only improvement I know of which would beat +SCM in speed. + +@quotation +Provided there is still type code space available in SCM, if we devote +some of the IMCAR codes to "inlined" operations, we should get a +significant performance boost. What is eliminated is the having to look +up a @code{GLOC} or @code{ILOC} and then dispatch on the subr type. The +IMCAR operation would be dispatched to directly. Another way to view +this is that we make available special form versions of @code{CAR}, +@code{CDR}, etc. Since the actual operation code is localized in the +interpreter, it is much easier than uncompilation and then recompilation +to handle @code{(trace car)}; For instance a switch gets set which tells +the interpreter to instead always look up the values of the associated +symbols. +@end quotation + +@defvar symhash +Top level symbol values are stored in the @code{symhash} table. +@code{symhash} is an array of lists of @code{ISYM}s and pairs of symbols +and values. +@end defvar + +@deftp Immediate ILOC +Whenever a symbol's value is found in the local environment the pointer +to the symbol in the code is replaced with an immediate object +(@code{ILOC}) which specifies how many environment frames down and how +far in to go for the value. When this immediate object is subsequently +encountered, the value can be retrieved quickly. +@end deftp + +@deftp Immediate GLOC +Pointers to symbols not defined in local environments are changed to one +plus the value cell address in symhash. This incremented pointer is +called a @code{GLOC}. The low order bit is normally reserved for +GCmark; But, since references to variables in the code always occur in +the @code{CAR} position and the GCmark is in the @code{CDR}, there is no +conflict. +@end deftp + +If the compile FLAG @code{CAUTIOUS} is #defined then the number of +arguments is always checked for application of closures. If the compile +FLAG @code{RECKLESS} is #defined then they are not checked. Otherwise, +number of argument checks for closures are made only when the function +position (whose value is the closure) of a combination is not an +@code{ILOC} or @code{GLOC}. When the function position of a combination +is a symbol it will be checked only the first time it is evaluated +because it will then be replaced with an @code{ILOC} or @code{GLOC}. + +@defmac EVAL expression env +@defmacx SIDEVAL expression env +@code{EVAL} Returns the result of evaluating @var{expression} in +@var{env}. @code{SIDEVAL} evaluates @var{expression} in @var{env} when +the value of the expression is not used. + +Both of these macros alter the list structure of @var{expression} as it +is memoized and hence should be used only when it is known that +@var{expression} will not be referenced again. The C function +@code{eval} is safe from this problem. +@end defmac + +@deftypefun SCM eval (SCM @var{expression}) +Returns the result of evaluating @var{expression} in the top-level +environment. @code{eval} copies @code{expression} so that memoization +does not modify @code{expression}. +@end deftypefun + +@node Improvements To Make, Finishing Dynamic Linking, Operations, The Implementation +@section Improvements To Make + +@itemize @bullet +@item +Prefix and make more uniform all C function, variable, and constant +names. Provide a file full of #define's to provide backward +compatability. +@item +@code{lgcd()} @emph{needs} to generate at most one bignum, but currently +generates more. +@item +@code{divide()} could use shifts instead of multiply and divide when +scaling. +@item +If an open fails because there are no unused file handles, GC should +be done so that file handles which are no longer used can be +collected. +@item +Currently, @code{dump}ing an executable does not preserve ports. When +loading a @code{dump}ed executable, disk files could be reopened to the +same file and position as they had when the executable was dumped. +@item +Compaction could be done to @code{malloc}ed objects by freeing and +reallocing all the malloc objects encountered in a scan of the heap. +Whether compactions would actually occur is system depenedent. +@item +Copying all of the stack is wasteful of storage. Any time a +call-with-current-continuation is called the stack could be re-rooted +with a frame which calls the contin just created. This in combination +with checking stack depth could also be used to allow stacks deeper +than 64K on the IBM PC. +@item +lookupcar in @file{eval.c} should @emph{not} memoize (to @code{ILOC}s) +when it retrieves environments deeper or longer than 4095. The values +can still be retrieved (albeit slowly), but an @code{ILOC} should not be +made. The @code{MEMOIZE_LOCALS} flag could then be flushed. +@item +The @code{must-} or @code{make-} routines need some sort of C macros or +conditionalization so that they check: + +@itemize @bullet +@item +that the @code{LENGTH} field fits into a @code{size_t} (as is checked +now) for platforms with @code{(sizeof(size_t) < sizeof(SCM))}. +@item +that the @code{LENGTH} field fits into 24 (or 56) bits on machines where +@code{size_t} is 32 bits or more. +@end itemize + +This is trickier than it first looks because the must_malloc() routine +is also used for allocating heap segments, which do not have the +@code{LENGTH} field restriction. Putting the 24 bit test into +@code{must_malloc()} should be tested for speed impact. +@end itemize + +@node Finishing Dynamic Linking, , Improvements To Make, The Implementation +@section Finishing Dynamic Linking + +@noindent +Scott Schwartz <schwartz@@galapagos.cse.psu.edu> suggests: One way to +tidy up the dynamic loading stuff would be to grab the code from perl5. + +@subsubheading VMS + +@noindent +George Carrette (gjc@@mitech.com) outlines how to dynamically link on +VMS. There is already some code in @file{dynl.c} to do this, but +someone with a VMS system needs to finish and debug it. + +@enumerate +@item +Say you have this @file{main.c} program: + +@format +@t{main() +@{init_lisp(); + lisp_repl();@}} +@end format + +@item +and you have your lisp in files @file{repl.c}, @file{gc.c}, +@code{eval.c} and there are some toplevel non-static variables in use +called @code{the_heap}, @code{the_environment}, and some read-only +toplevel structures, such as @code{the_subr_table}. + +@format +@t{$ LINK/SHARE=LISPRTL.EXE/DEBUG REPL.OBJ,GC.OBJ,EVAL.OBJ,LISPRTL.OPT/OPT} +@end format + +@item +where @file{LISPRTL.OPT} must contain at least this: + +@format +@t{SYS$LIBRARY:VAXCRTL/SHARE +UNIVERSAL=init_lisp +UNIVERSAL=lisp_repl +PSECT_ATTR=the_subr_table,SHR,NOWRT,LCL +PSECT_ATTR=the_heap,NOSHR,LCL +PSECT_ATTR=the_environment,NOSHR,LCL} +@end format + +@emph{Notice:} The @dfn{psect} (Program Section) attributes. +@table @code +@item LCL +means to keep the name local to the shared library. You almost always +want to do that for a good clean library. +@item SHR,NOWRT +means shared-read-only. Which is the default for code, and is also good +for efficiency of some data structures. +@item NOSHR,LCL +is what you want for everything else. +@end table + +Note: If you do not have a handy list of all these toplevel variables, +do not dispair. Just do your link with the /MAP=LISPRTL.MAP/FULL +and then search the map file, + +@format +@t{$SEARCH/OUT=LISPRTL.LOSERS LISPRTL.MAP ", SHR,NOEXE, RD, WRT"} +@end format + +And use an emacs keyboard macro to muck the result into the proper form. +Of course only the programmer can tell if things can be made read-only. +I have a DCL command procedure to do this if you want it. + +@item +@noindent +Now MAIN.EXE would be linked thusly: + +@format +@t{$ DEFINE LISPRTL USER$DISK:[JAFFER]LISPRTL.EXE + +$LINK MAIN.OBJ,SYS$INPUT:/OPT + SYS$LIBRARY:VAXCRTL/SHARE + LISPRTL/SHARE} +@end format + +Note the definition of the @code{LISPRTL} logical name. Without such a +definition you will need to copy @file{LISPRTL.EXE} over to +@file{SYS$SHARE:} (aka @file{SYS$LIBRARY:}) in order to invoke the main +program once it is linked. + +@item +Now say you have a file of optional subrs, @file{MYSUBRS.C}. And there +is a routine @code{INIT_MYSUBRS} that must be called before using it. + +@format +@t{$ CC MYSUBRS.C +$ LINK/SHARE=MYSUBRS.EXE MYSUBRS.OBJ,SYS$INPUT:/OPT + SYS$LIBRARY:VAXCRTL/SHARE + LISPRTL/SHARE + UNIVERSAL=INIT_MYSUBRS} +@end format + +Ok. Another hint is that you can avoid having to add the @code{PSECT} +declaration of @code{NOSHR,LCL} by declaring variables @code{status} in +the C language source. That works great for most things. + +@item +Then the dynamic loader would have to do this: + +@format +@t{@{void (*init_fcn)(); + long retval; + retval = lib$find_image_symbol("MYSUBRS","INIT_MYSUBRS",&init_fcn, + "SYS$DISK:[].EXE"); + if (retval != SS$_NORMAL) error(@dots{}); + (*init_fcn)();@}} +@end format + +But of course all string arguments must be @code{(struct dsc$descriptor +*)} and the last argument is optional if @code{MYSUBRS} is defined as a +logical name or if @file{MYSUBRS.EXE} has been copied over to +@file{SYS$SHARE}. The other consideration is that you will want to turn +off @key{C-c} or other interrupt handling while you are inside most +@code{lib$} calls. + +As far as the generation of all the @code{UNIVERSAL=@dots{}} +declarations. Well, you could do well to have that automatically +generated from the public @file{LISPRTL.H} file, of course. + +VMS has a good manual called the @cite{Guide to Writing Modular +Procedures} or something like that, which covers this whole area rather +well, and also talks about advanced techniques, such as a way to declare +a program section with a pointer to a procedure that will be +automatically invoked whenever any shared image is dynamically +activated. Also, how to set up a handler for normal or abnormal program +exit so that you can clean up side effects (such as opening a database). +But for use with @code{LISPRTL} you probably don't need that hair. + +One fancier option that is useful under VMS for @file{LISPLIB.EXE} is to +define all your exported procedures through an @dfn{call vector} instead +of having them just be pointers into random places in the image, which +is what you get by using @code{UNIVERSAL}. + +If you set up the call vector thing correctly it will allow you to +modify and relink @file{LISPLIB.EXE} without having to relink programs +that have been linked against it. +@end enumerate + +@subsubheading Windows NT +@noindent +George Carrette (gjc@@mitech.com) outlines how to dynamically link on +Windows NT: + +@itemize @bullet +@item +The Software Developers Kit has a sample called SIMPLDLL. +Here is the gist of it, following along the lines of the VMS description +above (contents of a makefile for the SDK NMAKE) + +@format +@t{LISPLIB.exp: +LISPLIB.lib: LISPLIB.def + $(implib) -machine:$(CPU) -def:LISPLIB.def -out:LISPLIB.lib + +LISPLIB.DLL : $(LISPLIB_OBJS) LISPLIB.EXP + $(link) $(linkdebug) \ + -dll \ + -out:LISPLIB.DLL \ + LISPLIB.EXP $(LISPLIB_OBJS) $(conlibsdll)} +@end format + +@item +The @file{LISPDEF.DEF} file has this: + +@format +@t{LIBRARY lisplib +EXPORT + init_lisp + init_repl} +@end format + +@item +And @file{MAIN.EXE} using: + +@format +@t{CLINK = $(link) $(ldebug) $(conflags) -out:$*.exe $** $(conlibsdll) + +MAIN.EXE : MAIN.OBJ LISPLIB.LIB + $(CLINK)} +@end format + +@item +And @file{MYSUBRS.DLL} is produced using: + +@format +@t{mysubrs.exp: +mysubrs.lib: mysubrs.def + $(implib) -machine:$(CPU) -def:MYSUBRS.def -out:MYSUBRS.lib + +mysubrs.dll : mysubrs.obj mysubrs.exp mysubrs.lib + $(link) $(linkdebug) \ + -dll \ + -out:mysubrs.dll \ + MYSUBRS.OBJ MYSUBRS.EXP LISPLIB.LIB $(conlibsdll)} +@end format + +@item +Where @file{MYSUBRS.DEF} has + +@format +@t{LIBRARY mysubrs +EXPORT + INIT_MYSUBRS} +@end format + +@item +And the dynamic loader looks something like this, calling the two +procedures @code{LoadLibrary} and @code{GetProcAddress}. + +@format +@t{LISP share_image_load(LISP fname) +@{long iflag; + LISP retval,(*fcn)(void); + HANDLE hLib; + DWORD err; + char *libname,fcnname[64]; + iflag = nointerrupt(1); + libname = c_string(fname); + _snprintf(fcnname,sizeof(fcnname),"INIT_%s",libname); + if (!(hLib = LoadLibrary(libname))) + @{err = GetLastError(); + retval = list2(fname,LSPNUM(err)); + serror1("library failed to load",retval);@} + if (!(fcn = (LISP (*)(void)) GetProcAddress(hLib,fcnname))) + @{err = GetLastError(); + retval = list2(fname,LSPNUM(err)); + serror1("could not find library init procedure",retval);@} + retval = (*fcn)(); + nointerrupt(iflag); + return(retval);@}} +@end format + +@item +@emph{Note:} in VMS the linker and dynamic loader is case sensitive, but +all the language compilers, including C, will by default upper-case +external symbols for use by the linker, although the debugger gets its +own symbols and case sensitivity is language mode dependant. In Windows +NT things are case sensitive generally except for file and device names, +which are case canonicalizing like in the Symbolics filesystem. + +@item +@emph{Also:} All this WINDOWS NT stuff will work in MS-DOS MS-Windows +3.1 too, by a method of compiling and linking under Windows NT, and then +copying various files over to MS-DOS/WINDOWS. +@end itemize + + +@node Procedure and Macro Index, Variable Index, The Implementation, Top +@unnumbered Procedure and Macro Index + +This is an alphabetical list of all the procedures and macros in SCM. + +@printindex fn + +@node Variable Index, Type Index, Procedure and Macro Index, Top +@unnumbered Variable Index + +This is an alphabetical list of all the global variables in SCM. + +@printindex vr + +@node Type Index, , Variable Index, Top +@unnumbered Type Index + +This is an alphabetical list of all the data types in SCM. + +@printindex tp + +@contents +@bye |