aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbuild2
-rw-r--r--build.scm40
-rw-r--r--continue.h2
-rw-r--r--debian/changelog238
-rw-r--r--debian/control16
-rw-r--r--debian/copyright16
-rw-r--r--debian/doc-base12
-rw-r--r--debian/postinst20
-rw-r--r--debian/prerm16
-rw-r--r--debian/require.scm.debian2
-rwxr-xr-xdebian/rules161
-rw-r--r--grtest.scm82
-rw-r--r--scm5d6.info8382
-rw-r--r--setjump.h4
-rw-r--r--turtle20
-rw-r--r--turtlegr.c1298
-rw-r--r--version.txi2
-rwxr-xr-xxgen.scm2
18 files changed, 10293 insertions, 22 deletions
diff --git a/build b/build
index cde6729..a76a67a 100755
--- a/build
+++ b/build
@@ -1,5 +1,5 @@
#! /bin/sh
-:;exec scmlit -f $0 -e"(bi)" build $*
+:;exec ./scmlit -f $0 -e"(bi)" build $*
(require (in-vicinity (program-vicinity) "build.scm"))
(require 'getopt)
diff --git a/build.scm b/build.scm
index 7f896d4..63249b3 100644
--- a/build.scm
+++ b/build.scm
@@ -457,7 +457,7 @@
(openbsd *unknown* unix gcc ) ;gcc
(os/2-cset i386 os/2 icc ) ;link386
(os/2-emx i386 os/2 gcc ) ;gcc
- (plan9-8 i386 plan9 8c ) ;8l
+;; (plan9-8 i386 plan9 8c ) ;8l
(svr4-gcc-sun-ld sparc sunos gcc ) ;ld
(sunos sparc sunos cc ) ;ld
(svr4 *unknown* unix cc ) ;ld
@@ -505,10 +505,12 @@
(m linux "" "-lm" "/lib/libm.so" () ())
(c linux "" "-lc" "/lib/libc.so" () ())
+ (regex linux "" "" "" () ())
+ (termcap linux "" "-lncurses" "/usr/lib/libncurses.a" () ())
(dlll linux "-DSUN_DL" "-ldl" #f () ())
(graphics linux "-I/usr/include/X11 -DX11" "-L/usr/X11R6/lib -lX11"
"/usr/X11R6/lib/libX11.so" () ())
- (curses linux "" "-lcurses" "/lib/libncurses.so" () ())
+ (curses linux "" "-lncurses" "/usr/lib/libncurses.so" () ())
(nostart linux "" "" #f () ())
(dump linux "" "" #f ("unexelf.c" "gmalloc.c") ())
@@ -529,8 +531,8 @@
(m atari-st-gcc "" "-lpml" #f () ())
(m atari-st-turbo-c "" "" #f () ())
- (c plan9-8 "" "" #f () ())
- (m plan9-8 "" "" #f () ())
+;; (c plan9-8 "" "" #f () ())
+;; (m plan9-8 "" "" #f () ())
(m sunos "" "-lm" #f () ())
(dlll sunos "-DSUN_DL" "-ldl" #f () ())
@@ -1017,21 +1019,21 @@
;; does print a lot of them, indeed.)
;; -p Invoke a standard ANSI C preprocessor before compiling
;; (instead of a rudimentary builtin one used by default).
-(defcommand compile-c-files plan9-8
- (lambda (files parms)
- (and (batch:try-chopped-command
- parms
- "8c" "-Fwp" "-DPLAN9" ;"-V"
- ;;(include-spec "-i" parms)
- (c-includes parms)
- (c-flags parms)
- files)
- (truncate-up-to (map c->8 files) #\/))))
-(defcommand link-c-program plan9-8
- (lambda (oname objects libs parms)
- (and (batch:try-command
- parms "8l" "-o" oname objects libs)
- oname)))
+;;(defcommand compile-c-files plan9-8
+;; (lambda (files parms)
+;; (and (batch:try-chopped-command
+;; parms
+;; "8c" "-Fwp" "-DPLAN9" ;"-V"
+;; ;;(include-spec "-i" parms)
+;; (c-includes parms)
+;; (c-flags parms)
+;; files)
+;; (truncate-up-to (map c->8 files) #\/))))
+;;(defcommand link-c-program plan9-8
+;; (lambda (oname objects libs parms)
+;; (and (batch:try-command
+;; parms "8l" "-o" oname objects libs)
+;; oname)))
(defcommand compile-c-files gcc
(lambda (files parms)
diff --git a/continue.h b/continue.h
index 42a5ff5..ee59f21 100644
--- a/continue.h
+++ b/continue.h
@@ -172,7 +172,7 @@ void throw_to_continuation P((CONTINUATION *cont, long val,
continuations on the SPARC. It flushes the register windows so
that all the state of the process is contained in the stack. */
-#ifdef sparc
+#if defined (sparc) || defined (__sparc__) || defined (__sparc)
# define FLUSH_REGISTER_WINDOWS asm("ta 3")
#else
# define FLUSH_REGISTER_WINDOWS /* empty */
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..e25b173
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,238 @@
+scm (5d6-3.2) unstable; urgency=low
+
+ * Fix hppa compile. Closes: #144062
+
+ -- LaMont Jones <lamont@debian.org> Wed, 7 May 2003 08:36:40 -0600
+
+scm (5d6-3.1) unstable; urgency=low
+
+ * NMU with patch from James Troup, to fix FTBFS on sparc. Closes: #191171
+
+ -- Joey Hess <joeyh@debian.org> Tue, 29 Apr 2003 19:56:51 -0400
+
+scm (5d6-3) unstable; urgency=low
+
+ * Add build depend on xlibs-dev (Closes: #148020)
+
+ -- James LewisMoss <dres@debian.org> Fri, 24 May 2002 15:56:12 -0400
+
+scm (5d6-2) unstable; urgency=low
+
+ * Remove libregexx-dev from build-depends.
+ * Change build to use ./scmlit rather than scmlit (should fix some build
+ problems) (looks like alpha is mostly building)
+ * New release (Closes: #140175)
+ * Built with turtlegraphics last time (Closes: #58515)
+
+ -- James LewisMoss <dres@debian.org> Thu, 23 May 2002 13:41:02 -0400
+
+scm (5d6-1) unstable; urgency=low
+
+ * New upstream.
+ * Add xlib and turtlegr to requested list of features. (closes
+ some bug)
+ * Make clean actually clean most everything up.
+ * Remove hacks renaming build to something else and just set build as a
+ .PHONY target in debian/rules.
+ * Add the turtlegr code.
+
+ -- James LewisMoss <dres@debian.org> Fri, 17 May 2002 13:27:00 -0400
+
+scm (5d5-1) unstable; urgency=low
+
+ * New upstream
+ * Has fixes for 64 bit archs. May fix alpha compile problem. Does fix
+ (Closes: #140175)
+ * Take out -O2 arg.
+
+ -- James LewisMoss <dres@debian.org> Sat, 6 Apr 2002 17:46:22 -0500
+
+scm (5d4-3) unstable; urgency=low
+
+ * Don't link with regexx, but just use libc6's regular expression
+ functions.
+ * Define (terms) to output /usr/share/common-licenses/GPL (Closes:
+ #119321)
+
+ -- James LewisMoss <dres@debian.org> Wed, 12 Dec 2001 16:27:02 -0500
+
+scm (5d4-2) unstable; urgency=low
+
+ * Add texinfo to build depends (Closes: #107011)
+
+ -- James LewisMoss <dres@debian.org> Sun, 29 Jul 2001 22:16:35 -0400
+
+scm (5d4-1) unstable; urgency=low
+
+ * New upstream release.
+ * Move install-info --remove to prerm.
+
+ -- James LewisMoss <dres@debian.org> Tue, 22 May 2001 01:35:50 -0400
+
+scm (5d3-5) unstable; urgency=low
+
+ * Move scm info files to section "The Algorithmic Language Scheme" to
+ match up with guile.
+
+ -- James LewisMoss <dres@debian.org> Mon, 11 Dec 2000 03:49:34 -0500
+
+scm (5d3-4) unstable; urgency=low
+
+ * Fix build depends (Closes: #76691)
+
+ -- James LewisMoss <dres@debian.org> Sat, 11 Nov 2000 09:55:07 -0500
+
+scm (5d3-3) unstable; urgency=low
+
+ * Fix path in scm dhelp file.
+
+ -- James LewisMoss <dres@debian.org> Fri, 27 Oct 2000 15:37:47 -0400
+
+scm (5d3-2) unstable; urgency=low
+
+ * Actually put the header files in the package. Oops.
+
+ -- James LewisMoss <dres@debian.org> Thu, 26 Oct 2000 21:52:47 -0400
+
+scm (5d3-1) unstable; urgency=low
+
+ * New upstream. (Closes: #74761)
+ * Make (terms) use new license location.
+ * Make use libregexx rather than librx.
+ * Fix build depends for above.
+ * Using new regex lib seems to fix crash (Closes: #66787)
+ * Consider adding scm-dev package with headers, but instead just add the
+ headers to the scm package. (Closes: #70787)
+ * Add doc-base support.
+
+ -- James LewisMoss <dres@debian.org> Sun, 22 Oct 2000 22:29:41 -0400
+
+scm (5d2-3) unstable frozen; urgency=low
+
+ * Fix libncurses4-dev -> libncurses5-dev build depend (Closes: #58435)
+ * Fix libreadline2-dev -> libreadline4-dev build depend.
+ * Fix license location in copyright file (lintian warning)
+ * Add tetex-bin as a build depend (needs makeinfo) (Closes: #53197)
+ * Add -isp option to dpkg-gencontrol (lintian error)
+ * Move scm to section interpreters.
+
+ -- James LewisMoss <dres@debian.org> Sun, 12 Mar 2000 09:04:17 -0500
+
+scm (5d2-2) unstable; urgency=low
+
+ * Apply patch from upstream for bug in eval.c. (Picked up from
+ comp.lang.scheme)
+ * Add Build-Depends on slib, librx1g-dev, libncurses4-dev, libreadlineg2-dev.
+ * Up standards version.
+ * Correct description: this is an R5RS implementation now
+ * Make sure no optimizations are done on m68k. (Closes: #52434)
+
+ -- James LewisMoss <dres@debian.org> Thu, 16 Dec 1999 23:53:15 -0500
+
+scm (5d2-1) unstable; urgency=low
+
+ * New upstream.
+
+ -- James LewisMoss <dres@debian.org> Mon, 6 Dec 1999 19:30:02 -0500
+
+scm (5d1-2) unstable; urgency=low
+
+ * Remove TAGS on clean (cut the diff back down to reasonable size).
+
+ -- James LewisMoss <dres@debian.org> Sat, 13 Nov 1999 14:10:10 -0500
+
+scm (5d1-1) unstable; urgency=low
+
+ * New upstream.
+ * move stuff to /usr/share.
+
+ -- James LewisMoss <dres@debian.org> Sat, 13 Nov 1999 13:26:46 -0500
+
+scm (5d0-3) unstable; urgency=low
+
+ * Change scmlit call to ./scmlit call (missed one) (Fixes bugs #37455
+ and #35545)
+ * Change man file permissions to 644 (fixes lintian warning)
+
+ -- James LewisMoss <dres@debian.org> Wed, 12 May 1999 22:39:54 -0400
+
+scm (5d0-2) unstable; urgency=low
+
+ * Removed call to add_final in init_crs. lendwin doesn't do anything
+ and scm was crashing when quit everytime in final_scm.
+ * Changed copyright to reflect new source.
+
+ -- James LewisMoss <dres@debian.org> Thu, 11 Mar 1999 22:13:19 -0500
+
+scm (5d0-1) unstable; urgency=low
+
+ * New upstream.
+ * Changed (terms) to access "/usr/doc/copyright/GPL".
+ * Changed regex to use -lrx
+
+ -- James LewisMoss <dres@debian.org> Sun, 7 Mar 1999 12:39:16 -0500
+
+scm (5c3-6) unstable; urgency=low
+
+ * New maintainer.
+
+ -- James LewisMoss <dres@debian.org> Fri, 26 Feb 1999 00:45:30 -0500
+
+scm (5c3-5) frozen unstable; urgency=low
+
+ * debian/rules chmod +x's bld.scm. Fixes #30521.
+
+ -- David N. Welton <davidw@efn.org> Fri, 11 Dec 1998 20:21:49 -0800
+
+scm (5c3-4) frozen unstable; urgency=low
+
+ * Made bld.scm executable. Fixes #29578.
+
+ -- David N. Welton <davidw@efn.org> Mon, 30 Nov 1998 20:57:12 -0800
+
+scm (5c3-3) frozen unstable; urgency=low
+
+ * -nw
+ * Fixes #16762.
+ * Fixes #18163.
+ * Fixes #18164.
+ * Fixes #23743.
+ * Fixes #24098.
+ * Fixes #24099.
+ * Fixes #24547.
+
+ -- David N. Welton <davidw@efn.org> Mon, 9 Nov 1998 21:41:29 -0800
+
+scm (5c3-2) frozen unstable; urgency=low
+
+ * Re-uploading for slink freeze.
+
+ -- David N. Welton <davidw@efn.org> Mon, 2 Nov 1998 21:06:01 -0800
+
+scm (5c3-1) unstable; urgency=low
+
+ * New upstream version.
+
+ -- David N. Welton <davidw@efn.org> Thu, 29 Oct 1998 21:37:49 -0800
+
+scm (5b3-1) unstable; urgency=low
+
+ * New maintainer
+ * New version
+ * libc6
+
+ -- Rob Browning <rlb@cs.utexas.edu> Fri, 12 Dec 1997 17:29:42 -0600
+
+scm (4e6-2) unstable; urgency=low
+
+ * Recompiled to use regex0.
+
+ -- Karl Sackett <krs@debian.org> Wed, 18 Dec 1996 13:27:20 -0600
+
+scm (4e6-1) unstable; urgency=low
+
+ * First Debian release.
+ * Makefile.in: scm compiles with regex.
+
+ -- Karl Sackett <krs@debian.org> Fri, 13 Dec 1996 08:55:23 -0600
+
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..533edb2
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,16 @@
+Source: scm
+Section: interpreters
+Priority: optional
+Maintainer: James LewisMoss <dres@debian.org>
+Standards-Version: 3.1.1
+Build-Depends: slib, libncurses5-dev, libreadline4-dev, texi2html, texinfo, xlibs-dev
+
+Package: scm
+Architecture: any
+Section: interpreters
+Priority: optional
+Depends: slib, ${shlibs:Depends}
+Description: A Scheme language interpreter.
+ Scm conforms to Revised^5 Report on the Algorithmic Language Scheme and
+ the IEEE P1178 specification.
+
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..419226e
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,16 @@
+This is the Debian GNU/Linux prepackaged version of scm.
+
+This package was put together by Karl Sackett <krs@debian.org>, and
+upgraded by James LewisMoss <dres@debian.org> from sources obtained
+from:
+
+ ftp://swiss-ftp.ai.mit.edu/archive/scm/scm5d0.tar.gz
+
+For more information see:
+
+ http://www-swiss.ai.mit.edu/~jaffer/SCM.html
+
+License:
+
+scm is distributed under the GNU General Public License. See
+/usr/share/common-licenses/GPL for details.
diff --git a/debian/doc-base b/debian/doc-base
new file mode 100644
index 0000000..59abf3f
--- /dev/null
+++ b/debian/doc-base
@@ -0,0 +1,12 @@
+Document: scm
+Title: SCM: scheme interpreter
+Author: Aubrey Jaffer
+Abstract: This manual describes the scheme interpreter scm.
+Section: Apps/Programming
+
+Format: info
+Files: /usr/share/info/scm.info
+
+Format: HTML
+Index: /usr/share/doc/scm/scm.html
+Files: /usr/share/doc/scm/scm.html
diff --git a/debian/postinst b/debian/postinst
new file mode 100644
index 0000000..c762db4
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,20 @@
+#!/bin/sh
+set -e
+
+install-info --quiet --section "The Algorithmic Language Scheme" \
+ "The Algorithmic Language Scheme" \
+ --description="A Scheme language interpreter" \
+ /usr/share/info/scm.info.gz
+
+if [ "$1" = "configure" ]; then
+ if [ -d /usr/doc -a ! -e /usr/doc/scm -a -d /usr/share/doc/scm ]; then
+ ln -sf ../share/doc/scm /usr/doc/scm
+ fi
+fi
+
+# doc base support
+if [ "$1" = configure ]; then
+ if command -v install-docs >/dev/null 2>&1; then
+ install-docs -i /usr/share/doc-base/scm
+ fi
+fi
diff --git a/debian/prerm b/debian/prerm
new file mode 100644
index 0000000..968aa17
--- /dev/null
+++ b/debian/prerm
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+set -e
+
+if [ \( "$1" = "upgrade" -o "$1" = "remove" \) -a -L /usr/doc/scm ]; then
+ rm -f /usr/doc/scm
+fi
+
+# doc base support
+if [ "$1" = remove -o "$1" = upgrade ]; then
+ if command -v install-docs >/dev/null 2>&1; then
+ install-docs -r scm
+ fi
+fi
+
+install-info --quiet --remove /usr/share/info/scm.info.gz
diff --git a/debian/require.scm.debian b/debian/require.scm.debian
new file mode 100644
index 0000000..06e43e6
--- /dev/null
+++ b/debian/require.scm.debian
@@ -0,0 +1,2 @@
+(define (library-vicinity) "/usr/share/slib/")
+(load (in-vicinity (library-vicinity) "require"))
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..da0e302
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,161 @@
+#! /usr/bin/make -f
+# -*-Makefile-*-
+
+CC =gcc
+CFLAGS = -g -Wall
+LDFLAGS =
+
+SHELL =/bin/sh
+srcdir =.
+
+INSTALL =/usr/bin/install
+INSTALL_DIR =$(INSTALL) -d -m 755 -o root -g root
+INSTALL_PROGRAM =$(INSTALL) -m 755 -o root -g root
+INSTALL_DATA =$(INSTALL) -m 644 -o root -g root
+INSTALL_MAN =$(INSTALL) -m 644 -o root -g root
+
+ifeq ($(DEB_BUILD_ARCH), m68k)
+COMPILER_OPTIONS=
+else
+COMPILER_OPTIONS=
+endif
+
+SCM_OPTIONS = -p linux \
+ --compiler-options="$(COMPILER_OPTIONS)" \
+ -F cautious \
+ -F bignums \
+ -F arrays \
+ -F array-for-each \
+ -F inexact \
+ -F record \
+ -F compiled-closure \
+ -F generalized-c-arguments \
+ -F tick-interrupts \
+ -F i/o-extensions \
+ -F edit-line \
+ -F regex \
+ -F socket \
+ -F posix \
+ -F unix \
+ -F curses \
+ -F dynamic-linking \
+ -F turtlegr \
+ -F xlib \
+ -F dump \
+ -F macro
+
+# -F dump
+
+# -F heap-can-shrink \
+
+NON_LIB_FILES = 'bench.scm|build.scm|example.scm|r4rstest.scm|pi.scm|grtest.scm'
+
+#test: stamp-configure
+# $(checkdir)
+# make checklit
+
+build: build-stamp
+build-stamp:
+ chmod +x build
+ $(checkdir)
+ cp debian/require.scm.debian require.scm
+ifeq ($(DEB_BUILD_ARCH), m68k)
+ ${MAKE} scmlit CFLAGS="-g -Wall"
+else
+ ${MAKE} scmlit
+endif
+ test -e /usr/share/slib || \
+ (echo "Must have slib installed for compile" && exit 1)
+ ./build ${SCM_OPTIONS} > debian/bld
+ chmod ug+x debian/bld
+ debian/bld
+ make scm.info
+ texi2html -monolithic scm.texi
+ touch build-stamp
+
+clean:
+ $(checkdir)
+ -rm -f scm.info* scm.html tmp1 tmp2 scmflags.h scmlit
+ -rm -f features.txi platform.txi
+ -rm -f scm5d0.info
+ -rm require.scm scm
+ make distclean
+ -rm -f srcdir.mk
+ -rm -f debian/bld
+ -rm -rf *~ debian/*~ debian/tmp* debian/files debian/substvars
+ -rm -f build-stamp
+
+binary-indep: checkroot
+ $(checkdir)
+
+binary-arch: checkroot build
+ $(checkdir)
+ -rm -rf debian/tmp*
+
+# debian/tmp
+ $(INSTALL_DIR) debian/tmp
+ $(INSTALL_DIR) debian/tmp/DEBIAN
+ $(INSTALL_PROGRAM) debian/postinst debian/tmp/DEBIAN
+ $(INSTALL_PROGRAM) debian/prerm debian/tmp/DEBIAN
+
+# binaries
+ $(INSTALL_DIR) debian/tmp/usr/bin
+ $(INSTALL_PROGRAM) -s scm debian/tmp/usr/bin
+
+# library
+ $(INSTALL_DIR) debian/tmp/usr/lib/scm
+ $(INSTALL_DATA) `ls *.scm | egrep -v ${NON_LIB_FILES}` debian/tmp/usr/lib/scm
+ $(INSTALL_DATA) slibcat debian/tmp/usr/lib/scm
+
+# headers
+ $(INSTALL_DIR) debian/tmp/usr/include/scm
+ $(INSTALL_DATA) *.h debian/tmp/usr/include/scm
+
+# man pages
+ $(INSTALL_DIR) debian/tmp/usr/share/man/man1
+ $(INSTALL_MAN) scm.1 debian/tmp/usr/share/man/man1
+ gzip -9vr debian/tmp/usr/share/man
+
+# documentation
+ $(INSTALL_DIR) debian/tmp/usr/share/doc/scm
+ $(INSTALL_DATA) debian/changelog debian/tmp/usr/share/doc/scm/changelog.Debian
+ $(INSTALL_DATA) ChangeLog debian/tmp/usr/share/doc/scm/changelog
+ $(INSTALL_DATA) QUICKREF debian/tmp/usr/share/doc/scm
+ $(INSTALL_DATA) README debian/tmp/usr/share/doc/scm
+ gzip -9v debian/tmp/usr/share/doc/scm/*
+ $(INSTALL_DATA) scm.html debian/tmp/usr/share/doc/scm
+ $(INSTALL_DATA) debian/copyright debian/tmp/usr/share/doc/scm
+
+ $(INSTALL_DIR) debian/tmp/usr/share/doc-base
+ $(INSTALL_DATA) debian/doc-base debian/tmp/usr/share/doc-base/scm
+
+# examples
+ $(INSTALL_DIR) debian/tmp/usr/share/doc/scm/examples
+ $(INSTALL_DATA) r4rstest.scm debian/tmp/usr/share/doc/scm/examples
+ $(INSTALL_DATA) example.scm debian/tmp/usr/share/doc/scm/examples
+ $(INSTALL_DATA) pi.scm debian/tmp/usr/share/doc/scm/examples
+ $(INSTALL_DATA) pi.c debian/tmp/usr/share/doc/scm/examples
+ $(INSTALL_DATA) bench.scm debian/tmp/usr/share/doc/scm/examples
+ $(INSTALL_DATA) grtest.scm debian/tmp/usr/share/doc/scm/examples
+ $(INSTALL_DATA) split.scm debian/tmp/usr/share/doc/scm/examples
+
+# info pages
+ $(INSTALL_DIR) debian/tmp/usr/share/info
+ $(INSTALL_DATA) scm.info* debian/tmp/usr/share/info
+ gzip -9 debian/tmp/usr/share/info/*
+
+ dpkg-shlibdeps scm
+ dpkg-gencontrol -isp
+ dpkg --build debian/tmp ..
+
+define checkdir
+ test -f scm.h -a -f debian/rules
+endef
+
+binary: binary-indep binary-arch
+
+checkroot:
+ $(checkdir)
+ test root = "`whoami`"
+
+.PHONY: build clean binary binary-arch binary-indep
diff --git a/grtest.scm b/grtest.scm
new file mode 100644
index 0000000..7401308
--- /dev/null
+++ b/grtest.scm
@@ -0,0 +1,82 @@
+
+; This is a quick hack to test the graphics primitives.
+; The SLIB scheme library is needed for random.
+; IMHO, the syntax of `do' in scheme is horrible!
+; - sjm
+
+(define (grtest)
+ (require 'random) ; needs SLIB
+ (graphics-mode!)
+
+ (display "testing draw-to") (newline)
+ (clear-graphics!)
+ (goto-center!)
+ (do ((x 0 (+ x 3)))
+ ((> x (max-x)) 0)
+ (set-color! (remainder (/ x 3) (max-color)))
+ (draw-to x 0)
+ (draw-to x (max-y))
+ )
+
+ (do ((y 0 (+ y 3)))
+ ((> y (max-y)) 0)
+ (set-color! (remainder (/ y 3) (max-color)))
+ (goto-center!)
+ (draw-to! 0 y)
+ (goto-center!)
+ (draw-to! (max-x) y)
+ )
+
+ (goto-nw!)
+ (do ((x 0 (+ x 2)))
+ ((> x (max-x)) 0)
+ (set-color! (remainder (/ x 2) (max-color)))
+ (draw-to x (max-y))
+ )
+ (do ((y (+ (max-y) 1) (- y 2)))
+ ((< y 0) 0)
+ (set-color! (remainder (/ y 2) (max-color)))
+ (draw-to (max-x) y)
+ )
+
+ (display "testing set-dot!") (newline)
+ (clear-graphics!)
+ (do ((x 0 (+ x 1)))
+ ((= x 100) 0)
+ (set-dot! (+ (random (max-x)) 1) (+ (random (max-y)) 1)
+ (+ (random (max-color)) 1))
+ )
+
+ (display "testing draw with turn-to!") (newline)
+ (clear-graphics!)
+ (goto-center!)
+ (do ((x 0 (+ x 1)))
+ ((= x 100) 0)
+ (set-color! (+ (random (max-color)) 1))
+ (turn-to! (random 360))
+ (draw (random 50))
+ )
+
+ (display "testing draw with turn-right") (newline)
+ (clear-graphics!)
+ (goto-center!)
+ (do ((x 0 (+ x 1)))
+ ((= x 100) 0)
+ (set-color! (+ (random (max-color)) 1))
+ (turn-right (random 90))
+ (draw (random 50))
+ )
+
+ (display "testing draw with turn-left") (newline)
+ (clear-graphics!)
+ (goto-center!)
+ (do ((x 0 (+ x 1)))
+ ((= x 100) 0)
+ (set-color! (+ (random (max-color)) 1))
+ (turn-left (random 90))
+ (draw (random 50))
+ )
+
+ (text-mode!)
+)
+
diff --git a/scm5d6.info b/scm5d6.info
new file mode 100644
index 0000000..7dbf40d
--- /dev/null
+++ b/scm5d6.info
@@ -0,0 +1,8382 @@
+This is scm.info, produced by makeinfo version 4.3 from scm.texi.
+
+INFO-DIR-SECTION The Algorithmic Language Scheme
+START-INFO-DIR-ENTRY
+* SCM: (scm). A Scheme interpreter.
+END-INFO-DIR-ENTRY
+
+
+File: scm.info, Node: Top, Next: Overview, Prev: (dir), Up: (dir)
+
+This manual documents the SCM Scheme implementation. SCM version
+5d6 was released May 2002. The most recent information about SCM can
+be found on SCM's "WWW" home page:
+
+ <http://swissnet.ai.mit.edu/~jaffer/SCM.html>
+
+Copyright (C) 1990-1999 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.
+
+* Menu:
+
+* Overview::
+* Installing SCM::
+* Operational Features::
+* The Language:: Reference.
+* Packages:: Optional Capabilities.
+* The Implementation:: How it works.
+* Index::
+
+
+File: scm.info, Node: Overview, Next: Installing SCM, Prev: Top, Up: Top
+
+Overview
+********
+
+Scm is a portable Scheme implementation written in C. Scm provides a
+machine independent platform for [JACAL], a symbolic algebra system.
+
+* Menu:
+
+* SCM Features::
+* SCM Authors::
+* Copying::
+* Bibliography::
+
+
+File: scm.info, Node: SCM Features, Next: SCM Authors, Prev: Overview, Up: Overview
+
+Features
+========
+
+ * Conforms to Revised^5 Report on the Algorithmic Language Scheme
+ [R5RS] and the [IEEE] P1178 specification.
+
+ * Support for [SICP], [R2RS], [R3RS], and [R5RS] scheme code.
+
+ * Runs under Amiga, Atari-ST, MacOS, MS-DOS, OS/2, NOS/VE, Unicos,
+ VMS, Unix and similar systems. Supports ASCII and EBCDIC
+ character sets.
+
+ * Is fully documented in TeXinfo form, allowing documentation to be
+ generated in info, TeX, html, nroff, and troff formats.
+
+ * Supports inexact real and complex numbers, 30 bit immediate
+ integers and large precision integers.
+
+ * Many Common Lisp functions: `logand', `logor', `logxor', `lognot',
+ `ash', `logcount', `integer-length', `bit-extract', `defmacro',
+ `macroexpand', `macroexpand1', `gentemp', `defvar', `force-output',
+ `software-type', `get-decoded-time', `get-internal-run-time',
+ `get-internal-real-time', `delete-file', `rename-file',
+ `copy-tree', `acons', and `eval'.
+
+ * `Char-code-limit', `most-positive-fixnum', `most-negative-fixnum',
+ `and internal-time-units-per-second' constants. `*Features*' and
+ `*load-pathname*' variables.
+
+ * Arrays and bit-vectors. String ports and software emulation ports.
+ I/O extensions providing ANSI C and POSIX.1 facilities.
+
+ * Interfaces to standard libraries including REGEX string regular
+ expression matching and the CURSES screen management package.
+
+ * Available add-on packages including an interactive debugger,
+ database, X-window graphics, BGI graphics, Motif, and Open-Windows
+ packages.
+
+ * A compiler (HOBBIT, available separately) and dynamic linking of
+ compiled modules.
+
+ * User definable responses to interrupts and errors,
+ Process-syncronization primitives. Setable levels of monitoring
+ and timing information printed interactively (the `verbose'
+ function). `Restart', `quit', and `exec'.
+
+
+File: scm.info, Node: SCM Authors, Next: Copying, Prev: SCM Features, Up: Overview
+
+Authors
+=======
+
+Aubrey Jaffer (jaffer @ alum.mit.edu)
+ Most of SCM.
+
+Radey Shouman
+ Arrays, `gsubr's, compiled closures, records, Ecache, syntax-rules
+ macros, and "safeport"s.
+
+Jerry D. Hedden
+ Real and Complex functions. Fast mixed type arithmetics.
+
+Hugh Secker-Walker
+ Syntax checking and memoization of special forms by evaluator.
+ Storage allocation strategy and parameters.
+
+George Carrette
+ "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
+ (*note Garbage Collection::).
+
+There are many other contributors to SCM. They are acknowledged in the
+file `ChangeLog', a log of changes that have been made to scm.
+
+
+File: scm.info, Node: Copying, Next: Bibliography, Prev: SCM Authors, Up: Overview
+
+Copyright
+=========
+
+Authors have assigned their SCM copyrights to:
+
+ Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111, USA
+
+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.
+
+ NO WARRANTY
+
+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.
+
+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.
+
+SIOD copyright
+==============
+
+
+ COPYRIGHT (c) 1989 BY
+ PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS.
+ ALL RIGHTS RESERVED
+
+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.
+
+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.
+
+gjc@paradigm.com
+ Phone: 617-492-6079
+
+Paradigm Associates Inc
+29 Putnam Ave, Suite 6
+Cambridge, MA 02138
+
+
+File: scm.info, Node: Bibliography, Prev: Copying, Up: Overview
+
+Bibliography
+============
+
+[IEEE]
+ `IEEE Standard 1178-1990. IEEE Standard for the Scheme
+ Programming Language.' IEEE, New York, 1991.
+
+[R4RS]
+ William Clinger and Jonathan Rees, Editors. Revised(4) Report on
+ the Algorithmic Language Scheme. `ACM Lisp Pointers' Volume IV,
+ Number 3 (July-September 1991), pp. 1-55.
+
+ *Note Top: (r4rs)Top.
+
+[R5RS]
+ Richard Kelsey and William Clinger and Jonathan (Rees, editors)
+ Revised(5) Report on the Algorithmic Language Scheme.
+ `Higher-Order and Symbolic Computation' Volume 11, Number 1 (1998),
+ pp. 7-105, and `ACM SIGPLAN Notices' 33(9), September 1998.
+
+ *Note Top: (r5rs)Top.
+
+[Exrename]
+ William Clinger Hygienic Macros Through Explicit Renaming `Lisp
+ Pointers' Volume IV, Number 4 (December 1991), pp 17-23.
+
+[SICP]
+ Harold Abelson and Gerald Jay Sussman with Julie Sussman.
+ `Structure and Interpretation of Computer Programs.' MIT Press,
+ Cambridge, 1985.
+
+[Simply]
+ Brian Harvey and Matthew Wright. `Simply Scheme: Introducing
+ Computer Science' MIT Press, 1994 ISBN 0-262-08226-8
+
+[SchemePrimer]
+ 犬飼大(Dai Inukai) `入門Scheme'
+ 1999年12月初版 ISBN4-87966-954-7
+
+[SLIB]
+ Todd R. Eigenschink, Dave Love, and Aubrey Jaffer. SLIB, The
+ Portable Scheme Library. Version 2c8, June 2000.
+
+ *Note Top: (slib)Top.
+
+[JACAL]
+ Aubrey Jaffer. JACAL Symbolic Mathematics System. Version 1b0,
+ Sep 1999.
+
+ *Note Top: (jacal)Top.
+
+`scm.texi'
+`scm.info'
+ Documentation of `scm' extensions (beyond Scheme standards).
+ Documentation on the internal representation and how to extend or
+ include `scm' in other programs.
+
+`Xlibscm.texi'
+`Xlibscm.info'
+ Documentation of the Xlib - SCM Language X Interface.
+
+
+File: scm.info, Node: Installing SCM, Next: Operational Features, Prev: Overview, Up: Top
+
+Installing SCM
+**************
+
+* Menu:
+
+* Making SCM:: Bootstrapping.
+* SLIB:: REQUIREd reading.
+* Building SCM::
+* Installing Dynamic Linking::
+* Configure Module Catalog::
+* Saving Images:: Make Fast-Booting Executables
+* Automatic C Preprocessor Definitions::
+* Problems Compiling::
+* Problems Linking::
+* Problems Running::
+* Testing::
+* Reporting Problems::
+
+
+File: scm.info, Node: Making SCM, Next: SLIB, Prev: Installing SCM, Up: Installing SCM
+
+Making SCM
+==========
+
+The SCM distribution has "Makefile" which contains rules for making
+"scmlit", a "bare-bones" version of SCM sufficient for running `build'.
+`build' is used to compile (or create scripts to compile) full
+featured versions.
+
+Makefiles are not portable to the majority of platforms. If `Makefile'
+works for you, good; If not, I don't want to hear about it. If you
+need to compile SCM without build, there are several ways to proceed:
+
+ * Use the build (http://swissnet.ai.mit.edu/~jaffer/buildscm.html)
+ web page to create custom batch scripts for compiling SCM.
+
+ * Use SCM on a different platform to run `build' to create a script
+ to build SCM;
+
+ * Use another implementation of Scheme to run `build' to create a
+ script to build SCM;
+
+ * Create your own script or `Makefile'.
+
+
+File: scm.info, Node: SLIB, Next: Building SCM, Prev: Making SCM, Up: Installing SCM
+
+SLIB
+====
+
+[SLIB] is a portable Scheme library meant to provide compatibility and
+utility functions for all standard Scheme implementations. Although
+SLIB is not _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:
+
+ * swissnet.ai.mit.edu:/pub/scm/slib2d4.tar.gz
+
+ * ftp.gnu.org:/pub/gnu/jacal/slib2d4.tar.gz
+
+ * ftp.cs.indiana.edu:/pub/scheme-repository/imp/slib2d4.tar.gz
+
+Unpack SLIB (`tar xzf slib2d4.tar.gz' or `unzip -ao slib2d4.zip') in an
+appropriate directory for your system; both `tar' and `unzip' will
+create the directory `slib'.
+
+Then create a file `require.scm' in the SCM "implementation-vicinity"
+(this is the same directory as where the file `Init5d6.scm' is
+installed). `require.scm' should have the contents:
+
+ (define (library-vicinity) "/usr/local/lib/slib/")
+ (load (in-vicinity (library-vicinity) "require"))
+
+where the pathname string `/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 (*note chmod: I/O-Extensions.).
+The way to specify a relative pathname is to append it to the
+implementation-vicinity, which is absolute:
+
+ (define library-vicinity
+ (let ((lv (string-append (implementation-vicinity) "../slib/")))
+ (lambda () lv)))
+ (load (in-vicinity (library-vicinity) "require"))
+
+Alternatively, you can set the (shell) environment variable
+`SCHEME_LIBRARY_PATH' to the pathname of the SLIB directory (*note
+SCHEME_LIBRARY_PATH: SCM Variables.). If set, the environment variable
+overrides `require.scm'. Again, absolute pathnames are recommended.
+
+
+File: scm.info, Node: Building SCM, Next: Installing Dynamic Linking, Prev: SLIB, Up: Installing SCM
+
+Building SCM
+============
+
+The file "build" loads the file "build.scm", which constructs a
+relational database of how to compile and link SCM executables.
+`build.scm' has information for the 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::
+* Compiling and Linking Custom Files::
+
+
+File: scm.info, Node: Invoking Build, Next: Build Options, Prev: Building SCM, Up: Building SCM
+
+Invoking Build
+--------------
+
+The _all_ method will also work for MS-DOS and unix. Use the _all_
+method if you encounter problems with `build'.
+
+MS-DOS
+ From the SCM source directory, type `build' followed by up to 9
+ command line arguments.
+
+unix
+ From the SCM source directory, type `./build' followed by command
+ line arguments.
+
+_all_
+ From the SCM source directory, start `scm' or `scmlit' and type
+ `(load "build")'. Alternatively, start `scm' or `scmlit' with the
+ command line argument `-ilbuild'.
+
+Invoking build without the `-F' option will build or create a shell
+script with the `arrays', `inexact', and `bignums' options as defaults.
+
+ bash$ ./build
+ -|
+ #! /bin/sh
+ # unix (linux) script created by SLIB/batch
+ # ================ Write file with C defines
+ rm -f scmflags.h
+ echo '#define IMPLINIT "Init5d6.scm"'>>scmflags.h
+ echo '#define BIGNUMS'>>scmflags.h
+ echo '#define FLOATS'>>scmflags.h
+ echo '#define ARRAYS'>>scmflags.h
+ # ================ Compile C source files
+ gcc -O2 -c continue.c scm.c scmmain.c findexec.c script.c time.c repl.c scl.c eval.c sys.c subr.c debug.c unif.c rope.c
+ # ================ Link C object files
+ gcc -rdynamic -o scm continue.o scm.o scmmain.o findexec.o script.o time.o repl.o scl.o eval.o sys.o subr.o debug.o unif.o rope.o -lm -lc
+
+To cross compile for another platform, invoke build with the `-p' or
+`--platform=' option. This will create a script for the platform named
+in the `-p' or `--platform=' option.
+
+ bash$ ./build -o scmlit -p darwin -F lit
+ -|
+ #! /bin/sh
+ # unix (darwin) script created by SLIB/batch
+ # ================ Write file with C defines
+ rm -f scmflags.h
+ echo '#define IMPLINIT "Init5d6.scm"'>>scmflags.h
+ # ================ Compile C source files
+ cc -O3 -c continue.c scm.c scmmain.c findexec.c script.c time.c repl.c scl.c eval.c sys.c subr.c debug.c unif.c rope.c
+ # ================ Link C object files
+ mv -f scmlit scmlit~
+ cc -o scmlit continue.o scm.o scmmain.o findexec.o script.o time.o repl.o scl.o eval.o sys.o subr.o debug.o unif.o rope.o
+
+
+File: scm.info, Node: Build Options, Next: Compiling and Linking Custom Files, Prev: Invoking Build, Up: Building SCM
+
+Build Options
+-------------
+
+The options to "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.
+
+ - Build Option: -p PLATFORM-NAME
+ - Build Option: --platform=PLATFORM-NAME
+ specifies that the compilation should be for a
+ computer/operating-system combination called PLATFORM-NAME.
+ _Note:_ The case of PLATFORM-NAME is distinguised. The current
+ PLATFORM-NAMEs are all lower-case.
+
+ The platforms defined by table "platform" in `build.scm' are:
+
+ Table: platform
+ name processor operating-system compiler
+ #f processor-family operating-system #f
+ symbol processor-family operating-system symbol
+ symbol atom symbol symbol
+ ================= ================= ================= =================
+ *unknown* *unknown* unix cc
+ acorn-unixlib acorn *unknown* cc
+ aix powerpc aix cc
+ alpha alpha osf1 cc
+ alpha-elf alpha unix cc
+ alpha-linux alpha linux gcc
+ amiga-aztec m68000 amiga cc
+ amiga-dice-c m68000 amiga dcc
+ amiga-gcc m68000 amiga gcc
+ amiga-sas m68000 amiga lc
+ atari-st-gcc m68000 atari.st gcc
+ atari-st-turbo-c m68000 atari.st tcc
+ borland-c 8086 ms-dos bcc
+ cygwin32 i386 unix gcc
+ darwin powerpc unix cc
+ djgpp i386 ms-dos gcc
+ freebsd i386 unix cc
+ gcc *unknown* unix gcc
+ highc i386 ms-dos hc386
+ hp-ux hp-risc hp-ux cc
+ irix mips irix gcc
+ linux i386 linux gcc
+ linux-aout i386 linux gcc
+ microsoft-c 8086 ms-dos cl
+ microsoft-c-nt i386 ms-dos cl
+ microsoft-quick-c 8086 ms-dos qcl
+ ms-dos 8086 ms-dos cc
+ openbsd *unknown* unix gcc
+ os/2-cset i386 os/2 icc
+ os/2-emx i386 os/2 gcc
+ sunos sparc sunos cc
+ svr4 *unknown* unix cc
+ svr4-gcc-sun-ld sparc sunos gcc
+ turbo-c 8086 ms-dos tcc
+ unicos cray unicos cc
+ unix *unknown* unix cc
+ vms vax vms cc
+ vms-gcc vax vms gcc
+ watcom-9.0 i386 ms-dos wcc386p
+
+ - Build Option: -o FILENAME
+ - Build Option: --outname=FILENAME
+ specifies that the compilation should produce an executable or
+ object name of FILENAME. The default is `scm'. Executable
+ suffixes will be added if neccessary, e.g. `scm' => `scm.exe'.
+
+ - Build Option: -l LIBNAME ...
+ - Build Option: --libraries=LIBNAME
+ specifies that the LIBNAME should be linked with the executable
+ produced. If compile flags or include directories (`-I') are
+ needed, they are automatically supplied for compilations. The `c'
+ library is always included. SCM "features" specify any libraries
+ they need; so you shouldn't need this option often.
+
+ - Build Option: -D DEFINITION ...
+ - Build Option: --defines=DEFINITION
+ specifies that the DEFINITION should be made in any C source
+ compilations. If compile flags or include directories (`-I') are
+ needed, they are automatically supplied for compilations. SCM
+ "features" specify any flags they need; so you shouldn't need this
+ option often.
+
+ - Build Option: --compiler-options=FLAG
+ specifies that that FLAG will be put on compiler command-lines.
+
+ - Build Option: --linker-options=FLAG
+ specifies that that FLAG will be put on linker command-lines.
+
+ - Build Option: -s PATHNAME
+ - Build Option: --scheme-initial=PATHNAME
+ specifies that PATHNAME should be the default location of the SCM
+ initialization file `Init5d6.scm'. SCM tries several likely
+ locations before resorting to PATHNAME (*note File-System
+ Habitat::). If not specified, the current directory (where build
+ is building) is used.
+
+ - Build Option: -c PATHNAME ...
+ - Build Option: --c-source-files=PATHNAME
+ specifies that the C source files PATHNAME ... are to be compiled.
+
+ - Build Option: -j PATHNAME ...
+ - Build Option: --object-files=PATHNAME
+ specifies that the object files PATHNAME ... are to be linked.
+
+ - Build Option: -i CALL ...
+ - Build Option: --initialization=CALL
+ specifies that the C functions CALL ... are to be invoked during
+ initialization.
+
+ - Build Option: -t BUILD-WHAT
+ - Build Option: --type=BUILD-WHAT
+ specifies in general terms what sort of thing to build. The
+ choices are:
+ `exe'
+ executable program.
+
+ `lib'
+ library module.
+
+ `dlls'
+ archived dynamically linked library object files.
+
+ `dll'
+ dynamically linked library object file.
+
+ The default is to build an executable.
+
+ - Build Option: -h BATCH-SYNTAX
+ - Build Option: -batch-dialect=BATCH-SYNTAX
+ specifies how to build. The default is to create a batch file for
+ the host system. The SLIB file `batch.scm' knows how to create
+ batch files for:
+ * unix
+
+ * dos
+
+ * vms
+
+ * amigaos (was amigados)
+
+ * system
+
+ This option executes the compilation and linking commands
+ through the use of the `system' procedure.
+
+ * *unknown*
+
+ This option outputs Scheme code.
+
+ - Build Option: -w BATCH-FILENAME
+ - Build Option: -script-name=BATCH-FILENAME
+ specifies where to write the build script. The default is to
+ display it on `(current-output-port)'.
+
+ - Build Option: -F FEATURE ...
+ - Build Option: --features=FEATURE
+ specifies to build the given features into the executable. The
+ defined features are:
+
+ "array"
+ Alias for ARRAYS
+
+ "array-for-each"
+ array-map! and array-for-each (arrays must also be featured).
+
+ "arrays"
+ Use if you want arrays, uniform-arrays and uniform-vectors.
+
+ "bignums"
+ Large precision integers.
+
+ "careful-interrupt-masking"
+ Define this for extra checking of interrupt masking and some
+ simple checks for proper use of malloc and free. This is for
+ debugging C code in `sys.c', `eval.c', `repl.c' and makes the
+ interpreter several times slower than usual.
+
+ "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
+ `reckless' disables any checking. If you want to have SCM
+ always check the number of arguments to interpreted closures
+ define feature `cautious'.
+
+ "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
+ _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.
+
+ "compiled-closure"
+ Use if you want to use compiled closures.
+
+ "curses"
+ For the "curses" screen management package.
+
+ "debug"
+ Turns on the features `cautious',
+ `careful-interrupt-masking', and `stack-limit'; uses `-g'
+ flags for debugging SCM source code.
+
+ "dump"
+ Convert a running scheme program into an executable file.
+
+ "dynamic-linking"
+ Be able to load compiled files while running.
+
+ "edit-line"
+ interface to the editline or GNU readline library.
+
+ "engineering-notation"
+ Use if you want floats to display in engineering notation
+ (exponents always multiples of 3) instead of scientific
+ notation.
+
+ "generalized-c-arguments"
+ `make_gsubr' for arbitrary (< 11) arguments to C functions.
+
+ "i/o-extensions"
+ Commonly available I/O extensions: "exec", line I/O, file
+ positioning, file delete and rename, and directory functions.
+
+ "inexact"
+ Use if you want floating point numbers.
+
+ "lit"
+ Lightweight - no features
+
+ "macro"
+ C level support for hygienic and referentially transparent
+ macros (syntax-rules macros).
+
+ "mysql"
+ Client connections to the mysql databases.
+
+ "no-heap-shrink"
+ Use if you want segments of unused heap to not be freed up
+ after garbage collection. This may increase time in GC for
+ *very* large working sets.
+
+ "none"
+ No features
+
+ "posix"
+ Posix functions available on all "Unix-like" systems. fork
+ and process functions, user and group IDs, file permissions,
+ and "link".
+
+ "reckless"
+ If your scheme code runs without any errors you can disable
+ almost all error checking by compiling all files with
+ `reckless'.
+
+ "record"
+ The Record package provides a facility for user to define
+ their own record data types. See SLIB for documentation.
+
+ "regex"
+ String regular expression matching.
+
+ "rev2-procedures"
+ These procedures were specified in the `Revised^2 Report on
+ Scheme' but not in `R4RS'.
+
+ "sicp"
+ Use if you want to run code from:
+
+ Harold Abelson and Gerald Jay Sussman with Julie Sussman.
+ `Structure and Interpretation of Computer Programs.' The MIT
+ Press, Cambridge, Massachusetts, USA, 1985.
+
+ Differences from R5RS are:
+ * (eq? '() '#f)
+
+ * (define a 25) returns the symbol a.
+
+ * (set! a 36) returns 36.
+
+ "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.
+
+ "socket"
+ BSD "socket" interface.
+
+ "stack-limit"
+ Use to enable checking for stack overflow. Define value of
+ the C preprocessor variable 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.
+
+ "tick-interrupts"
+ Use if you want the ticks and ticks-interrupt functions.
+
+ "turtlegr"
+ "Turtle" graphics calls for both Borland-C and X11 from
+ sjm@ee.tut.fi.
+
+ "unix"
+ Those unix features which have not made it into the Posix
+ specs: nice, acct, lstat, readlink, symlink, mknod and sync.
+
+ "windows"
+ Microsoft Windows executable.
+
+ "x"
+ Alias for Xlib feature.
+
+ "xlib"
+ Interface to Xlib graphics routines.
+
+
+
+File: scm.info, Node: Compiling and Linking Custom Files, Prev: Build Options, Up: Building SCM
+
+Compiling and Linking Custom Files
+----------------------------------
+
+A correspondent asks:
+
+ How can we link in our own c files to the SCM interpreter so that
+ we can add our own functionality? (e.g. we have a bunch of tcp
+ functions we want access to). Would this involve changing
+ build.scm or the Makefile or both?
+
+(*note Changing Scm:: has instructions describing the C code format).
+Suppose a C file "foo.c" has functions you wish to add to SCM. To
+compile and link your file at compile time, use the `-c' and `-i'
+options to build:
+
+ bash$ build -c foo.c -i init_foo
+ -|
+ #! /bin/sh
+ rm -f scmflags.h
+ echo '#define IMPLINIT "/home/jaffer/scm/Init5d6.scm"'>>scmflags.h
+ echo '#define COMPILED_INITS init_foo();'>>scmflags.h
+ echo '#define BIGNUMS'>>scmflags.h
+ echo '#define FLOATS'>>scmflags.h
+ echo '#define ARRAYS'>>scmflags.h
+ gcc -O2 -c continue.c scm.c findexec.c script.c time.c repl.c scl.c \
+ eval.c sys.c subr.c unif.c rope.c foo.c
+ gcc -rdynamic -o scm continue.o scm.o findexec.o script.o time.o \
+ repl.o scl.o eval.o sys.o subr.o unif.o rope.o foo.o -lm -lc
+
+To make a dynamically loadable object file use the `-t dll' option:
+
+ bash$ build -t dll -c foo.c
+ -|
+ #! /bin/sh
+ rm -f scmflags.h
+ echo '#define IMPLINIT "/home/jaffer/scm/Init5d6.scm"'>>scmflags.h
+ echo '#define BIGNUMS'>>scmflags.h
+ echo '#define FLOATS'>>scmflags.h
+ echo '#define ARRAYS'>>scmflags.h
+ echo '#define DLL'>>scmflags.h
+ gcc -O2 -fpic -c foo.c
+ gcc -shared -o foo.so foo.o -lm -lc
+
+Once `foo.c' compiles correctly (and your SCM build supports
+dynamic-loading), you can load the compiled file with the Scheme command
+`(load "./foo.so")'. See *Note Configure Module Catalog:: for how to
+add a compiled dll file to SLIB's catalog.
+
+
+File: scm.info, Node: Installing Dynamic Linking, Next: Configure Module Catalog, Prev: Building SCM, Up: Installing SCM
+
+Installing Dynamic Linking
+==========================
+
+Dynamic linking has not been ported to all platforms. Operating systems
+in the BSD family (a.out binary format) can usually be ported to "DLD".
+The "dl" library (`#define SUN_DL' for SCM) was a proposed POSIX
+standard and may be available on other machines with "COFF" binary
+format. For notes about porting to MS-Windows and finishing the port
+to VMS *Note Finishing Dynamic Linking::.
+
+"DLD" is a library package of C functions that performs "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:
+
+ * ftp.gnu.org:pub/gnu/dld-3.3.tar.gz
+
+These notes about using libdl on SunOS are from `gcc.info':
+
+ 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 `libdl.a' with some
+ versions of SunOS (mainly 4.1). This results in undefined symbols
+ when linking static binaries (that is, if you use `-static'). If
+ you see undefined symbols `_dlclose', `_dlsym' or `_dlopen' when
+ linking, compile and link against the file `mit/util/misc/dlsym.c'
+ from the MIT version of X windows.
+
+
+File: scm.info, Node: Configure Module Catalog, Next: Saving Images, Prev: Installing Dynamic Linking, Up: Installing SCM
+
+Configure Module Catalog
+========================
+
+The SLIB module "catalog" can be extended to define other
+`require'-able packages by adding calls to the Scheme source file
+`mkimpcat.scm'. Within `mkimpcat.scm', the following procedures are
+defined.
+
+ - Function: add-link feature object-file lib1 ...
+ FEATURE should be a symbol. OBJECT-FILE should be a string naming
+ a file containing compiled "object-code". Each LIBn argument
+ should be either a string naming a library file or `#f'.
+
+ If OBJECT-FILE exists, the `add-link' procedure registers symbol
+ FEATURE so that the first time `require' is called with the symbol
+ FEATURE as its argument, OBJECT-FILE and the LIB1 ... are
+ dynamically linked into the executing SCM session.
+
+ If OBJECT-FILE exists, `add-link' returns `#t', otherwise it
+ returns `#f'.
+
+ For example, to install a compiled dll `foo', add these lines to
+ `mkimpcat.scm':
+
+ (add-link 'foo
+ (in-vicinity (implementation-vicinity) "foo"
+ link:able-suffix))
+
+
+ - Function: add-alias alias feature
+ ALIAS and FEATURE are symbols. The procedure `add-alias'
+ registers ALIAS as an alias for FEATURE. An unspecified value is
+ returned.
+
+ `add-alias' causes `(require 'ALIAS)' to behave like `(require
+ 'FEATURE)'.
+
+ - Function: add-source feature filename
+ FEATURE is a symbol. FILENAME is a string naming a file
+ containing Scheme source code. The procedure `add-source'
+ registers FEATURE so that the first time `require' is called with
+ the symbol FEATURE as its argument, the file FILENAME will be
+ `load'ed. An unspecified value is returned.
+
+Remember to delete the file `slibcat' after modifying the file
+`mkimpcat.scm' in order to force SLIB to rebuild its cache.
+
+
+File: scm.info, Node: Saving Images, Next: Automatic C Preprocessor Definitions, Prev: Configure Module Catalog, Up: Installing SCM
+
+Saving Images
+=============
+
+In SCM, the ability to save running program images is called "dump"
+(*note Dump::). In order to make `dump' available to SCM, build with
+feature `dump'. `dump'ed executables are compatible with dynamic
+linking.
+
+Most of the code for "dump" is taken from `emacs-19.34/src/unex*.c'.
+No modifications to the emacs source code were required to use
+`unexelf.c'. Dump has not been ported to all platforms. If `unexec.c'
+or `unexelf.c' don't work for you, try using the appropriate `unex*.c'
+file from emacs.
+
+
+File: scm.info, Node: Automatic C Preprocessor Definitions, Next: Problems Compiling, Prev: Saving Images, Up: Installing SCM
+
+Automatic C Preprocessor Definitions
+====================================
+
+These `#defines' are automatically provided by preprocessors of various
+C compilers. SCM uses the presence or absence of these definitions to
+configure "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 `-DFLAG' to the compilation command
+lines or add a `#define FLAG' line to `scmfig.h' or the beginning of
+`scmfig.h'.
+
+ #define Platforms:
+ ------- ----------
+ ARM_ULIB Huw Rogers free unix library for acorn archimedes
+ AZTEC_C Aztec_C 5.2a
+ __CYGWIN__ Cygwin
+ _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
+ __MWERKS__ Metrowerks Compiler; Macintosh and WIN32 (?)
+ _POSIX_SOURCE ??
+ _QC Microsoft QuickC
+ __STDC__ ANSI C compliant
+ __TURBOC__ Turbo C and Borland C
+ __USE_POSIX ??
+ __WATCOMC__ Watcom C on MS-DOS
+ __ZTC__ Zortech C
+
+ _AIX AIX operating system
+ __APPLE__ Apple Darwin
+ AMIGA SAS/C 5.10 or Dice C on AMIGA
+ __amigaos__ Gnu CC on AMIGA
+ atarist ATARI-ST under Gnu CC
+ __FreeBSD__ FreeBSD
+ GNUDOS DJGPP (obsolete in version 1.08)
+ __GO32__ DJGPP (future?)
+ hpux HP-UX
+ linux Linux
+ macintosh Macintosh (THINK_C and __MWERKS__ define)
+ MCH_AMIGA Aztec_c 5.2a on AMIGA
+ __MACH__ Apple Darwin
+ 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.
+ __SVR4 SunOS
+ 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
+ vaxc VAX C compiler
+ VAXC VAX C compiler
+ vax11c VAX C compiler
+ VAX11 VAX C compiler
+ _Windows Borland C 3.1 compiling for Windows
+ _WIN32 MS VisualC++ 4.2 and Cygwin (Win32 API)
+ vms (and VMS) VAX-11 C under VMS.
+
+ __alpha DEC Alpha processor
+ __alpha__ DEC Alpha processor
+ hp9000s800 HP RISC processor
+ __i386__ DJGPP
+ i386 DJGPP
+ MULTIMAX Encore computer
+ ppc PowerPC
+ __ppc__ PowerPC
+ pyr Pyramid 9810 processor
+ __sgi__ Silicon Graphics Inc.
+ sparc SPARC processor
+ sequent Sequent computer
+ tahoe CCI Tahoe processor
+ vax VAX processor
+
+
+File: scm.info, Node: Problems Compiling, Next: Problems Linking, Prev: Automatic C Preprocessor Definitions, Up: Installing SCM
+
+Problems Compiling
+==================
+
+FILE PROBLEM / MESSAGE HOW TO FIX
+*.c include file not found. Correct the status of
+ STDC_HEADERS in scmfig.h.
+ fix #include statement or add
+ #define for system type to
+ scmfig.h.
+*.c Function should return a value. Ignore.
+ Parameter is never used.
+ Condition is always false.
+ Unreachable code in function.
+scm.c assignment between incompatible Change SIGRETTYPE in scm.c.
+ types.
+time.c CLK_TCK redefined. incompatablility between
+ <stdlib.h> and <sys/types.h>.
+ Remove STDC_HEADERS in scmfig.h.
+ Edit <sys/types.h> to remove
+ incompatability.
+subr.c Possibly incorrect assignment Ignore.
+ in function lgcd.
+sys.c statement not reached. Ignore.
+ constant in conditional
+ expression.
+sys.c undeclared, outside of #undef STDC_HEADERS in scmfig.h.
+ functions.
+scl.c syntax error. #define SYSTNAME to your system
+ type in scl.c (softtype).
+
+
+File: scm.info, Node: Problems Linking, Next: Problems Running, Prev: Problems Compiling, Up: Installing SCM
+
+Problems Linking
+================
+
+PROBLEM HOW TO FIX
+_sin etc. missing. Uncomment LIBS in makefile.
+
+
+File: scm.info, Node: Problems Running, Next: Testing, Prev: Problems Linking, Up: Installing SCM
+
+Problems Running
+================
+
+PROBLEM HOW TO FIX
+Opening message and then machine Change memory model option to C
+crashes. compiler (or makefile).
+ Make sure sizet definition is
+ correct in scmfig.h.
+ Reduce the size of HEAP_SEG_SIZE in
+ setjump.h.
+Input hangs. #define NOSETBUF
+ERROR: heap: need larger initial. Increase initial heap allocation
+ using -a<kb> or INIT_HEAP_SIZE.
+ERROR: Could not allocate. Check sizet definition.
+ Use 32 bit compiler mode.
+ Don't try to run as subproccess.
+remove <FLAG> in scmfig.h and Do so and recompile files.
+recompile scm.
+add <FLAG> in scmfig.h and
+recompile scm.
+ERROR: Init5d6.scm not found. Assign correct IMPLINIT in makefile
+ or scmfig.h.
+ Define environment variable
+ SCM_INIT_PATH to be the full
+ pathname of Init5d6.scm.
+WARNING: require.scm not found. Define environment variable
+ SCHEME_LIBRARY_PATH to be the full
+ pathname of the scheme library
+ [SLIB].
+ Change library-vicinity in
+ Init5d6.scm to point to library or
+ remove.
+ Make sure the value of
+ (library-vicinity) has a trailing
+ file separator (like / or \).
+
+
+File: scm.info, Node: Testing, Next: Reporting Problems, Prev: Problems Running, Up: Installing SCM
+
+Testing
+=======
+
+Loading `r4rstest.scm' in the distribution will run an [R4RS]
+conformance test on `scm'.
+
+ > (load "r4rstest.scm")
+ -|
+ ;loading "r4rstest.scm"
+ SECTION(2 1)
+ SECTION(3 4)
+ #<primitive-procedure boolean?>
+ #<primitive-procedure char?>
+ #<primitive-procedure null?>
+ #<primitive-procedure number?>
+ ...
+
+Loading `pi.scm' in the distribution will enable you to compute digits
+of pi.
+
+ > (load "pi")
+ ;loading "pi"
+ ;done loading "pi.scm"
+ ;Evaluation took 20 ms (0 in gc) 767 cells work, 233.B 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 ms (60 in gc) 36976 cells work, 1548.B other
+ #<unspecified>
+
+Loading `bench.scm' will compute and display performance statistics of
+SCM running `pi.scm'. `make bench' or `make benchlit' appends the
+performance report to the file `BenchLog', facilitating tracking
+effects of changes to SCM on performance.
+
+PROBLEM HOW TO FIX
+Runs some and then machine crashes. See above under machine crashes.
+Runs some and then ERROR: ... Remove optimization option to C
+(after a GC has happened). compiler and recompile.
+ #define SHORT_ALIGN in `scmfig.h'.
+Some symbol names print incorrectly. Change memory model option to C
+ compiler (or makefile).
+ Check that HEAP_SEG_SIZE fits
+ within sizet.
+ Increase size of HEAP_SEG_SIZE (or
+ INIT_HEAP_SIZE if it is smaller
+ than HEAP_SEG_SIZE).
+ERROR: Rogue pointer in Heap. See above under machine crashes.
+Newlines don't appear correctly in Check file mode (define OPEN_... in
+output files. `Init5d6.scm').
+Spaces or control characters appear Check character defines in
+in symbol names. `scmfig.h'.
+Negative numbers turn positive. Check SRS in `scmfig.h'.
+VMS: Couldn't unwind stack. #define CHEAP_CONTIUATIONS in
+ `scmfig.h'.
+VAX: botched longjmp.
+
+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 _conservative_ GC until we find
+ what instruction will clear the register windows. This problem is
+ exacerbated by using lots of call-with-current-continuations.
+
+
+File: scm.info, Node: Reporting Problems, Prev: Testing, Up: Installing SCM
+
+Reporting Problems
+==================
+
+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 `jaffer @ alum.mit.edu'. The bug report
+should include:
+
+ 1. The version of SCM (printed when SCM is invoked with no arguments).
+
+ 2. The type of computer you are using.
+
+ 3. The name and version of your computer's operating system.
+
+ 4. The values of the environment variables `SCM_INIT_PATH' and
+ `SCHEME_LIBRARY_PATH'.
+
+ 5. The name and version of your C compiler.
+
+ 6. 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.
+
+
+File: scm.info, Node: Operational Features, Next: The Language, Prev: Installing SCM, Up: Top
+
+Operational Features
+********************
+
+* Menu:
+
+* Invoking SCM::
+* SCM Options::
+* Invocation Examples::
+* SCM Variables::
+* SCM Session::
+* Editing Scheme Code::
+* Debugging Scheme Code::
+* Errors::
+* Memoized Expressions::
+* Internal State::
+* Scripting::
+
+
+File: scm.info, Node: Invoking SCM, Next: SCM Options, Prev: Operational Features, Up: Operational Features
+
+Invoking SCM
+============
+
+ scm [-a kbytes] [-muvbiq] [-version] [-help]
+ [[-]-no-init-file] [-p int] [-r feature] [-h feature]
+ [-d filename] [-f filename] [-l filename]
+ [-c expression] [-e expression] [-o dumpname]
+ [-- | - | -s] [filename] [arguments ...]
+
+Upon startup `scm' loads the file specified by by the environment
+variable SCM_INIT_PATH.
+
+If SCM_INIT_PATH is not defined or if the file it names is not present,
+`scm' tries to find the directory containing the executable file. If
+it is able to locate the executable, `scm' looks for the initialization
+file (usually `Init5d6.scm') in platform-dependent directories relative
+to this directory. See *Note File-System Habitat:: for a blow-by-blow
+description.
+
+As a last resort (if initialization file cannot be located), the C
+compile parameter IMPLINIT (defined in the makefile or `scmfig.h') is
+tried.
+
+Unless the option `-no-init-file' or `--no-init-file' occurs in the
+command line, `Init5d6.scm' checks to see if there is file
+`ScmInit.scm' in the path specified by the environment variable HOME
+(or in the current directory if HOME is undefined). If it finds such a
+file it is loaded.
+
+`Init5d6.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.
+
+This explanation applies to SCMLIT or other builds of SCM.
+
+Scheme-code files can also invoke SCM and its variants. *Note #!:
+Syntax Extensions.
+
+
+File: scm.info, Node: SCM Options, Next: Invocation Examples, Prev: Invoking SCM, Up: Operational Features
+
+Options
+=======
+
+The options are processed in the order specified on the command line.
+
+ - Command Option: -a k
+ specifies that `scm' should allocate an initial heapsize of K
+ kilobytes. This option, if present, must be the first on the
+ command line. If not specified, the default is `INIT_HEAP_SIZE'
+ in source file `setjump.h' which the distribution sets at
+ `25000*sizeof(cell)'.
+
+ - Command Option: -no-init-file
+ - Command Option: --no-init-file
+ Inhibits the loading of `ScmInit.scm' as described above.
+
+ - Command Option: --help
+ prints usage information and URI; then exit.
+
+ - Command Option: --version
+ prints version information and exit.
+
+ - Command Option: -r feature
+ requires FEATURE. This will load a file from [SLIB] if that
+ FEATURE is not already provided. If FEATURE is 2, 2rs, r2rs, 3,
+ 3rs, r3rs, 4, 4rs, r4rs, 5, 5rs, or r5rs; `scm' will require the
+ features neccessary to support [R2RS], [R3RS], [R4RS], or [R5RS],
+ respectively.
+
+ - Command Option: -h feature
+ provides FEATURE.
+
+ - Command Option: -l filename
+ - Command Option: -f filename
+ loads FILENAME. `Scm' will load the first (unoptioned) file named
+ on the command line if no `-c', `-e', `-f', `-l', or `-s' option
+ preceeds it.
+
+ - Command Option: -d filename
+ Loads SLIB `databases' feature and opens FILENAME as a database.
+
+ - Command Option: -e expression
+ - Command Option: -c expression
+ specifies that the scheme expression EXPRESSION is to be
+ evaluated. These options are inspired by `perl' and `sh'
+ respectively. On Amiga systems the entire option and argument
+ need to be enclosed in quotes. For instance `"-e(newline)"'.
+
+ - Command Option: -o dumpname
+ saves the current SCM session as the executable program `dumpname'.
+ This option works only in SCM builds supporting `dump' (*note
+ Dump::).
+
+ If options appear on the command line after `-o DUMPNAME', 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.
+
+ - Command Option: -p level
+ sets the prolixity (verboseness) to LEVEL. This is the same as
+ the `scm' command (verobse LEVEL).
+
+ - Command Option: -v
+ (verbose mode) specifies that `scm' will print prompts, evaluation
+ times, notice of loading files, and garbage collection statistics.
+ This is the same as `-p3'.
+
+ - Command Option: -q
+ (quiet mode) specifies that `scm' will print no extra information.
+ This is the same as `-p0'.
+
+ - Command Option: -m
+ specifies that subsequent loads, evaluations, and user
+ interactions will be with syntax-rules macro capability. To use a
+ specific syntax-rules macro implementation from [SLIB] (instead of
+ [SLIB]'s default) put `-r' MACROPACKAGE before `-m' on the command
+ line.
+
+ - Command Option: -u
+ specifies that subsequent loads, evaluations, and user
+ interactions will be without syntax-rules macro capability.
+ Syntax-rules macro capability can be restored by a subsequent `-m'
+ on the command line or from Scheme code.
+
+ - Command Option: -i
+ specifies that `scm' should run interactively. That means that
+ `scm' will not terminate until the `(quit)' or `(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 `scm' is started from a tty, it
+ will assume that it should be interactive unless given a
+ subsequent `-b' option.
+
+ - Command Option: -b
+ specifies that `scm' should run non-interactively. That means that
+ `scm' will terminate after processing the command line or if there
+ are errors.
+
+ - Command Option: -s
+ specifies, by analogy with `sh', that further options are to be
+ treated as program aguments.
+
+ - Command Option: -
+ - Command Option: --
+ specifies that there are no more options on the command line.
+
+
+File: scm.info, Node: Invocation Examples, Next: SCM Variables, Prev: SCM Options, Up: Operational Features
+
+Invocation Examples
+===================
+
+`% scm foo.scm'
+ Loads and executes the contents of `foo.scm' and then enters
+ interactive session.
+
+`% scm -f foo.scm arg1 arg2 arg3'
+ Parameters `arg1', `arg2', and `arg3' are stored in the global
+ list `*argv*'; Loads and executes the contents of `foo.scm' and
+ exits.
+
+`% scm -s foo.scm arg1 arg2'
+ Sets *argv* to `("foo.scm" "arg1" "arg2")' and enters interactive
+ session.
+
+`% scm -e `(write (list-ref *argv* *optind*))' bar'
+ Prints `"bar"'.
+
+`% scm -rpretty-print -r format -i'
+ Loads `pretty-print' and `format' and enters interactive session.
+
+`% scm -r5'
+ Loads `dynamic-wind', `values', and syntax-rules macros and enters
+ interactive (with macros) session.
+
+`% scm -r5 -r4'
+ Like above but `rev4-optional-procedures' are also loaded.
+
+
+File: scm.info, Node: SCM Variables, Next: SCM Session, Prev: Invocation Examples, Up: Operational Features
+
+Environment Variables
+=====================
+
+ - Environment Variable: SCM_INIT_PATH
+ is the pathname where `scm' will look for its initialization code.
+ The default is the file `Init5d6.scm' in the source directory.
+
+ - Environment Variable: SCHEME_LIBRARY_PATH
+ is the [SLIB] Scheme library directory.
+
+ - Environment Variable: HOME
+ is the directory where `Init5d6.scm' will look for the user
+ initialization file `ScmInit.scm'.
+
+ - Environment Variable: EDITOR
+ is the name of the program which `ed' will call. If EDITOR is not
+ defined, the default is `ed'.
+
+Scheme Variables
+================
+
+ - Variable: *argv*
+ contains the list of arguments to the program. `*argv*' can change
+ during argument processing. This list is suitable for use as an
+ argument to [SLIB] `getopt'.
+
+ - Variable: *syntax-rules*
+ controls whether loading and interaction support syntax-rules
+ macros. Define this in `ScmInit.scm' or files specified on the
+ command line. This can be overridden by subsequent `-m' and `-u'
+ options.
+
+ - Variable: *interactive*
+ controls interactivity as explained for the `-i' and `-b' options.
+ Define this in `ScmInit.scm' or files specified on the command
+ line. This can be overridden by subsequent `-i' and `-b' options.
+
+
+File: scm.info, Node: SCM Session, Next: Editing Scheme Code, Prev: SCM Variables, Up: Operational Features
+
+SCM Session
+===========
+
+ * Options, file loading and features can be specified from the
+ command line. *Note System interface: (scm)System interface.
+ *Note Require: (slib)Require.
+
+ * Typing the end-of-file character at the top level session (while
+ SCM is not waiting for parenthesis closure) causes SCM to exit.
+
+ * Typing the interrupt character aborts evaluation of the current
+ form and resumes the top level read-eval-print loop.
+
+ - Function: quit
+ - Function: quit n
+ - Function: exit
+ - Function: exit n
+ Aliases for `exit' (*note exit: (slib)System.). On many systems,
+ SCM can also tail-call another program. *Note execp:
+ I/O-Extensions.
+
+ - Callback procedure: boot-tail dumped?
+ `boot-tail' is called by `scm_top_level' just before entering
+ interactive top-level. If `boot-tail' calls `quit', then
+ interactive top-level is not entered.
+
+ - Function: program-arguments
+ Returns a list of strings of the arguments scm was called with.
+
+For documentation of the procedures `getenv' and `system' *Note System
+Interface: (slib)System Interface.
+
+ - Function: vms-debug
+ If SCM is compiled under VMS this `vms-debug' will invoke the VMS
+ debugger.
+
+
+File: scm.info, Node: Editing Scheme Code, Next: Debugging Scheme Code, Prev: SCM Session, Up: Operational Features
+
+Editing Scheme Code
+===================
+
+ - Function: ed arg1 ...
+ The value of the environment variable `EDITOR' (or just `ed' if it
+ isn't defined) is invoked as a command with arguments ARG1 ....
+
+ - Function: ed filename
+ If SCM is compiled under VMS `ed' will invoke the editor with a
+ single the single argument FILENAME.
+
+Gnu Emacs:
+ Editing of Scheme code is supported by emacs. Buffers holding
+ files ending in .scm are automatically put into scheme-mode.
+ EMACS for MS-DOS and MS-Windows systems is available (free) from:
+
+ <http://simtel.coast.net/SimTel/gnu/demacs.html>
+ If your Emacs can
+ run a process in a buffer you can use the Emacs command `M-x
+ run-scheme' with SCM. Otherwise, use the emacs command `M-x
+ suspend-emacs'; or see "other systems" below.
+
+Epsilon (MS-DOS):
+ There is lisp (and scheme) mode available by use of the package
+ `LISP.E'. It offers several different indentation formats. With
+ this package, buffers holding files ending in `.L', `.LSP', `.S',
+ and `.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 `-e512 -m0' are neccessary to
+ manage RAM properly. It has been reported that when compiling SCM
+ with Turbo C, you need to `#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.
+
+other systems:
+ Define the environment variable `EDITOR' to be the name of the
+ editing program you use. The SCM procedure `(ed arg1 ...)' will
+ invoke your editor and return to SCM when you exit the editor. The
+ following definition is convenient:
+
+ (define (e) (ed "work.scm") (load "work.scm"))
+
+ Typing `(e)' will invoke the editor with the file of interest.
+ After editing, the modified file will be loaded.
+
+
+File: scm.info, Node: Debugging Scheme Code, Next: Errors, Prev: Editing Scheme Code, Up: Operational Features
+
+Debugging Scheme Code
+=====================
+
+The `cautious' and `stack-limit' options of `build' (*note Build
+Options::) support debugging in Scheme.
+
+"CAUTIOUS"
+ If SCM is built with the `CAUTIOUS' flag, then when an error
+ occurs, a "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. See *Note Memoized Expressions:: for
+ how to read memoized expressions.
+
+ Also as the result of the `CAUTIOUS' flag, both `error' and
+ `user-interrupt' (invoked by <C-c>) to print stack traces and
+ conclude by calling `breakpoint' (*note Breakpoints:
+ (slib)Breakpoints.) instead of aborting to top level. Under
+ either condition, program execution can be resumed by `(continue)'.
+
+ In this configuration one can interrupt a running Scheme program
+ with <C-c>, inspect or modify top-level values, trace or untrace
+ procedures, and continue execution with `(continue)'.
+
+"STACK_LIMIT"
+ If SCM is built with the `STACK_LIMIT' flag, the interpreter will
+ check stack size periodically. If the size of stack exceeds a
+ certain amount (default is `HEAP_SEG_SIZE/2'), SCM generates a
+ `segment violation' interrupt.
+
+ The usefulness of `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.
+
+There are several SLIB macros which so useful that SCM automatically
+loads the appropriate module from SLIB if they are invoked.
+
+ - Macro: trace proc1 ...
+ Traces the top-level named procedures given as arguments.
+
+ - Macro: 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.
+
+ - Macro: untrace proc1 ...
+ Turns tracing off for its arguments.
+
+ - Macro: untrace
+ With no arguments, untraces all currently traced identifiers and
+ returns a list of these formerly traced identifiers.
+
+The routines I use most frequently for debugging are:
+
+ - Procedure: print arg1 ...
+ `Print' writes all its arguments, separated by spaces. `Print'
+ outputs a `newline' at the end and returns the value of the last
+ argument.
+
+ One can just insert `(print '<proc-name>' and `)' around an
+ expression in order to see its value as a program operates.
+
+ - Syntax: print-args name1 ...
+ Writes NAME1 ... (separated by spaces) and then writes the values
+ of the closest lexical bindings enclosing the call to `Print-args'.
+
+ (define (foo a b) (print-args foo) (+ a b))
+ (foo 3 6)
+ -| In foo: a = 3; b = 6;
+ => 9
+
+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, *Note Quick Print: (slib)Quick Print, can be
+used.
+
+When `trace' is not sufficient to find program flow problems, SLIB-PSD,
+the Portable Scheme Debugger offers source code debugging from GNU
+Emacs. PSD runs slowly, so start by instrumenting only a few functions
+at a time.
+ http://swissnet.ai.mit.edu/ftpdir/scm/slib-psd1-3.tar.gz
+ swissnet.ai.mit.edu:/pub/scm/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
+
+
+File: scm.info, Node: Errors, Next: Memoized Expressions, Prev: Debugging Scheme Code, Up: Operational Features
+
+Errors
+======
+
+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.
+
+The following common error and conditions are handled by C code. Those
+with callback names after them can also be handled by Scheme code
+(*note 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.
+
+"ARGn"
+ Wrong type in argument
+
+"ARG1"
+ Wrong type in argument 1
+
+"ARG2"
+ Wrong type in argument 2
+
+"ARG3"
+ Wrong type in argument 3
+
+"ARG4"
+ Wrong type in argument 4
+
+"ARG5"
+ Wrong type in argument 5
+
+"WNA"
+ Wrong number of args
+
+"OVFLOW"
+ numerical overflow
+
+"OUTOFRANGE"
+ Argument out of range
+
+"NALLOC"
+ `(out-of-storage)'
+
+"THRASH"
+ GC is `(thrashing)'
+
+"EXIT"
+ `(end-of-program)'
+
+"HUP_SIGNAL"
+ `(hang-up)'
+
+"INT_SIGNAL"
+ `(user-interrupt)'
+
+"FPE_SIGNAL"
+ `(arithmetic-error)'
+
+"BUS_SIGNAL"
+ bus error
+
+"SEGV_SIGNAL"
+ segment violation
+
+"ALRM_SIGNAL"
+ `(alarm-interrupt)'
+
+"VTALRM_SIGNAL"
+ `(virtual-alarm-interrupt)'
+
+"PROF_SIGNAL"
+ `(profile-alarm-interrupt)'
+
+ - Variable: errobj
+ When 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 ERROBJ is the
+ offending object if appropriate. The builtin procedure `error'
+ does _not_ set ERROBJ.
+
+`errno' and `perror' report ANSI C errors encountered during a call to
+a system or library function.
+
+ - Function: errno
+ - Function: errno n
+ With no argument returns the current value of the system variable
+ `errno'. When given an argument, `errno' sets the system variable
+ `errno' to N and returns the previous value of `errno'. `(errno
+ 0)' will clear outstanding errors. This is recommended after
+ `try-load' returns `#f' since this occurs when the file could not
+ be opened.
+
+ - Function: perror string
+ Prints on standard error output the argument STRING, a colon,
+ followed by a space, the error message corresponding to the current
+ value of `errno' and a newline. The value returned is unspecified.
+
+`warn' and `error' provide a uniform way for Scheme code to signal
+warnings and errors.
+
+ - Function: warn arg1 arg2 arg3 ...
+ Alias for *Note slib:warn: (slib)System. Outputs an error message
+ containing the arguments. `warn' is defined in `Init5d6.scm'.
+
+ - Function: error arg1 arg2 arg3 ...
+ Alias for *Note slib:error: (slib)System. 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 `Init5d6.scm'.
+
+If SCM is built with the `CAUTIOUS' flag, then when an error occurs, a
+"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. See *Note Memoized Expressions:: for how to read memoized
+expressions.
+
+Also as the result of the `CAUTIOUS' flag, both `error' and
+`user-interrupt' (invoked by <C-c>) are defined to print stack traces
+and conclude by calling `breakpoint' (*note Breakpoints:
+(slib)Breakpoints.). This allows the user to interract with SCM as
+with Lisp systems.
+
+ - Function: stack-trace
+ Prints information describing the stack of partially evaluated
+ expressions. `stack-trace' returns `#t' if any lines were printed
+ and `#f' otherwise. See `Init5d6.scm' for an example of the use
+ of `stack-trace'.
+
+
+File: scm.info, Node: Memoized Expressions, Next: Internal State, Prev: Errors, Up: Operational Features
+
+Memoized Expressions
+====================
+
+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.
+
+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.
+
+ * The names of memoized lexically bound identifiers are replaced with
+ #@<m>-<n>, where <m> is the number of binding contours back and
+ <n> is the index of the value in that binding countour.
+
+ * The names of identifiers which are not lexiallly bound but defined
+ at top-level have #@ prepended.
+
+For instance, `open-input-file' is defined as follows in `Init5d6.scm':
+
+ (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)))
+
+If `open-input-file' has not yet been used, the displayed procedure is
+similar to the original definition (lines wrapped for readability):
+
+ open-input-file =>
+ #<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))>
+
+If we open a file using `open-input-file', the sections of code used
+become memoized:
+
+ (open-input-file "r4rstest.scm") => #<input-port 3>
+ open-input-file =>
+ #<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))>
+
+If we cause `open-input-file' to execute other sections of code, they
+too become memoized:
+
+ (open-input-file "foo.scm") =>
+
+ ERROR: No such file or directory
+ ERROR: OPEN-INPUT-FILE couldn't open file "foo.scm"
+
+ open-input-file =>
+ #<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))>
+
+
+File: scm.info, Node: Internal State, Next: Scripting, Prev: Memoized Expressions, Up: Operational Features
+
+Internal State
+==============
+
+ - Variable: *interactive*
+ The variable *INTERACTIVE* determines whether the SCM session is
+ interactive, or should quit after the command line is processed.
+ *INTERACTIVE* is controlled directly by the command-line options
+ `-b', `-i', and `-s' (*note Invoking SCM::). If none of these
+ options are specified, the rules to determine interactivity are
+ more complicated; see `Init5d6.scm' for details.
+
+ - Function: abort
+ Resumes the top level Read-Eval-Print loop.
+
+ - Function: restart
+ Restarts the SCM program with the same arguments as it was
+ originally invoked. All `-l' loaded files are loaded again; If
+ those files have changed, those changes will be reflected in the
+ new session.
+
+ _Note:_ When running a saved executable (*note Dump::), `restart'
+ is redefined to be `exec-self'.
+
+ - Function: 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 _new_ executable
+ will be invoked. This differentiates `exec-self' from `restart'.
+
+ - Function: verbose n
+ Controls how much monitoring information is printed. If N is:
+
+ 0
+ no prompt or information is printed.
+
+ >= 1
+ a prompt is printed.
+
+ >= 2
+ messages bracketing file loading are printed.
+
+ >= 3
+ the CPU time is printed after each top level form evaluated;
+ notifications of heap growth printed.
+
+ >= 4
+ a garbage collection summary is printed after each top level
+ form evaluated;
+
+ >= 5
+ a message for each GC (*note Garbage Collection::) is printed;
+ warnings issued for top-level symbols redefined.
+
+ - Function: gc
+ Scans all of SCM objects and reclaims for further use those that
+ are no longer accessible.
+
+ - Function: room
+ - Function: room #t
+ Prints out statistics about SCM's current use of storage. `(room
+ #t)' also gives the hexadecimal heap segment and stack bounds.
+
+ - Constant: *scm-version*
+ Contains the version string (e.g. `5d6') of SCM.
+
+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 (*note
+Executable Pathname::) guesses incorrectly the location of the
+currently running executable. In that case, the correct path can be set
+by calling `execpath' with the pathname.
+
+ - Function: 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.
+
+ - Function: execpath #f
+ - Function: execpath newpath
+ Sets the path to `#f' or NEWPATH, respectively. The old path is
+ returned.
+
+For other configuration constants and procedures *Note Configuration:
+(slib)Configuration.
+
+
+File: scm.info, Node: Scripting, Prev: Internal State, Up: Operational Features
+
+Scripting
+=========
+
+* Menu:
+
+* Unix Scheme Scripts:: From Olin Shivers' Scheme Shell
+* MS-DOS Compatible Scripts:: Run in MS-DOS and Unix
+* Unix Shell Scripts:: Use /bin/sh to run Scheme
+
+
+File: scm.info, Node: Unix Scheme Scripts, Next: MS-DOS Compatible Scripts, Prev: Scripting, Up: Scripting
+
+Unix Scheme Scripts
+-------------------
+
+In reading this section, keep in mind that the first line of a script
+file has (different) meanings to SCM and the operating system
+(`execve').
+
+ - file: #! interpreter \ ...
+ On unix systems, a "Shell-Script" is a file (with execute
+ permissions) whose first two characters are `#!'. The INTERPRETER
+ argument must be the pathname of the program to process the rest
+ of the file. The directories named by environment variable `PATH'
+ are _not_ searched to find INTERPRETER.
+
+ When executing a shell-script, the operating system invokes
+ INTERPRETER with a single argument encapsulating the rest of the
+ first line's contents (if if not just whitespace), the pathname of
+ the Scheme Script file, and then any arguments which the
+ shell-script was invoked with.
+
+ Put one space character between `#!' and the first character of
+ INTERPRETER (`/'). The INTERPRETER name is followed by ` \'; SCM
+ substitutes the second line of FILE for `\' (and the rest of the
+ line), then appends any arguments given on the command line
+ invoking this Scheme-Script.
+
+ When SCM executes the script, the Scheme variable *SCRIPT* will be
+ set to the script pathname. The last argument before `!#' on the
+ second line should be `-'; SCM will load the script file, preserve
+ the unprocessed arguments, and set *ARGV* to a list of the script
+ pathname and the unprocessed arguments.
+
+ Note that the interpreter, not the operating system, provides the
+ `\' substitution; this will only take place if INTERPRETER is a
+ SCM or SCSH interpreter.
+
+ - Read syntax: #! ignored !#
+ When the first two characters of the file being loaded are `#!' and
+ a `\' is present before a newline in the file, all characters up
+ to `!#' will be ignored by SCM `read'.
+
+This combination of interpretatons allows SCM source files to be used as
+POSIX shell-scripts if the first line is:
+
+ #! /usr/local/bin/scm \
+
+The following Scheme-Script prints factorial of its argument:
+
+ #! /usr/local/bin/scm \ %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
+ - !#
+ ; -*-scheme-*-
+ (define (go-script)
+ (cond ((not *script*))
+ ((and (= 1 (- (length *argv*) *optind*))
+ (string->number (list-ref *argv* *optind*)))
+ => (lambda (n) (print (fact n))))
+ (else
+ (print *argv*)
+ (display "\
+ Usage: fact n
+ Returns the factorial of N.
+
+ http://swissnet.ai.mit.edu/~jaffer/SLIB.html
+ "
+ (current-error-port))
+ (exit #f))))
+
+ (define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n)))))
+ (go-script)
+
+ ./fact 32
+ =>
+ 263130836933693530167218012160000000
+
+If the wrong number of arguments is given, `fact' prints its ARGV with
+usage information.
+
+ ./fact 3 2
+ -|
+ ("./fact" "3" "2")
+ Usage: fact n
+ Returns the factorial of N.
+
+ http://swissnet.ai.mit.edu/~jaffer/SLIB.html
+
+
+File: scm.info, Node: MS-DOS Compatible Scripts, Next: Unix Shell Scripts, Prev: Unix Scheme Scripts, Up: Scripting
+
+MS-DOS Compatible Scripts
+-------------------------
+
+It turns out that we can create scheme-scripts which run both under unix
+and MS-DOS. To implement this, I have written the MS-DOS programs:
+`#!.bat' and `!#.exe'.
+
+With these two programs installed in a `PATH' directory, we have the
+following syntax for <PROGRAM>.BAT files.
+
+ - file: #! interpreter \ %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
+ The first two characters of the Scheme-Script are `#!'. The
+ INTERPRETER can be either a unix style program path (using `/'
+ between filename components) or a DOS program name or path. The
+ rest of the first line of the Scheme-Script should be literally
+ `\ %0 %1 %2 %3 %4 %5 %6 %7 %8 %9', as shown.
+
+ If INTERPRETER has `/' in it, INTERPRETER is converted to a DOS
+ style filename (`/' => `\').
+
+ In looking for an executable named INTERPRETER, `#!' first checks
+ this (converted) filename; if INTERPRETER doesn't exist, it then
+ tries to find a program named like the string starting after the
+ last `\' (or `/') in INTERPRETER. When searching for executables,
+ `#!' tries all directories named by environment variable `PATH'.
+
+ Once the INTERPRETER executable path is found, arguments are
+ processed in the manner of scheme-shell, with the all the text
+ after the `\' taken as part of the meta-argument. More precisely,
+ `#!' calls INTERPRETER with any options on the second line of the
+ Scheme-Script up to `!#', the name of the Scheme-Script file, and
+ then any of at most 8 arguments given on the command line invoking
+ this Scheme-Script.
+
+The previous example Scheme-Script works in both MS-DOS and unix
+systems.
+
+
+File: scm.info, Node: Unix Shell Scripts, Prev: MS-DOS Compatible Scripts, Up: Scripting
+
+Unix Shell Scripts
+------------------
+
+Scheme-scripts suffer from two drawbacks:
+ * Some Unixes limit the length of the `#!' interpreter line to the
+ size of an object file header, which can be as small as 32 bytes.
+
+ * A full, explicit pathname must be specified, perhaps requiring
+ more than 32 bytes and making scripts vulnerable to breakage when
+ programs are moved.
+
+The following approach solves these problems at the expense of slower
+startup. Make `#! /bin/sh' the first line and prepend every subsequent
+line to be executed by the shell with `:;'. The last line to be
+executed by the shell should contain an "exec" command; `exec'
+tail-calls its argument.
+
+`/bin/sh' is thus invoked with the name of the script file, which it
+executes as a *sh script. Usually the second line starts `:;exec scm
+-f$0', which executes scm, which in turn loads the script file. When
+SCM loads the script file, it ignores the first and second lines, and
+evaluates the rest of the file as Scheme source code.
+
+The second line of the script file does not have the length restriction
+mentioned above. Also, `/bin/sh' searches the directories listed in
+the `PATH' environment variable for `scm', eliminating the need to use
+absolute locations in order to invoke a program.
+
+The following example additionally sets *SCRIPT* to the script
+argument, making it compatible with the scheme code of the previous
+example.
+
+ #! /bin/sh
+ :;exec scm -e"(set! *script* \"$0\")" -l$0 $*
+
+ (define (go-script)
+ (cond ((not *script*))
+ ((and (= 1 (- (length *argv*) *optind*))
+ (string->number (list-ref *argv* *optind*)))
+ => (lambda (n) (print (fact n))))
+ (else
+ (print *argv*)
+ (display "\
+ Usage: fact n
+ Returns the factorial of N.
+
+ http://swissnet.ai.mit.edu/~jaffer/SLIB.html
+ "
+ (current-error-port))
+ (exit #f))))
+
+ (define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n)))))
+
+ (go-script)
+
+ ./fact 6
+ => 720
+
+
+File: scm.info, Node: The Language, Next: Packages, Prev: Operational Features, Up: Top
+
+The Language
+************
+
+* Menu:
+
+* Standards Compliance:: Links to sections in [R5RS] and [SLIB]
+* Miscellaneous Procedures::
+* Time:: Both real time and processor time
+* Interrupts:: and exceptions
+* Process Synchronization:: Because interrupts are preemptive
+* Files and Ports::
+* Line Numbers::
+* Soft Ports:: Emulate I/O devices
+* Syntax Extensions::
+* Low Level Syntactic Hooks::
+* Syntactic Hooks for Hygienic Macros::
+
+
+File: scm.info, Node: Standards Compliance, Next: Miscellaneous Procedures, Prev: The Language, Up: The Language
+
+Standards Compliance
+====================
+
+Scm conforms to the `IEEE Standard 1178-1990. IEEE Standard for the
+Scheme Programming Language.' (*note Bibliography::), and `Revised(5)
+Report on the Algorithmic Language Scheme'. *Note Top: (r5rs)Top. All
+the required features of these specifications are supported. Many of
+the optional features are supported as well.
+
+Optionals of [R5RS] Supported by SCM
+------------------------------------
+
+`-' and `/' of more than 2 arguments
+`exp'
+`log'
+`sin'
+`cos'
+`tan'
+`asin'
+`acos'
+`atan'
+`sqrt'
+`expt'
+`make-rectangular'
+`make-polar'
+`real-part'
+`imag-part'
+`magnitude'
+`angle'
+`exact->inexact'
+`inexact->exact'
+ *Note Numerical operations: (r5rs)Numerical operations.
+
+`with-input-from-file'
+`with-output-to-file'
+ *Note Ports: (r5rs)Ports.
+
+`load'
+`transcript-on'
+`transcript-off'
+ *Note System interface: (r5rs)System interface.
+
+Optionals of [R5RS] not Supported by SCM
+----------------------------------------
+
+`numerator'
+`denominator'
+`rationalize'
+ *Note Numerical operations: (r5rs)Numerical operations.
+
+[SLIB] Features of SCM and SCMLIT
+---------------------------------
+
+`delay'
+`full-continuation'
+`ieee-p1178'
+`object-hash'
+`rev4-report'
+`source'
+ See SLIB file `Template.scm'.
+
+`current-time'
+ *Note Time: (slib)Time.
+
+`defmacro'
+ *Note Defmacro: (slib)Defmacro.
+
+`getenv'
+`system'
+ *Note System Interface: (slib)System Interface.
+
+`hash'
+ *Note Hashing: (slib)Hashing.
+
+`logical'
+ *Note Bit-Twiddling: (slib)Bit-Twiddling.
+
+`multiarg-apply'
+ *Note Multi-argument Apply: (slib)Multi-argument Apply.
+
+`multiarg/and-'
+ *Note Multi-argument / and -: (slib)Multi-argument / and -.
+
+`rev4-optional-procedures'
+ *Note Rev4 Optional Procedures: (slib)Rev4 Optional Procedures.
+
+`string-port'
+ *Note String Ports: (slib)String Ports.
+
+`tmpnam'
+ *Note Input/Output: (slib)Input/Output.
+
+`transcript'
+ *Note Transcripts: (slib)Transcripts.
+
+`vicinity'
+ *Note Vicinity: (slib)Vicinity.
+
+`with-file'
+ *Note With-File: (slib)With-File.
+
+[SLIB] Features of SCM
+----------------------
+
+`array'
+ *Note Arrays: (slib)Arrays.
+
+`array-for-each'
+ *Note Array Mapping: (slib)Array Mapping.
+
+`bignum'
+`complex'
+`inexact'
+`rational'
+`real'
+ *Note Require: (slib)Require.
+
+
+File: scm.info, Node: Miscellaneous Procedures, Next: Time, Prev: Standards Compliance, Up: The Language
+
+Miscellaneous Procedures
+========================
+
+ - Function: try-load filename
+ If the string 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 `#t'.
+ If not, try-load returns `#f'. The try-load procedure does not
+ affect the values returned by `current-input-port' and
+ `current-output-port'.
+
+ - Variable: *load-pathname*
+ Is set to the pathname given as argument to `load', `try-load',
+ and `dyn:link' (*note Compiling And Linking: (hobbit)Compiling And
+ Linking.). `*load-pathname*' is used to compute the value of
+ *Note program-vicinity: (slib)Vicinity.
+
+ - Function: line-number
+ Returns the current line number of the file currently being loaded.
+
+ - Function: port-filename port
+ Returns the filename PORT was opened with. If PORT is not open to
+ a file the result is unspecified.
+
+ - Function: port-line port
+ - Function: port-column port
+ If PORT is a tracked port, return the current line (column) number,
+ otherwise return `#f'. Line and column numbers begin with 1. The
+ column number applies to the next character to be read; if that
+ character is a newline, then the column number will be one more
+ than the length of the line.
+
+ - Function: eval obj
+ Alias for *Note eval: (slib)System.
+
+ - Function: eval-string str
+ Returns the result of reading an expression from STR and
+ evaluating it. `eval-string' does not change `*load-pathname*' or
+ `line-number'.
+
+ - Function: load-string str
+ Reads and evaluates all the expressions from STR. As with `load',
+ the value returned is unspecified. `load-string' does not change
+ `*load-pathname*' or `line-number'.
+
+ - Function: vector-set-length! object length
+ Change the length of string, vector, bit-vector, or uniform-array
+ OBJECT to LENGTH. If this shortens OBJECT then the remaining
+ contents are lost. If it enlarges 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.
+
+ - Function: copy-tree obj
+ - Function: @copy-tree obj
+ *Note copy-tree: (slib)Tree Operations. This extends the SLIB
+ version by also copying vectors. Use `@copy-tree' if you depend
+ on this feature; `copy-tree' could get redefined.
+
+ - Function: 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.
+
+ - Function: terms
+ This command displays the GNU General Public License.
+
+ - Function: list-file filename
+ Displays the text contents of FILENAME.
+
+ - Procedure: print arg1 ...
+ `Print' writes all its arguments, separated by spaces. `Print'
+ outputs a `newline' at the end and returns the value of the last
+ argument.
+
+
+File: scm.info, Node: Time, Next: Interrupts, Prev: Miscellaneous Procedures, Up: The Language
+
+Time
+====
+
+ - Constant: internal-time-units-per-second
+ Is the integer number of internal time units in a second.
+
+ - Function: get-internal-run-time
+ Returns the integer run time in internal time units from an
+ unspecified starting time. The difference of two calls to
+ `get-internal-run-time' divided by
+ `internal-time-units-per-second' will give elapsed run time in
+ seconds.
+
+ - Function: get-internal-real-time
+ Returns the integer time in internal time units from an unspecified
+ starting time. The difference of two calls to
+ `get-internal-real-time' divided by
+ `interal-time-units-per-second' will give elapsed real time in
+ seconds.
+
+ - Function: current-time
+ Returns the time since 00:00:00 GMT, January 1, 1970, measured in
+ seconds. *Note current-time: (slib)Time. `current-time' is used
+ in *Note Time: (slib)Time.
+
+
+File: scm.info, Node: Interrupts, Next: Process Synchronization, Prev: Time, Up: The Language
+
+Interrupts
+==========
+
+ - Function: 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 N is 0, any ticks request is canceled. Otherwise a
+ `ticks-interrupt' will be signaled N from the current time.
+ `ticks' is supported if SCM is compiled with the `ticks' flag
+ defined.
+
+ - Callback procedure: ticks-interrupt ...
+ Establishes a response for tick interrupts. Another tick
+ interrupt will not occur unless `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.
+
+ - Function: alarm secs
+ Returns the number of seconds remaining till the next alarm
+ interrupt. If SECS is 0, any alarm request is canceled.
+ Otherwise an `alarm-interrupt' will be signaled SECS from the
+ current time. ALARM is not supported on all systems.
+
+ - Function: milli-alarm millisecs interval
+ - Function: virtual-alarm millisecs interval
+ - Function: profile-alarm millisecs interval
+ `milli-alarm' is similar to `alarm', except that the first
+ argument MILLISECS, and the return value are measured in
+ milliseconds rather than seconds. If the optional argument
+ INTERVAL is supplied then alarm interrupts will be scheduled every
+ INTERVAL milliseconds until turned off by a call to `milli-alarm'
+ or `alarm'.
+
+ `virtual-alarm' and `profile-alarm' are similar. `virtual-alarm'
+ decrements process execution time rather than real time, and
+ causes `SIGVTALRM' to be signaled. `profile-alarm' decrements
+ both process execution time and system execution time on behalf
+ of the process, and causes `SIGPROF' to be signaled.
+
+ `milli-alarm', `virtual-alarm', and `profile-alarm' are supported
+ only on systems providing the `setitimer' system call.
+
+ - Callback procedure: user-interrupt ...
+ - Callback procedure: alarm-interrupt ...
+ - Callback procedure: virtual-alarm-interrupt ...
+ - Callback procedure: profile-alarm-interrupt ...
+ Establishes a response for `SIGINT' (control-C interrupt) and
+ `SIGALRM', `SIGVTALRM', and `SIGPROF' interrupts. 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 after it returns.
+
+ Interrupt handlers are disabled during execution `system' and `ed'
+ procedures.
+
+ To unestablish a response for an interrupt set the handler symbol
+ to `#f'. For instance, `(set! user-interrupt #f)'.
+
+ - Callback procedure: out-of-storage ...
+ - Callback procedure: could-not-open ...
+ - Callback procedure: end-of-program ...
+ - Callback procedure: hang-up ...
+ - Callback procedure: arithmetic-error ...
+ 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
+ HANG-UP then END-OF-PROGRAM (if defined) will be called.
+
+ To unestablish a response for an error set the handler symbol to
+ `#f'. For instance, `(set! could-not-open #f)'.
+
+ - Callback procedure: gc-hook ...
+ Allows a Scheme procedure to be run shortly after each garbage
+ collection. This procedure will not be run recursively. If it
+ runs long enough to cause a garbage collection before returning a
+ warning will be printed.
+
+ - Function: add-finalizer object finalizer
+ OBJECT may be any garbage collected object, that is, any object
+ other than an immediate integer, character, or special token such
+ as `#f' or `#t', *Note Immediates::. FINALIZER is a thunk, or
+ procedure taking no arguments.
+
+ FINALIZER will be invoked asynchronously exactly once some time
+ after OBJECT becomes eligible for garbage collection. A reference
+ to OBJECT in the environment of FINALIZER will not prevent
+ finalization, but will delay the reclamation of OBJECT at least
+ until the next garbage collection. A reference to OBJECT in some
+ other object's finalizer will necessarily prevent finalization
+ until both objects are eligible for garbage collection.
+
+ Finalizers are not run in any predictable order. All finalizers
+ will be run by the time the program ends.
+
+ This facility was based on the paper by Simon Peyton Jones, et al,
+ "Stretching the storage manager: weak pointers and stable names in
+ Haskell", Proc. 11th International Workshop on the Implementation
+ of Functional Languages, The Netherlands, September 7-10 1999,
+ Springer-Verlag LNCS.
+
+
+
+File: scm.info, Node: Process Synchronization, Next: Files and Ports, Prev: Interrupts, Up: The Language
+
+Process Synchronization
+=======================
+
+An "exchanger" is a procedure of one argument regulating mutually
+exclusive access to a resource. When a exchanger is called, its current
+content is returned, while being replaced by its argument in an atomic
+operation.
+
+ - Function: make-exchanger obj
+ Returns a new exchanger with the argument OBJ as its initial
+ content.
+
+ (define queue (make-exchanger (list a)))
+
+ A queue implemented as an exchanger holding a list can be
+ protected from reentrant execution thus:
+
+ (define (pop queue)
+ (let ((lst #f))
+ (dynamic-wind
+ (lambda () (set! lst (queue #f)))
+ (lambda () (and lst (not (null? lst))
+ (let ((ret (car lst)))
+ (set! lst (cdr lst))
+ ret)))
+ (lambda () (and lst (queue lst))))))
+
+ (pop queue) => a
+
+ (pop queue) => #f
+
+ - Function: make-arbiter name
+ Returns an object of type arbiter and name NAME. Its state is
+ initially unlocked.
+
+ - Function: try-arbiter arbiter
+ Returns `#t' and locks ARBITER if ARBITER was unlocked.
+ Otherwise, returns `#f'.
+
+ - Function: release-arbiter arbiter
+ Returns `#t' and unlocks ARBITER if ARBITER was locked.
+ Otherwise, returns `#f'.
+
+
+File: scm.info, Node: Files and Ports, Next: Line Numbers, Prev: Process Synchronization, Up: The Language
+
+Files and Ports
+===============
+
+These procedures generalize and extend the standard capabilities in
+*Note Ports: (r5rs)Ports.
+
+ - Function: open-file string modes
+ - Function: try-open-file string modes
+ Returns a port capable of receiving or delivering characters as
+ specified by the MODES string. If a file cannot be opened `#f' is
+ returned.
+
+ Internal functions opening files "callback" to the SCM function
+ `open-file'. You can extend `open-file' by redefining it.
+ `try-open-file' is the primitive procedure; Do not redefine
+ `try-open-file'!
+
+ - Constant: open_read
+ - Constant: open_write
+ - Constant: open_both
+ Contain modes strings specifying that a file is to be opened for
+ reading, writing, and both reading and writing respectively.
+
+ 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.
+
+ - Function: _ionbf modestr
+ Returns a version of MODESTR which when `open-file' is called with
+ it as the second argument will return an unbuffered port. An
+ input-port must be unbuffered in order for `char-ready?' and
+ `wait-for-input' to work correctly on it. The initial value of
+ `(current-input-port)' is unbuffered if the platform supports it.
+
+ - Function: _tracked modestr
+ Returns a version of MODESTR which when `open-file' is called with
+ it as the second argument will return a tracked port. A tracked
+ port maintains current line and column numbers, which may be
+ queried with `port-line' and `port-column'.
+
+ - Function: _exclusive modestr
+ Returns a version of MODESTR which when `open-file' is called with
+ it as the second argument will return a port only if the named file
+ does not already exist. This functionality is provided by calling
+ `try-create-file' *Note I/O-Extensions::, which is not available
+ for all platforms.
+
+ - Function: port-closed? port
+ Returns #t if PORT is closed.
+
+ - Function: port-type obj
+ If OBJ is not a port returns false, otherwise returns a symbol
+ describing the port type, for example string or pipe.
+
+ - Function: close-port port
+ Closes PORT. The same as close-input-port and close-output-port.
+
+ - Function: current-error-port
+ Returns the current port to which diagnostic output is directed.
+
+ - Function: with-error-to-file string thunk
+ 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 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 THUNK.
+
+ - Function: with-input-from-port port thunk
+ - Function: with-output-to-port port thunk
+ - Function: 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.
+
+ - Function: call-with-outputs thunk proc
+ Calls the THUNK procedure while the current-output-port and
+ current-error-port are directed to string-ports. If THUNK
+ returns, the PROC procedure is called with the output-string, the
+ error-string, and the value returned by THUNK. If THUNK does not
+ return a value (perhaps because of error), PROC is called with
+ just the output-string and the error-string as arguments.
+
+ - procedure: char-ready?
+ - procedure: char-ready? port
+ Returns `#t' if a character is ready on the input PORT and returns
+ `#f' otherwise. If `char-ready?' returns `#t' then the next
+ `read-char' operation on the given PORT is guaranteed not to hang.
+ If the PORT is at end of file then `char-ready?' returns `#t'.
+ PORT may be omitted, in which case it defaults to the value
+ returned by `current-input-port'.
+
+ _Rationale:_ `Char-ready?' exists to make it possible for a
+ program to 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 `char-ready?' cannot be rubbed out. If
+ `char-ready?' were to return `#f' at end of file, a port at end of
+ file would be indistinguishable from an interactive port that has
+ no ready characters.
+
+ - procedure: wait-for-input x
+ - procedure: wait-for-input x port1 ...
+ Returns a list those ports PORT1 ... which are `char-ready?'. If
+ none of PORT1 ... become `char-ready?' within the time interval of
+ X seconds, then #f is returned. The PORT1 ... arguments may be
+ omitted, in which case they default to the list of the value
+ returned by `current-input-port'.
+
+ - Function: isatty? port
+ Returns `#t' if PORT is input or output to a serial non-file
+ device.
+
+ - Function: freshline port
+ Outputs a newline to optional argument PORT unless the current
+ output column number of PORT is known to be zero, ie output will
+ start at the beginning of a new line. PORT defaults to
+ `current-output-port'. If PORT is not a tracked port `freshline'
+ is equivalent to `newline'.
+
+ - Function: open-ports
+ Returns a list of all currently open ports, excluding string ports,
+ see *Note String Ports: (slib)String Ports. This may be useful
+ after a fork *Note Posix Extensions::, or for debugging. Bear in
+ mind that ports that would be closed by gc will be kept open by a
+ reference to this list.
+
+
+File: scm.info, Node: Line Numbers, Next: Soft Ports, Prev: Files and Ports, Up: The Language
+
+Line Numbers
+============
+
+Scheme code define by load may optionally contain line number
+information. Currently this information is used only for reporting
+expansion time errors, but in the future run-time error messages may
+also include line number information.
+
+ - Function: try-load pathname reader
+ This is the primitive for loading, PATHNAME is the name of a file
+ containing Scheme code, and optional argument READER is a function
+ of one argument, a port. READER should read and return Scheme
+ code as list structure. The default value is `read', which is
+ used if READER is not supplied or is false.
+
+Line number objects are disjoint from integers or other Scheme types.
+When evaluated or loaded as Scheme code, an s-expression containing a
+line-number in the car is equivalent to the cdr of the s-expression. A
+pair consisting of a line-number in the car and a vector in the cdr is
+equivalent to the vector. The meaning of s-expressions with
+line-numbers in other positions is undefined.
+
+ - Function: read-numbered port
+ Behaves like `read', except that every s-expression read will be
+ replaced with a cons of a line-number object and the sexp actually
+ read. This replacement is done only if PORT is a tracked port See
+ *Note Files and Ports::.
+
+ - Function: integer->line-number int
+ Returns a line-number object with value INT. INT should be an
+ exact non-negative integer.
+
+ - Function: line-number->integer linum
+ Returns the value of line-number object LINUM as an integer.
+
+ - Function: line-number? obj
+ Returns true if and only if OBJ is a line-number object.
+
+ - Variable: *load-reader*
+ - Variable: *slib-load-reader*
+ The value of `*load-reader*' should be a value acceptable as the
+ second argument to `try-load' (note that #f is acceptable). This
+ value will be used to read code during calls to `scm:load'. The
+ value of `*slib-load-reader*' will similarly be used during calls
+ to `slib:load' and `require'.
+
+ In order to disable all line-numbering, it is sufficient to set!
+ `*load-reader*' and `*slib-load-reader*' to #f.
+
+
+File: scm.info, Node: Soft Ports, Next: Syntax Extensions, Prev: Line Numbers, Up: The Language
+
+Soft Ports
+==========
+
+A "soft-port" is a port based on a vector of procedures capable of
+accepting or delivering characters. It allows emulation of I/O ports.
+
+ - Function: make-soft-port vector modes
+ Returns a port capable of receiving or delivering characters as
+ specified by the MODES string (*note open-file: Files and Ports.).
+ VECTOR must be a vector of length 6. Its components are as
+ follows:
+
+ 0. procedure accepting one character for output
+
+ 1. procedure accepting a string for output
+
+ 2. thunk for flushing output
+
+ 3. thunk for getting one character
+
+ 4. thunk for closing port (not by garbage collection)
+
+ 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 `#f' if there is no
+ useful operation for them to perform.
+
+ If thunk 3 returns `#f' or an `eof-object' (*note eof-object?:
+ (r5rs)Input.) it indicates that the port has reached end-of-file.
+ For example:
+
+ If it is necessary to explicitly close the port when it is garbage
+ collected, (*note add-finalizer: Interrupts.).
+
+ (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) => #<input-output-soft#\space45d10#\>
+
+
+File: scm.info, Node: Syntax Extensions, Next: Low Level Syntactic Hooks, Prev: Soft Ports, Up: The Language
+
+Syntax Extensions
+=================
+
+ - procedure: procedure-documentation proc
+ Returns the documentation string of PROC if it exists, or `#f' if
+ not.
+
+ If the body of a `lambda' (or the definition of a procedure) has
+ more than one expression, and the first expression (preceeding any
+ internal definitions) is a string, then that string is the
+ "documentation string" of that procedure.
+
+ (procedure-documentation (lambda (x) "Identity" x)) => "Identity"
+ (define (square x)
+ "Return the square of X."
+ (* x x))
+ => #<unspecified>
+ (procedure-documentation square) => "Return the square of X."
+
+ - Function: comment string1 ...
+ Appends STRING1 ... to the strings given as arguments to previous
+ calls `comment'.
+
+ - Function: comment
+ Returns the (appended) strings given as arguments to previous calls
+ `comment' and empties the current string collection.
+
+ - Read syntax: #;text-till-end-of-line
+ Behaves as `(comment "TEXT-TILL-END-OF-LINE")'.
+
+ - Read syntax: #. expression
+ Is read as the object resulting from the evaluation of EXPRESSION.
+ This substitution occurs even inside quoted structure.
+
+ In order to allow compiled code to work with `#.' it is good
+ practice to define those symbols used inside of EXPRESSION with
+ `#.(define ...)'. For example:
+
+ #.(define foo 9) => #<unspecified>
+ '(#.foo #.(+ foo foo)) => (9 18)
+
+ - Read syntax: #+ feature form
+ If feature is `provided?' (by `*features*') then FORM is read as a
+ scheme expression. If not, then FORM is treated as whitespace.
+
+ Feature is a boolean expression composed of symbols and `and',
+ `or', and `not' of boolean expressions.
+
+ For more information on `provided?' and `*features*', *Note
+ Require: (slib)Require.
+
+ - Read syntax: #- feature form
+ is equivalent to `#+(not feature) expression'.
+
+ - Read syntax: #' form
+ is equivalent to FORM (for compatibility with common-lisp).
+
+ - Read syntax: #| any thing |#
+ Is a balanced comment. Everything up to the matching `|#' is
+ ignored by the `read'. Nested `#|...|#' can occur inside ANY
+ THING.
+
+A similar read syntax "#!" (exclamation rather than vertical bar) is
+supported for Posix shell-scripts (*note Scripting::).
+
+ - Read syntax: #\token
+ If TOKEN is a sequence of two or more digits, then this syntax is
+ equivalent to `#.(integer->char (string->number token 8))'.
+
+ If TOKEN is `C-', `c-', or `^' followed by a character, then this
+ syntax is read as a control character. If TOKEN is `M-' or `m-'
+ followed by a character, then a meta character is read. `c-' and
+ `m-' prefixes may be combined.
+
+ - Special Form: defined? symbol
+ Equivalent to `#t' if SYMBOL is a syntactic keyword (such as `if')
+ or a symbol with a value in the top level environment (*note
+ Variables and regions: (r5rs)Variables and regions.). Otherwise
+ equivalent to `#f'.
+
+ - Special Form: defvar identifier initial-value
+ If IDENTIFIER is unbound in the top level environment, then
+ IDENTIFIER is `define'd to the result of evaluating the form
+ INITIAL-VALUE as if the `defvar' form were instead the form
+ `(define identifier initial-value)' . If IDENTIFIER already has a
+ value, then INITIAL-VALUE is _not_ evaluated and IDENTIFIER's
+ value is not changed. `defconst' is valid only when used at
+ top-level.
+
+ - Special Form: defconst identifier value
+ If IDENTIFIER is unbound in the top level environment, then
+ IDENTIFIER is `define'd to the result of evaluating the form VALUE
+ as if the `defconst' form were instead the form `(define
+ identifier value)' . If IDENTIFIER already has a value, then
+ VALUE is _not_ evaluated, IDENTIFIER's value is not changed, and
+ an error is signaled. `defconst' is valid only when used at
+ top-level.
+
+ - Special Form: set! (variable1 variable2 ...) <expression>
+ The identifiers VARIABLE1, VARIABLE2, ... must be bound either in
+ some region enclosing the `set!' expression or at top level.
+
+ <Expression> is evaluated, and the elements of the resulting list
+ are stored in the locations to which each corresponding VARIABLE
+ is bound. The result of the `set!' expression is unspecified.
+
+ (define x 2)
+ (define y 3)
+ (+ x y) => 5
+ (set! (x y) (list 4 5)) => _unspecified_
+ (+ x y) => 9
+
+ - Special Form: qase key clause1 clause2 ...
+ `qase' is an extension of standard Scheme `case': Each CLAUSE of a
+ `qase' statement must have as first element a list containing
+ elements which are:
+
+ * literal datums, or
+
+ * a comma followed by the name of a symbolic constant, or
+
+ * a comma followed by an at-sign (@) followed by the name of a
+ symbolic constant whose value is a list.
+
+ A `qase' statement is equivalent to a `case' statement in which
+ these symbolic constants preceded by commas have been replaced by
+ the values of the constants, and all symbolic constants preceded by
+ comma-at-signs have been replaced by the elements of the list
+ values of the constants. This use of comma, (or, equivalently,
+ `unquote') is similar to that of `quasiquote' except that the
+ unquoted expressions must be "symbolic constants".
+
+ Symbolic constants are defined using `defconst', their values are
+ substituted in the head of each `qase' clause during macro
+ expansion. `defconst' constants should be defined before use.
+ `qase' can be substituted for any correct use of `case'.
+
+ (defconst unit '1)
+ (defconst semivowels '(w y))
+ (qase (* 2 3)
+ ((2 3 5 7) 'prime)
+ ((,unit 4 6 8 9) 'composite)) ==> composite
+ (qase (car '(c d))
+ ((a) 'a)
+ ((b) 'b)) ==> _unspecified_
+ (qase (car '(c d))
+ ((a e i o u) 'vowel)
+ ((,@semivowels) 'semivowel)
+ (else 'consonant)) ==> consonant
+
+
+SCM also supports the following constructs from Common Lisp:
+`defmacro', `macroexpand', `macroexpand-1', and `gentemp'. *Note
+Defmacro: (slib)Defmacro.
+
+SCM `defmacro' is extended over that described for SLIB:
+
+ (defmacro (macro-name . arguments) body)
+
+is equivalent to
+
+ (defmacro macro-name arguments body)
+
+As in Common Lisp, an element of the formal argument list for
+`defmacro' may be a possibly nested list, in which case the
+corresponding actual argument must be a list with as many members as the
+formal argument. Rest arguments are indicated by improper lists, as in
+Scheme. It is an error if the actual argument list does not have the
+tree structure required by the formal argument list.
+
+For example:
+
+ (defmacro (let1 ((name value)) . body)
+ `((lambda (,name) ,@body) ,value))
+
+ (let1 ((x (foo))) (print x) x) == ((lambda (x) (print x) x) (foo))
+
+ (let1 not legal syntax) error--> not "does not match" ((name value))
+
+SCM supports [R5RS] `syntax-rules' macros *Note Macros: (r5rs)Macros.
+
+The pattern language is extended by the syntax `(... <obj>)', which is
+identical to `<obj>' except that ellipses in `<obj>' are treated as
+ordinary identifiers in a template, or as literals in a pattern. In
+particular, `(... ...)' quotes the ellipsis token `...' in a pattern or
+template.
+
+For example:
+ (define-syntax check-tree
+ (syntax-rules ()
+ ((_ (?pattern (... ...)) ?obj)
+ (let loop ((obj ?obj))
+ (or (null? obj)
+ (and (pair? obj)
+ (check-tree ?pattern (car obj))
+ (loop (cdr obj))))))
+ ((_ (?first . ?rest) ?obj)
+ (let ((obj ?obj))
+ (and (pair? obj)
+ (check-tree ?first (car obj))
+ (check-tree ?rest (cdr obj)))))
+ ((_ ?atom ?obj) #t)))
+
+ (check-tree ((a b) ...) '((1 2) (3 4) (5 6))) => #t
+
+ (check-tree ((a b) ...) '((1 2) (3 4) not-a-2list) => #f
+
+Note that although the ellipsis is matched as a literal token in the
+defined macro it is not included in the literals list for
+`syntax-rules'.
+
+The pattern language is also extended to support identifier macros. A
+reference to an identifier macro keyword that is not the first
+identifier in a form may expand into Scheme code, rather than raising a
+"keyword as variable" error. The pattern for expansion of such a bare
+macro keyword is a single identifier, as in other syntax rules the
+identifier is ignored.
+
+For example:
+ (define-syntax eight
+ (syntax-rules ()
+ (_ 8)))
+
+ (+ 3 eight) => 11
+ (eight) => ERROR
+ (set! eight 9) => ERROR
+
+
+File: scm.info, Node: Low Level Syntactic Hooks, Next: Syntactic Hooks for Hygienic Macros, Prev: Syntax Extensions, Up: The Language
+
+Low Level Syntactic Hooks
+=========================
+
+ - Callback procedure: read:sharp c port
+ If a <#> followed by a character (for a non-standard syntax) is
+ encountered by `read', `read' will call the value of the symbol
+ `read:sharp' with arguments the character and the port being read
+ from. The value returned by this function will be the value of
+ `read' for this expression unless the function returns
+ `#<unspecified>' in which case the expression will be treated as
+ whitespace. `#<unspecified>' is the value returned by the
+ expression `(if #f #f)'.
+
+ - Callback procedure: read:sharp-char token
+ If the sequence <#\> followed by a non-standard character name is
+ encountered by `read', `read' will call the value of the symbol
+ `read:sharp-char' with the token (a string of length at least two)
+ as argument. If the value returned is a character, then that will
+ be the value of `read' for this expression, otherwise an error
+ will be signaled.
+
+_Note:_ When adding new <#> syntaxes, have your code save the previous
+value of `read:sharp' or `read:sharp-char' when defining it. Call this
+saved value if an invocation's syntax is not recognized. This will
+allow `#+', `#-', `#!', and *Note Uniform Array::s to still be
+supported (as they use `read:sharp').
+
+ - Function: procedure->syntax proc
+ Returns a "macro" which, when a symbol defined to this value
+ appears as the first symbol in an expression, returns the result
+ of applying PROC to the expression and the environment.
+
+ - Function: procedure->macro proc
+ - Function: procedure->memoizing-macro proc
+ - Function: procedure->identifier-macro
+ Returns a "macro" which, when a symbol defined to this value
+ appears as the first symbol in an expression, evaluates the result
+ of applying PROC to the expression and the environment. The value
+ returned from PROC which has been passed to
+ `PROCEDURE->MEMOIZING-MACRO' replaces the form passed to PROC.
+ For example:
+
+ (defsyntax trace
+ (procedure->macro
+ (lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x))))))
+
+ (trace foo) == (set! foo (tracef foo 'foo)).
+
+ `PROCEDURE->IDENTIFIER-MACRO' is similar to
+ `PROCEDURE->MEMOIZING-MACRO' except that PROC is also called in
+ case the symbol bound to the macro appears in an expression but
+ _not_ as the first symbol, that is, when it looks like a variable
+ reference. In that case, the form passed to PROC is a single
+ identifier.
+
+
+ - Special Form: defsyntax name expr
+ Defines NAME as a macro keyword bound to the result of evaluating
+ EXPR, which should be a macro. Using `define' for this purpose
+ may not result in NAME being interpreted as a macro keyword.
+
+An "environment" is a list of frames representing lexical bindings.
+Only the names and scope of the bindings are included in environments
+passed to macro expanders - run-time values are not included.
+
+There are several types of environment frames:
+
+`((lambda (variable1 ...) ...) value1 ...)'
+`(let ((variable1 value1) (variable2 value2) ...) ...)'
+`(letrec ((variable1 value1) ...) ...)'
+ result in a single enviroment frame:
+
+ (variable1 variable2 ...)
+
+`(let ((variable1 value1)) ...)'
+`(let* ((variable1 value1) ...) ...)'
+ result in an environment frame for each variable:
+
+ variable1 variable2 ...
+
+`(let-syntax ((key1 macro1) (key2 macro2)) ...)'
+`(letrec-syntax ((key1 value1) (key2 value2)) ...)'
+ Lexically bound macros result in environment frames consisting of
+ a marker and an alist of keywords and macro objects:
+
+ (<env-syntax-marker> (key1 . value1) (key2 . value2))
+ Currently <env-syntax-marker> is the integer 6.
+
+`line numbers'
+ Line numbers (*note Line Numbers::) may be included in the
+ environment as frame entries to indicate the line number on which
+ a function is defined. They are ignored for variable lookup.
+
+ #<line 8>
+
+`miscellaneous'
+ Debugging information is stored in environments in a plist format:
+ Any exact integer stored as an environment frame may be followed
+ by any value. The two frame entries are ignored when doing
+ variable lookup. Load file names, procedure names, and closure
+ documentation strings are stored in this format.
+
+ <env-filename-marker> "foo.scm" <env-procedure-name-marker> foo ...
+
+ Currently <env-filename-marker> is the integer 1 and
+ <env-procedure-name-marker> the integer 2.
+
+ - Special Form: @apply procedure argument-list
+ Returns the result of applying PROCEDURE to ARGUMENT-LIST.
+ `@apply' differs from `apply' when the identifiers bound by the
+ closure being applied are `set!'; setting affects ARGUMENT-LIST.
+
+ (define lst (list 'a 'b 'c))
+ (@apply (lambda (v1 v2 v3) (set! v1 (cons v2 v3))) lst)
+ lst => ((b . c) b c)
+
+ Thus a mutable environment can be treated as both a list and local
+ bindings.
+
+
+File: scm.info, Node: Syntactic Hooks for Hygienic Macros, Prev: Low Level Syntactic Hooks, Up: The Language
+
+Syntactic Hooks for Hygienic Macros
+===================================
+
+SCM provides a synthetic identifier type for efficient implementation of
+hygienic macros (for example, `syntax-rules' *note Macros:
+(r5rs)Macros.) A synthetic identifier may be inserted in Scheme code by
+a macro expander in any context where a symbol would normally be used.
+Collectively, symbols and synthetic identifiers are _identifiers_.
+
+ - Function: identifier? obj
+ Returns `#t' if OBJ is a symbol or a synthetic identifier, and
+ `#f' otherwise.
+
+If it is necessary to distinguish between symbols and synthetic
+identifiers, use the predicate `symbol?'.
+
+A synthetic identifier includes two data: a parent, which is an
+identifier, and an environment, which is either `#f' or a lexical
+environment which has been passed to a "macro expander" (a procedure
+passed as an argument to `procedure->macro',
+`procedure->memoizing-macro', or `procedure->syntax').
+
+ - Function: renamed-identifier parent env
+ Returns a synthetic identifier. PARENT must be an identifier, and
+ ENV must either be `#f' or a lexical environment passed to a macro
+ expander. `renamed-identifier' returns a distinct object for each
+ call, even if passed identical arguments.
+
+There is no direct way to access all of the data internal to a synthetic
+identifier, those data are used during variable lookup. If a synthetic
+identifier is inserted as quoted data then during macro expansion it
+will be repeatedly replaced by its parent, until a symbol is obtained.
+
+ - Function: identifier->symbol id
+ Returns the symbol obtained by recursively extracting the parent of
+ ID, which must be an identifier.
+
+Use of synthetic identifiers
+----------------------------
+
+`renamed-identifier' may be used as a replacement for `gentemp':
+ (define gentemp
+ (let ((name (string->symbol "An unlikely variable")))
+ (lambda ()
+ (renamed-identifier name #f))))
+
+If an identifier returned by this version of `gentemp' is inserted in a
+binding position as the name of a variable then it is guaranteed that
+no other identifier (except one produced by passing the first to
+`renamed-identifier') may denote that variable. If an identifier
+returned by `gentemp' is inserted free, then it will denote the
+top-level value bound to its parent, the symbol named "An unlikely
+variable". This behavior, of course, is meant to be put to good use:
+
+ (define top-level-foo
+ (procedure->memoizing-macro
+ (lambda (exp env)
+ (renamed-identifier 'foo #f))))
+
+Defines a macro which may always be used to refer to the top-level
+binding of `foo'.
+
+ (define foo 'top-level)
+ (let ((foo 'local))
+ (top-level-foo)) => top-level
+
+In other words, we can avoid capturing `foo'.
+
+If a lexical environment is passed as the second argument to
+`renamed-identifier' then if the identifier is inserted free its parent
+will be looked up in that environment, rather than in the top-level
+environment. The use of such an identifier _must_ be restricted to the
+lexical scope of its environment.
+
+There is another restriction imposed for implementation convenience:
+Macros passing their lexical environments to `renamed-identifier' may
+be lexically bound only by the special forms `let-syntax' or
+`letrec-syntax'. No error is signaled if this restriction is not met,
+but synthetic identifier lookup will not work properly.
+
+In order to maintain referential transparency it is necessary to
+determine whether two identifiers have the same denotation. With
+synthetic identifiers it is not necessary that two identifiers be `eq?'
+in order to denote the same binding.
+
+ - Function: identifier-equal? id1 id2 env
+ Returns `#t' if identifiers ID1 and ID2 denote the same binding in
+ lexical environment ENV, and `#f' otherwise. ENV must either be a
+ lexical environment passed to a macro transformer during macro
+ expansion or the empty list.
+
+ For example,
+ (define top-level-foo?
+ (procedure->memoizing-macro
+ (let ((foo-name (renamed-identifier 'foo #f)))
+ (lambda (exp env)
+ (identifier-equal? (cadr exp) foo-name env)))))
+
+ (top-level-foo? foo) => #t
+
+ (let ((foo 'local))
+ (top-level-foo? foo)) => #f
+
+ - Function: @macroexpand1 expr env
+ If the `car' of EXPR denotes a macro in ENV, then if that macro is
+ a primitive, EXPR will be returned, if the macro was defined in
+ Scheme, then a macro expansion will be returned. If the `car' of
+ EXPR does not denote a macro, the `#f' is returned.
+
+ - Function: extended-environment names values env
+ Returns a new environment object, equivalent to ENV, which must
+ either be an environment object or null, extended by one frame.
+ NAMES must be an identifier, or an improper list of identifiers,
+ usable as a formals list in a `lambda' expression. VALUES must be
+ a list of objects long enough to provide a binding for each of the
+ identifiers in NAMES. If NAMES is an identifier or an improper
+ list then VALS may be, respectively, any object or an improper
+ list of objects.
+
+ - Special Form: syntax-quote obj
+ Synthetic identifiers are converted to their parent symbols by
+ `quote' and `quasiquote' so that literal data in macro definitions
+ will be properly transcribed. `syntax-quote' behaves like
+ `quote', but preserves synthetic identifier intact.
+
+ - Special Form: the-macro mac
+ `the-macro' is the simplest of all possible macro transformers:
+ MAC may be a syntactic keyword (macro name) or an expression
+ evaluating to a macro, otherwise an error is signaled. MAC is
+ evaluated and returned once only, after which the same memoizied
+ value is returned.
+
+ `the-macro' may be used to protect local copies of macros against
+ redefinition, for example:
+ (@let-syntax ((let (the-macro let)))
+ ;; code that will continue to work even if LET is redefined.
+ ...)
+
+ - Special Form: renaming-transformer proc
+ A low-level "explicit renaming" macro facility very similar to that
+ proposed by W. Clinger [Exrename] is supported. Syntax may be
+ defined in `define-syntax', `let-syntax', and `letrec-syntax'
+ using `renaming-transformer' instead of `syntax-rules'. PROC
+ should evaluate to a procedure accepting three arguments: EXPR,
+ RENAME, and COMPARE. EXPR is a representation of Scheme code to
+ be expanded, as list structure. RENAME is a procedure accepting
+ an identifier and returning an identifier renamed in the
+ definition environment of the new syntax. COMPARE accepts two
+ identifiers and returns true if and only if both denote the same
+ binding in the usage environment of the new syntax.
+
+
+File: scm.info, Node: Packages, Next: The Implementation, Prev: The Language, Up: Top
+
+Packages
+********
+
+* Menu:
+
+* Dynamic Linking::
+* Dump:: Create Fast-Booting Executables
+* Numeric:: Numeric Language Extensions
+* Arrays:: As in APL
+* Records:: Define new aggregate data types
+* I/O-Extensions:: i/o-extensions
+* Posix Extensions:: posix
+* Unix Extensions:: non-posix unix
+* Regular Expression Pattern Matching:: regex
+* Line Editing:: edit-line
+* Curses:: Screen Control
+* Sockets:: Cruise the Net
+
+* Menu:
+
+* Xlib: (Xlibscm). X Window Graphics.
+* Hobbit: (hobbit). Scheme-to-C Compiler.
+
+
+File: scm.info, Node: Dynamic Linking, Next: Dump, Prev: Packages, Up: Packages
+
+Dynamic Linking
+===============
+
+If SCM has been compiled with `dynl.c' then the additional properties
+of load and ([SLIB]) require specified here are supported. The
+`require' form is preferred.
+
+ - Function: require feature
+ If the symbol FEATURE has not already been given as an argument to
+ `require', then the object and library files associated with
+ FEATURE will be dynamically-linked, and an unspecified value
+ returned. If FEATURE is not found in `*catalog*', then an error
+ is signaled.
+
+ - Function: usr:lib lib
+ Returns the pathname of the C library named LIB. For example:
+ `(usr:lib "m")' returns `"/usr/lib/libm.a"', the path of the C
+ math library.
+
+ - Function: x:lib lib
+ Returns the pathname of the X library named LIB. For example:
+ `(x:lib "X11")' returns `"/usr/X11/lib/libX11.sa"', the path of
+ the X11 library.
+
+ - Function: load filename lib1 ...
+ In addition to the [R5RS] requirement of loading Scheme
+ expressions if FILENAME is a Scheme source file, `load' will also
+ dynamically load/link object files (produced by `compile-file', for
+ instance). The object-suffix need not be given to load. For
+ example,
+
+ (load (in-vicinity (implementation-vicinity) "sc2"))
+ or (load (in-vicinity (implementation-vicinity) "sc2.o"))
+ or (require 'rev2-procedures)
+ or (require 'rev3-procedures)
+
+ will load/link `sc2.o' if it exists.
+
+ The LIB1 ... pathnames specify additional libraries which may be
+ needed for object files not produced by the Hobbit compiler. For
+ instance, crs is linked on Linux by
+
+ (load (in-vicinity (implementation-vicinity) "crs.o")
+ (usr:lib "ncurses") (usr:lib "c"))
+ or (require 'curses)
+
+ Turtlegr graphics library is linked by:
+
+ (load (in-vicinity (implementation-vicinity) "turtlegr")
+ (usr:lib "X11") (usr:lib "c") (usr:lib "m"))
+ or (require 'turtle-graphics)
+
+ And the string regular expression (*note Regular Expression
+ Pattern Matching::) package is linked by:
+
+ (load (in-vicinity (implementation-vicinity) "rgx") (usr:lib "c"))
+ or
+ (require 'regex)
+
+The following functions comprise the low-level Scheme interface to
+dynamic linking. See the file `Link.scm' in the SCM distribution for
+an example of their use.
+
+ - Function: dyn:link filename
+ FILENAME should be a string naming an "object" or "archive" file,
+ the result of C-compiling. The `dyn:link' procedure links and
+ loads FILENAME into the current SCM session. If successfull,
+ `dyn:link' returns a "link-token" suitable for passing as the
+ second argument to `dyn:call'. If not successful, `#f' is
+ returned.
+
+ - Function: dyn:call name link-token
+ LINK-TOKEN should be the value returned by a call to `dyn:link'.
+ NAME should be the name of C function of no arguments defined in
+ the file named FILENAME which was succesfully `dyn:link'ed in the
+ current SCM session. The `dyn:call' procedure calls the C
+ function corresponding to NAME. If successful, `dyn:call' returns
+ `#t'; If not successful, `#f' is returned.
+
+ `dyn:call' is used to call the "init_..." function after loading
+ SCM object files. The init_... function then makes the
+ identifiers defined in the file accessible as Scheme procedures.
+
+ - Function: dyn:main-call name link-token arg1 ...
+ LINK-TOKEN should be the value returned by a call to `dyn:link'.
+ NAME should be the name of C function of 2 arguments, `(int argc,
+ char **argv)', defined in the file named FILENAME which was
+ succesfully `dyn:link'ed in the current SCM session. The
+ `dyn:main-call' procedure calls the C function corresponding to
+ NAME with `argv' style arguments, such as are given to C `main'
+ functions. If successful, `dyn:main-call' returns the integer
+ returned from the call to NAME.
+
+ `dyn:main-call' can be used to call a `main' procedure from SCM.
+ For example, I link in and `dyn:main-call' a large C program, the
+ low level routines of which callback (*note Callbacks::) into SCM
+ (which emulates PCI hardware).
+
+ - Function: dyn:unlink link-token
+ LINK-TOKEN should be the value returned by a call to `dyn:link'.
+ The `dyn:unlink' procedure removes the previously loaded file from
+ the current SCM session. If successful, `dyn:unlink' returns
+ `#t'; If not successful, `#f' is returned.
+
+
+File: scm.info, Node: Dump, Next: Numeric, Prev: Dynamic Linking, Up: Packages
+
+Dump
+====
+
+"Dump", (also known as "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.
+
+There are constraints on which sessions are savable using `dump'
+
+ * Saved continuations are invalid in subsequent invocations; they
+ cause segmentation faults and other unpleasant side effects.
+
+ * Although DLD (*note Dynamic Linking::) can be used to load compiled
+ modules both before and after dumping, `SUN_DL' ELF systems can
+ load compiled modules only after dumping. This can be worked
+ around by compiling in those features you wish to `dump'.
+
+ * Ports (other than `current-input-port', `current-output-port',
+ `current-error-port'), X windows, etc. are invalid in subsequent
+ invocations.
+
+ This restriction could be removed; *Note Improvements To Make::.
+
+ * `Dump' should only be called from a loading file when the call to
+ dump is the last expression in that file.
+
+ * `Dump' can be called from the command line.
+
+ - Function: dump newpath
+ - Function: dump newpath #f
+ - Function: dump newpath #t
+ - Function: dump newpath thunk
+ * Calls `gc'.
+
+ * Creates an executable program named NEWPATH which continues
+ the state of the current SCM session when invoked. The
+ optional argument THUNK, if provided, should be a procedure
+ of no arguments; BOOT-TAIL will be set to this procedure,
+ causing it to 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 `dump' is `#t', argument processing
+ will continue from the command line passed to the dumping
+ session. If the second argument is missing or `#f' then the
+ command line arguments of the restoring invocation will be
+ processed.
+
+ * 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.
+
+ `dump' may set the values of `boot-tail', `*argv*', `restart', and
+ *INTERACTIVE*. `dump' returns an unspecified value.
+
+When a dumped executable is invoked, the variable *INTERACTIVE* (*note
+Internal State::) has the value it possessed when `dump' created it.
+Calling `dump' with a single argument sets *INTERACTIVE* to `#f', which
+is the state it has at the beginning of command line processing.
+
+The procedure `program-arguments' returns the command line arguments
+for the curent invocation. More specifically, `program-arguments' for
+the restored session are _not_ saved from the dumping session. Command
+line processing is done on the value of the identifier `*argv*'.
+
+The following example shows how to create `rscm', which is like regular
+scm, but which loads faster and has the `random' package alreadly
+provided.
+
+ 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$
+
+This task can also be accomplished using the `-o' command line option
+(*note SCM Options::).
+
+ 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$
+
+
+File: scm.info, Node: Numeric, Next: Arrays, Prev: Dump, Up: Packages
+
+Numeric
+=======
+
+ - Constant: most-positive-fixnum
+ The immediate integer closest to positive infinity. *Note
+ Configuration: (slib)Configuration.
+
+ - Constant: most-negative-fixnum
+ The immediate integer closest to negative infinity.
+
+ - Constant: $pi
+ - Constant: pi
+ The ratio of the circumference to the diameter of a circle.
+
+These procedures augment the standard capabilities in *Note Numerical
+operations: (r5rs)Numerical operations.
+
+ - Function: pi* z
+ `(* pi Z)'
+
+ - Function: pi/ z
+ `(/ pi Z)'
+
+ - Function: sinh z
+ - Function: cosh z
+ - Function: tanh z
+ Return the hyperbolic sine, cosine, and tangent of Z
+
+ - Function: asinh z
+ - Function: acosh z
+ - Function: atanh z
+ Return the inverse hyperbolic sine, cosine, and tangent of Z
+
+ - Function: $sqrt x
+ - Function: $abs x
+ - Function: $exp x
+ - Function: $log x
+ - Function: $sin x
+ - Function: $cos x
+ - Function: $tan x
+ - Function: $asin x
+ - Function: $acos x
+ - Function: $atan x
+ - Function: $sinh x
+ - Function: $cosh x
+ - Function: $tanh x
+ - Function: $asinh x
+ - Function: $acosh x
+ - Function: $atanh x
+ Real-only versions of these popular functions. The argument X
+ must be a real number. It is an error if the value which should be
+ returned by a call to these procedures is _not_ real.
+
+ - Function: $log10 x
+ Real-only base 10 logarithm.
+
+ - Function: $atan2 y x
+ Computes `(angle (make-rectangular x y))' for real numbers Y and X.
+
+ - Function: $expt x1 x2
+ Returns real number X1 raised to the real power X2. It is an
+ error if the value which should be returned by a call to `$expt'
+ is not real.
+
+
+File: scm.info, Node: Arrays, Next: Records, Prev: Numeric, Up: Packages
+
+Arrays
+======
+
+* Menu:
+
+* Conventional Arrays::
+* Array Mapping:: array-for-each
+* Uniform Array::
+* Bit Vectors::
+
+
+File: scm.info, Node: Conventional Arrays, Next: Array Mapping, Prev: Arrays, Up: Arrays
+
+Conventional Arrays
+-------------------
+
+"Arrays" read and write as a `#' followed by the "rank" (number of
+dimensions) followed by the character #\a or #\A and 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.
+ (make-array 'ho 3 3) =>
+ #2A((ho ho ho) (ho ho ho) (ho ho ho))
+
+The rank may be elided, in which case it is read as one.
+ '#A(a b c) == '#(a b c)
+
+Unshared conventional (not uniform) 0-based arrays of rank 1 (dimension)
+are equivalent to (and can't be distinguished from) vectors.
+ (make-array 'ho 3) => #(ho ho ho)
+
+When constructing an array, BOUND is either an inclusive range of
+indices expressed as a two element list, or an upper bound expressed as
+a single integer. So
+ (make-array 'foo 3 3) == (make-array 'foo '(0 2) '(0 2))
+
+ - Function: array? obj
+ Returns `#t' if the OBJ is an array, and `#f' if not.
+
+ - Function: make-array initial-value bound1 bound2 ...
+ Creates and returns an array that has as many dimensions as there
+ are BOUNDs and fills it with INITIAL-VALUE.
+
+ - Function: array-ref array index1 index2 ...
+ Returns the INDEX1, INDEX2, ...'th element of ARRAY.
+
+ - Function: array-in-bounds? array index1 index2 ...
+ Returns `#t' if its arguments would be acceptable to ARRAY-REF.
+
+ - Function: array-set! array new-value index1 index2 ...
+ Sets the INDEX1, INDEX2, ...'th element of ARRAY to NEW-VALUE.
+ The value returned by `array-set!' is unspecified.
+
+ - Function: make-shared-array array mapper bound1 bound2 ...
+ `make-shared-array' can be used to create shared subarrays of other
+ arrays. The MAPPER is a function that translates coordinates in
+ the new array into coordinates in the old array. A 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:
+ (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) => foo
+ (define freds-center
+ (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))
+ (array-ref freds-center 0 0) => foo
+
+ - Function: transpose-array array dim0 dim1 ...
+ Returns an array sharing contents with ARRAY, but with dimensions
+ arranged in a different order. There must be one DIM argument for
+ each dimension of ARRAY. DIM0, DIM1, ... 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 DIM0, DIM1, ... correspond to dimensions in the
+ array to be returned, their positions in the argument list to
+ dimensions of ARRAY. Several DIMs may have the same value, in
+ which case the returned array will have smaller rank than ARRAY.
+
+ examples:
+ (transpose-array '#2A((a b) (c d)) 1 0) => #2A((a c) (b d))
+ (transpose-array '#2A((a b) (c d)) 0 0) => #1A(a d)
+ (transpose-array '#3A(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) =>
+ #2A((a 4) (b 5) (c 6))
+
+ - Function: enclose-array array dim0 dim1 ...
+ DIM0, DIM1 ... should be nonnegative integers less than the rank
+ of ARRAY. ENCLOSE-ARRAY returns an array resembling an array of
+ shared arrays. The dimensions of each shared array are the same
+ as the DIMth 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 DIM.
+
+ An enclosed array is not a general Scheme array. Its elements may
+ not be set using `array-set!'. Two references to the same element
+ of an enclosed array will be `equal?' but will not in general be
+ `eq?'. The value returned by ARRAY-PROTOTYPE when given an
+ enclosed array is unspecified.
+
+ examples:
+ (enclose-array '#3A(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) =>
+ #<enclosed-array (#1A(a d) #1A(b e) #1A(c f)) (#1A(1 4) #1A(2 5) #1A(3 6))>
+
+ (enclose-array '#3A(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) =>
+ #<enclosed-array #2A((a 1) (d 4)) #2A((b 2) (e 5)) #2A((c 3) (f 6))>
+
+ - Function: array-shape array
+ Returns a list of inclusive bounds of integers.
+ (array-shape (make-array 'foo '(-1 3) 5)) => ((-1 3) (0 4))
+
+ - Function: array-dimensions array
+ `Array-dimensions' is similar to `array-shape' but replaces
+ elements with a `0' minimum with one greater than the maximum. So:
+ (array-dimensions (make-array 'foo '(-1 3) 5)) => ((-1 3) 5)
+
+ - Function: array-rank obj
+ Returns the number of dimensions of OBJ. If OBJ is not an array,
+ `0' is returned.
+
+ - Function: array->list array
+ Returns a list consisting of all the elements, in order, of ARRAY.
+ In the case of a rank-0 array, returns the single element.
+
+ - Function: array-copy! source destination
+ Copies every element from vector or array SOURCE to the
+ corresponding element of DESTINATION. DESTINATION must have the
+ same rank as SOURCE, and be at least as large in each dimension.
+ The order of copying is unspecified.
+
+ - Function: serial-array-copy! source destination
+ Same as `array-copy!' but guaranteed to copy in row-major order.
+
+ - Function: array-fill! array fill
+ Stores FILL in every element of ARRAY. The value returned is
+ unspecified.
+
+ - Function: array-equal? array0 array1 ...
+ Returns `#t' iff all arguments are arrays with the same shape, the
+ same type, and have corresponding elements which are either
+ `equal?' or `array-equal?'. This function differs from `equal?'
+ in that a one dimensional shared array may be ARRAY-EQUAL? but not
+ EQUAL? to a vector or uniform vector.
+
+ - Function: array-contents array
+ - Function: array-contents array strict
+ If ARRAY may be "unrolled" into a one dimensional shared array
+ without changing their order (last subscript changing fastest),
+ then `array-contents' returns that shared array, otherwise it
+ returns `#f'. All arrays made by MAKE-ARRAY and CREATE-ARRAY may
+ be unrolled, some arrays made by MAKE-SHARED-ARRAY may not be.
+
+ If the optional argument STRICT is provided, a shared array will
+ be returned only if its elements are stored internally contiguous
+ in memory.
+
+
+File: scm.info, Node: Array Mapping, Next: Uniform Array, Prev: Conventional Arrays, Up: Arrays
+
+Array Mapping
+-------------
+
+`(require 'array-for-each)'
+
+ - Function: array-map! array0 proc array1 ...
+ If ARRAY1, ... are arrays, they must have the same number of
+ dimensions as ARRAY0 and have a range for each index which
+ includes the range for the corresponding index in ARRAY0. If they
+ are scalars, that is, not arrays, vectors, or strings, then they
+ will be converted internally to arrays of the appropriate shape.
+ PROC is applied to each tuple of elements of ARRAY1 ... and the
+ result is stored as the corresponding element in ARRAY0. The
+ value returned is unspecified. The order of application is
+ unspecified.
+
+
+ - Function: serial-array-map! array0 proc array1 ...
+ Same as ARRAY-MAP!, but guaranteed to apply PROC in row-major
+ order.
+
+ - Function: array-for-each proc array0 ...
+ PROC is applied to each tuple of elements of ARRAY0 ... in
+ row-major order. The value returned is unspecified.
+
+ - Function: array-index-map! array proc
+ applies PROC to the indices of each element of ARRAY in turn,
+ storing the result in the corresponding element. The value
+ returned and the order of application are unspecified.
+
+ One can implement ARRAY-INDEXES as
+ (define (array-indexes array)
+ (let ((ra (apply make-array #f (array-shape array))))
+ (array-index-map! ra (lambda x x))
+ ra))
+ Another example:
+ (define (apl:index-generator n)
+ (let ((v (make-vector n 1)))
+ (array-index-map! v (lambda (i) i))
+ v))
+
+ - Function: scalar->array scalar array prototype
+ Returns a uniform array of the same shape as ARRAY, having only
+ one shared element, which is `eqv?' to SCALAR. If the optional
+ argument 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 `array' if that is possible, and a conventional
+ array if it is not. This function is used internally by
+ `array-map!' and friends to handle scalar arguments.
+
+
+File: scm.info, Node: Uniform Array, Next: Bit Vectors, Prev: Array Mapping, Up: Arrays
+
+Uniform Array
+-------------
+
+"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.
+
+SLIB now supports uniform arrys. The primary array creation procedure
+is `create-array', detailed in *Note Arrays: (slib)Arrays.
+
+Unshared uniform character 0-based arrays of rank 1 (dimension) are
+equivalent to (and can't be distinguished from) strings.
+ (create-array "" 3) => "$q2"
+
+Unshared uniform boolean 0-based arrays of rank 1 (dimension) are
+equivalent to (and can't be distinguished from) *Note bit-vectors: Bit
+Vectors.
+ (create-array '#at() 3) => #*000
+ ==
+ #At(#f #f #f) => #*000
+ ==
+ #1At(#f #f #f) => #*000
+
+PROTOTYPE arguments in the following procedures are interpreted
+according to the table:
+
+ prototype type display prefix
+
+ () conventional vector #a
+ +64i complex (double precision) #ac64
+ 64.0 double (double precision) #ar64
+ 32.0 float (single precision) #ar32
+ 32 unsigned integer (32-bit) #au32
+ -32 signed integer (32-bit) #as32
+ -16 signed integer (16-bit) #as16
+ #\a char (string) #a\
+ #t boolean (bit-vector) #at
+
+Other uniform vectors are written in a form similar to that of general
+arrays, except that one or more modifying characters are put between the
+#\A character and the contents list. For example, `'#As32(3 5 9)'
+returns a uniform vector of signed integers.
+
+ - Function: array? obj prototype
+ Returns `#t' if the OBJ is an array of type corresponding to
+ PROTOTYPE, and `#f' if not.
+
+ - Function: array-prototype array
+ Returns an object that would produce an array of the same type as
+ ARRAY, if used as the PROTOTYPE for `list->uniform-array'.
+
+ - Function: list->uniform-array rank prot lst
+ Returns a uniform array of the type indicated by prototype PROT
+ with elements the same as those of LST. Elements must be of the
+ appropriate type, no coercions are done.
+
+ In, for example, the case of a rank-2 array, LST must be a list of
+ lists, all of the same length. The length of LST will be the
+ first dimension of the result array, and the length of each
+ element the second dimension.
+
+ If RANK is zero, LST, which need not be a list, is the single
+ element of the returned array.
+
+ - Function: uniform-vector-fill! uve fill
+ Stores FILL in every element of UVE. The value returned is
+ unspecified.
+
+ - Function: dimensions->uniform-array dims prototype fill
+ - Function: dimensions->uniform-array dims prototype
+ Creates and returns a uniform array or vector of type
+ corresponding to PROTOTYPE with dimensions DIMS or length LENGTH.
+ If the FILL argument is supplied, the returned array is filled with
+ this value.
+
+ - Function: uniform-array-read! ura
+ - Function: uniform-array-read! ura port
+ Attempts to read all elements of URA, in lexicographic order, as
+ binary objects from PORT. If an end of file is encountered during
+ uniform-array-read! the objects up to that point only are put into
+ URA (starting at the beginning) and the remainder of the array is
+ unchanged.
+
+ `uniform-array-read!' returns the number of objects read. PORT
+ may be omitted, in which case it defaults to the value returned by
+ `(current-input-port)'.
+
+ - Function: uniform-array-write ura
+ - Function: uniform-array-write ura port
+ Writes all elements of URA as binary objects to PORT. The number
+ of of objects actually written is returned. PORT may be omitted,
+ in which case it defaults to the value returned by
+ `(current-output-port)'.
+
+ - Function: logaref array index1 index2 ...
+ If an INDEX is provided for each dimension of ARRAY returns the
+ INDEX1, INDEX2, ...'th element of ARRAY. If one more INDEX is
+ provided, then the last index specifies bit position of the
+ twos-complement representation of the array element indexed by the
+ other INDEXs returning `#t' if the bit is 1, and `#f' if 0. It is
+ an error if this element is not an exact integer.
+
+ (logaref '#(#b1101 #b0010) 0) => #b1101
+ (logaref '#(#b1101 #b0010) 0 1) => #f
+ (logaref '#2((#b1101 #b0010)) 0 0) => #b1101
+
+ - Function: logaset! array val index1 index2 ...
+ If an INDEX is provided for each dimension of ARRAY sets the
+ INDEX1, INDEX2, ...'th element of ARRAY to VAL. If one more INDEX
+ is provided, then the last index specifies bit position of the
+ twos-complement representation of an exact integer array element,
+ setting the bit to 1 if VAL is `#t' and to 0 if VAL is `#f'. In
+ this case it is an error if the array element is not an exact
+ integer or if VAL is not boolean.
+
+
+File: scm.info, Node: Bit Vectors, Prev: Uniform Array, Up: Arrays
+
+Bit Vectors
+-----------
+
+Bit vectors can be written and read as a sequence of `0's and `1's
+prefixed by `#*'.
+
+ #At(#f #f #f #t #f #t #f) => #*0001010
+
+Some of these operations will eventually be generalized to other
+uniform-arrays.
+
+ - Function: bit-count bool bv
+ Returns the number occurrences of BOOL in BV.
+
+ - Function: bit-position bool bv k
+ Returns the minimum index of an occurrence of BOOL in BV which is
+ at least K. If no BOOL occurs within the specified range `#f' is
+ returned.
+
+ - Function: bit-invert! bv
+ Modifies BV by replacing each element with its negation.
+
+ - Function: bit-set*! bv uve bool
+ If uve is a bit-vector BV and uve must be of the same length. If
+ BOOL is `#t', uve is OR'ed into BV; If BOOL is `#f', the inversion
+ of uve is AND'ed into BV.
+
+ If uve is a unsigned integer vector all the elements of uve must be
+ between 0 and the `LENGTH' of BV. The bits of BV corresponding to
+ the indexes in uve are set to BOOL.
+
+ The return value is unspecified.
+
+ - Function: bit-count* bv uve bool
+ Returns
+ (bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t).
+ BV is not modified.
+
+
+File: scm.info, Node: Records, Next: I/O-Extensions, Prev: Arrays, Up: Packages
+
+Records
+=======
+
+SCM provides user-definable datatypes with the same interface as SLIB,
+see *Note Records: (slib)Records, with the following extension.
+
+ - Function: record-printer-set! rtd printer
+ Causes records of type RTD to be printed in a user-specified
+ format. RTD must be a record type descriptor returned by
+ `make-record-type', PRINTER a procedure accepting three arguments:
+ the record to be printed, the port to print to, and a boolean
+ which is true if the record is being written on behalf of `write'
+ and false if for `display'. If PRINTER returns #f, the default
+ record printer will be called.
+
+ A PRINTER value of #f means use the default printer.
+
+ Only the default printer will be used when printing error messages.
+
+
+File: scm.info, Node: I/O-Extensions, Next: Posix Extensions, Prev: Records, Up: Packages
+
+I/O-Extensions
+==============
+
+If `'i/o-extensions' is provided (by linking in `ioext.o'), *Note Line
+I/O: (slib)Line I/O, and the following functions are defined:
+
+ - Function: 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
+ `#f' is returned. The elements of the returned vector are as
+ follows:
+
+ 0 st_dev
+ ID of device containing a directory entry for this file
+
+ 1 st_ino
+ Inode number
+
+ 2 st_mode
+ File type, attributes, and access control summary
+
+ 3 st_nlink
+ Number of links
+
+ 4 st_uid
+ User ID of file owner
+
+ 5 st_gid
+ Group ID of file group
+
+ 6 st_rdev
+ Device ID; this entry defined only for char or blk spec files
+
+ 7 st_size
+ File size (bytes)
+
+ 8 st_atime
+ Time of last access
+
+ 9 st_mtime
+ Last modification time
+
+ 10 st_ctime
+ Last file status change time
+
+ - Function: getpid
+ Returns the process ID of the current process.
+
+ - Function: file-position port
+ Returns the current position of the character in PORT which will
+ next be read or written. If PORT is not open to a file the result
+ is unspecified.
+
+ - Function: file-set-position port integer
+ Sets the current position in PORT which will next be read or
+ written. If PORT is not open to a file the action of
+ `file-set-position' is unspecified. The result of
+ `file-set-position' is unspecified.
+
+ - Function: try-create-file name modes perms
+ If the file with name NAME already exists, return `#f', otherwise
+ try to create and open the file like `try-open-file', *Note Files
+ and Ports::. If the optional integer argument PERMS is provided,
+ it is used as the permissions of the new file (modified by the
+ current umask).
+
+ - Function: reopen-file filename modes port
+ Closes port PORT and reopens it with FILENAME and MODES.
+ `reopen-file' returns `#t' if successful, `#f' if not.
+
+ - Function: duplicate-port port modes
+ Creates and returns a "duplicate" port from PORT. Duplicate
+ _unbuffered_ ports share one file position. MODES are as for
+ *Note open-file: Files and Ports.
+
+ - Function: redirect-port! from-port to-port
+ Closes TO-PORT and makes TO-PORT be a duplicate of FROM-PORT.
+ `redirect-port!' returns TO-PORT if successful, `#f' if not. If
+ unsuccessful, TO-PORT is not closed.
+
+ - Function: opendir dirname
+ Returns a "directory" object corresponding to the file system
+ directory named DIRNAME. If unsuccessful, returns `#f'.
+
+ - Function: readdir dir
+ Returns the string name of the next entry from the directory DIR.
+ If there are no more entries in the directory, `readdir' returns a
+ `#f'.
+
+ - Function: rewinddir dir
+ Reinitializes DIR so that the next call to `readdir' with DIR will
+ return the first entry in the directory again.
+
+ - Function: closedir dir
+ Closes DIR and returns `#t'. If DIR is already closed,,
+ `closedir' returns a `#f'.
+
+ - Function: directory-for-each proc directory
+ The LISTs must be lists, and PROC must be a procedure taking one
+ argument. `Directory-For-Each' applies PROC to the (string) name
+ of each file in DIRECTORY. The dynamic order in which PROC is
+ applied to the elements of the LISTs is unspecified. The value
+ returned by `directory-for-each' is unspecified.
+
+ - Function: directory-for-each proc directory pred
+ Applies PROC only to those filenames for which the procedure PRED
+ returns a non-false value.
+
+ - Function: directory-for-each proc directory match
+ Applies PROC only to those filenames for which `(filename:match??
+ MATCH)' would return a non-false value (*note Filenames:
+ (slib)Filenames.).
+
+ (require 'directory-for-each)
+ (directory-for-each print "." "[A-Z]*.scm")
+ -|
+ "Init.scm"
+ "Iedline.scm"
+ "Link.scm"
+ "Macro.scm"
+ "Transcen.scm"
+ "Init5d6.scm"
+
+ - Function: mkdir path mode
+ The `mkdir' function creates a new, empty directory whose name is
+ PATH. The integer argument MODE specifies the file permissions
+ for the new directory. *Note The Mode Bits for Access Permission:
+ (libc)The Mode Bits for Access Permission, for more information
+ about this.
+
+ `mkdir' returns if successful, `#f' if not.
+
+ - Function: rmdir path
+ The `rmdir' function deletes the directory PATH. The directory
+ must be empty before it can be removed. `rmdir' returns if
+ successful, `#f' if not.
+
+ - Function: chdir filename
+ Changes the current directory to FILENAME. If FILENAME does not
+ exist or is not a directory, `#f' is returned. Otherwise, `#t' is
+ returned.
+
+ - Function: getcwd
+ The function `getcwd' returns a string containing the absolute file
+ name representing the current working directory. If this string
+ cannot be obtained, `#f' is returned.
+
+ - Function: rename-file oldfilename newfilename
+ Renames the file specified by OLDFILENAME to NEWFILENAME. If the
+ renaming is successful, `#t' is returned. Otherwise, `#f' is
+ returned.
+
+ - Function: chmod file mode
+ The function `chmod' sets the access permission bits for the file
+ named by FILE to MODE. The FILE argument may be a string
+ containing the filename or a port open to the file.
+
+ `chmod' returns if successful, `#f' if not.
+
+ - Function: utime pathname acctime modtime
+ Sets the file times associated with the file named PATHNAME to
+ have access time ACCTIME and modification time MODTIME. `utime'
+ returns if successful, `#f' if not.
+
+ - Function: umask mode
+ The function `umask' sets the file creation mask of the current
+ process to MASK, and returns the previous value of the file
+ creation mask.
+
+ - Function: fileno port
+ Returns the integer file descriptor associated with the port PORT.
+ If an error is detected, `#f' is returned.
+
+ - Function: access pathname how
+ Returns `#t' if the file named by PATHNAME can be accessed in the
+ way specified by the HOW argument. The HOW argument can be the
+ `logior' of the flags:
+
+ 0. File-exists?
+
+ 1. File-is-executable?
+
+ 2. File-is-writable?
+
+ 4. File-is-readable?
+
+ Or the HOW argument can be a string of 0 to 3 of the following
+ characters in any order. The test performed is the `and' of the
+ associated tests and `file-exists?'.
+
+ <x>
+ File-is-executable?
+
+ <w>
+ File-is-writable?
+
+ <r>
+ File-is-readable?
+
+ - Function: execl command arg0 ...
+ - Function: execlp command arg0 ...
+ Transfers control to program COMMAND called with arguments ARG0
+ .... For `execl', COMMAND must be an exact pathname of an
+ executable file. `execlp' searches for COMMAND in the list of
+ directories specified by the environment variable PATH. The
+ convention is that ARG0 is the same name as COMMAND.
+
+ If successful, this procedure does not return. Otherwise an error
+ message is printed and the integer `errno' is returned.
+
+ - Function: execv command arglist
+ - Function: execvp command arglist
+ Like `execl' and `execlp' except that the set of arguments to
+ COMMAND is ARGLIST.
+
+ - Function: putenv string
+ adds or removes definitions from the "environment". If the STRING
+ is of the form `NAME=VALUE', the definition is added to the
+ environment. Otherwise, the 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 `='. System-defined environment variables
+ are invariably uppercase.
+
+ `Putenv' is used to set up the environment before calls to
+ `execl', `execlp', `execv', `execvp', `system', or `open-pipe'
+ (*note open-pipe: Posix Extensions.).
+
+ To access environment variables, use `getenv' (*note getenv:
+ (slib)System Interface.).
+
+
+File: scm.info, Node: Posix Extensions, Next: Unix Extensions, Prev: I/O-Extensions, Up: Packages
+
+Posix Extensions
+================
+
+If `'posix' is provided (by linking in `posix.o'), the following
+functions are defined:
+
+ - Function: open-pipe string modes
+ If the string MODES contains an <r>, returns an input port capable
+ of delivering characters from the standard output of the system
+ command STRING. Otherwise, returns an output port capable of
+ receiving characters which become the standard input of the system
+ command STRING. If a pipe cannot be created `#f' is returned.
+
+ - Function: open-input-pipe string
+ Returns an input port capable of delivering characters from the
+ standard output of the system command STRING. If a pipe cannot be
+ created `#f' is returned.
+
+ - Function: open-output-pipe string
+ Returns an output port capable of receiving characters which become
+ the standard input of the system command STRING. If a pipe cannot
+ be created `#f' is returned.
+
+ - Function: broken-pipe port
+ If this function is defined at top level, it will be called when an
+ output pipe is closed from the other side (this is the condition
+ under which a SIGPIPE is sent). The already closed PORT will be
+ passed so that any necessary cleanup may be done. An error is not
+ signaled when output to a pipe fails in this way, but any further
+ output to the closed pipe will cause an error to be signaled.
+
+ - Function: close-port pipe
+ Closes the 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.
+
+ - Function: pipe
+ Returns `(cons RD WD)' where RD and WD are the read and write
+ (port) ends of a "pipe" respectively.
+
+ - Function: fork
+ Creates a copy of the process calling `fork'. Both processes
+ return from `fork', but the calling ("parent") process's `fork'
+ returns the "child" process's ID whereas the child process's
+ `fork' returns 0.
+
+For a discussion of "ID"s *Note Process Persona: (GNU C Library)Process
+Persona.
+
+ - Function: getppid
+ Returns the process ID of the parent of the current process. For
+ a process's own ID *Note getpid: I/O-Extensions.
+
+ - Function: getlogin
+ Returns the (login) name of the user logged in on the controlling
+ terminal of the process, or #f if this information cannot be
+ determined.
+
+ - Function: getuid
+ Returns the real user ID of this process.
+
+ - Function: getgid
+ Returns the real group ID of this process.
+
+ - Function: getegid
+ Returns the effective group ID of this process.
+
+ - Function: geteuid
+ Returns the effective user ID of this process.
+
+ - Function: setuid id
+ Sets the real user ID of this process to ID. Returns `#t' if
+ successful, `#f' if not.
+
+ - Function: setgid id
+ Sets the real group ID of this process to ID. Returns `#t' if
+ successful, `#f' if not.
+
+ - Function: setegid id
+ Sets the effective group ID of this process to ID. Returns `#t'
+ if successful, `#f' if not.
+
+ - Function: seteuid id
+ Sets the effective user ID of this process to ID. Returns `#t' if
+ successful, `#f' if not.
+
+ - Function: kill pid sig
+ The `kill' function sends the signal SIGNUM to the process or
+ process group specified by PID. Besides the signals listed in
+ *Note Standard Signals: (libc)Standard Signals, SIGNUM can also
+ have a value of zero to check the validity of the PID.
+
+ The PID specifies the process or process group to receive the
+ signal:
+
+ > 0
+ The process whose identifier is PID.
+
+ 0
+ All processes in the same process group as the sender. The
+ sender itself does not receive the signal.
+
+ -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.
+
+ < -1
+ The process group whose identifier is `(abs PID)'.
+
+ A process can send a signal to itself with `(kill (getpid)
+ SIGNUM)'. If `kill' is used by a process to send a signal to
+ itself, and the signal is not blocked, then `kill' delivers at
+ least one signal (which might be some other pending unblocked
+ signal instead of the signal SIGNUM) to that process before it
+ returns.
+
+ The return value from `kill' is zero if the signal can be sent
+ successfully. Otherwise, no signal is sent, and a value of `-1' is
+ returned. If PID specifies sending a signal to several processes,
+ `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.
+
+ - Function: waitpid pid options
+ The `waitpid' function suspends execution of the current process
+ until a child as specified by the PID argument has exited, or
+ until a signal is delivered whose action is to terminate the
+ current process or to call a signal handling function. If a child
+ as requested by PID has already exited by the time of the call (a
+ so-called "zombie" process), the function returns immediately.
+ Any system resources used by the child are freed.
+
+ The value of PID can be:
+
+ < -1
+ which means to wait for any child process whose process group
+ ID is equal to the absolute value of PID.
+
+ -1
+ which means to wait for any child process; this is the same
+ behaviour which wait exhibits.
+
+ 0
+ which means to wait for any child process whose process group
+ ID is equal to that of the calling process.
+
+ > 0
+ which means to wait for the child whose process ID is equal
+ to the value of PID.
+
+ The value of OPTIONS is one of the following:
+
+ 0. Nothing special.
+
+ 1. (`WNOHANG') which means to return immediately if no child is
+ there to be waited for.
+
+ 2. (`WUNTRACED') which means to also return for children which
+ are stopped, and whose status has not been reported.
+
+ 3. Which means both of the above.
+
+ The return value normally is the exit status of the child process,
+ including the exit value along with flags indicating whether a
+ coredump was generated or the child terminated as a result of a
+ signal. If the `WNOHANG' option was specified and no child
+ process is waiting to be noticed, the value is zero. A value of
+ `#f' is returned in case of error and `errno' is set. For
+ information about the `errno' codes *Note Process Completion: (GNU
+ C Library)Process Completion.
+
+ - Function: uname
+ You can use the `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:
+
+ 0. The name of the operating system in use.
+
+ 1. The network name of this particular computer.
+
+ 2. The current release level of the operating system
+ implementation.
+
+ 3. The current version level within the release of the operating
+ system.
+
+ 4. Description of the type of hardware that is in use.
+
+ Some examples are `"i386-ANYTHING"', `"m68k-hp"',
+ `"sparc-sun"', `"m68k-sun"', `"m68k-sony"' and `"mips-dec"'.
+
+ - Function: getpw name
+ - Function: getpw uid
+ - Function: getpw
+ Returns a vector of information for the entry for `NAME', `UID',
+ or the next entry if no argument is given. The information is:
+
+ 0. The user's login name.
+
+ 1. The encrypted password string.
+
+ 2. The user ID number.
+
+ 3. The user's default group ID number.
+
+ 4. A string typically containing the user's real name, and
+ possibly other information such as a phone number.
+
+ 5. The user's home directory, initial working directory, or
+ `#f', in which case the interpretation is system-dependent.
+
+ 6. The user's default shell, the initial program run when the
+ user logs in, or `#f', indicating that the system default
+ should be used.
+
+ - Function: setpwent #t
+ Rewinds the pw entry table back to the begining.
+
+ - Function: setpwent #f
+ - Function: setpwent
+ Closes the pw table.
+
+ - Function: getgr name
+ - Function: getgr uid
+ - Function: getgr
+ Returns a vector of information for the entry for `NAME', `UID',
+ or the next entry if no argument is given. The information is:
+
+ 0. The name of the group.
+
+ 1. The encrypted password string.
+
+ 2. The group ID number.
+
+ 3. A list of (string) names of users in the group.
+
+ - Function: setgrent #t
+ Rewinds the group entry table back to the begining.
+
+ - Function: setgrent #f
+ - Function: setgrent
+ Closes the group table.
+
+ - Function: getgroups
+ Returns a vector of all the supplementary group IDs of the process.
+
+ - Function: link oldname newname
+ The `link' function makes a new link to the existing file named by
+ OLDNAME, under the new name NEWNAME.
+
+ `link' returns a value of `#t' if it is successful and `#f' on
+ failure.
+
+ - Function: chown filename owner group
+ The `chown' function changes the owner of the file FILENAME to
+ OWNER, and its group owner to GROUP.
+
+ `chown' returns a value of `#t' if it is successful and `#f' on
+ failure.
+
+ - Function: ttyname port
+ If port PORT is associated with a terminal device, returns a
+ string containing the file name of termainal device; otherwise
+ `#f'.
+
+
+File: scm.info, Node: Unix Extensions, Next: Regular Expression Pattern Matching, Prev: Posix Extensions, Up: Packages
+
+Unix Extensions
+===============
+
+If `'unix' is provided (by linking in `unix.o'), the following
+functions are defined:
+
+These "privileged" and symbolic link functions are not in Posix:
+
+ - Function: symlink oldname newname
+ The `symlink' function makes a symbolic link to OLDNAME named
+ NEWNAME.
+
+ `symlink' returns a value of `#t' if it is successful and `#f' on
+ failure.
+
+ - Function: readlink filename
+ Returns the value of the symbolic link FILENAME or `#f' for
+ failure.
+
+ - Function: lstat filename
+ The `lstat' function is like `stat', except that it does not
+ follow symbolic links. If FILENAME is the name of a symbolic
+ link, `lstat' returns information about the link itself; otherwise,
+ `lstat' works like `stat'. *Note I/O-Extensions::.
+
+ - Function: nice increment
+ Increment the priority of the current process by INCREMENT.
+ `chown' returns a value of `#t' if it is successful and `#f' on
+ failure.
+
+ - Function: acct filename
+ When called with the name of an exisitng file as argument,
+ accounting is turned on, records for each terminating process are
+ appended to FILENAME as it terminates. An argument of `#f' causes
+ accounting to be turned off.
+
+ `acct' returns a value of `#t' if it is successful and `#f' on
+ failure.
+
+ - Function: mknod filename mode dev
+ The `mknod' function makes a special file with name FILENAME and
+ modes MODE for device number DEV.
+
+ `mknod' returns a value of `#t' if it is successful and `#f' on
+ failure.
+
+ - Function: sync
+ `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.
+
+
+File: scm.info, Node: Regular Expression Pattern Matching, Next: Line Editing, Prev: Unix Extensions, Up: Packages
+
+Regular Expression Pattern Matching
+===================================
+
+These functions are defined in `rgx.c' using a POSIX or GNU "regex"
+library. If your computer does not support regex, a package is
+available via ftp from `ftp.gnu.org:/pub/gnu/regex-0.12.tar.gz'. For a
+description of regular expressions, *Note syntax: (regex)syntax.
+
+ - Function: regcomp PATTERN [FLAGS]
+ Compile a "regular expression". Return a compiled regular
+ expression, or an integer error code suitable as an argument to
+ `regerror'.
+
+ FLAGS in `regcomp' is a string of option letters used to control
+ the compilation of the regular expression. The letters may
+ consist of:
+
+ `n'
+ newlines won't be matched by `.' or hat lists; ( `[^...]' )
+
+ `i'
+ ignore case.only when compiled with _GNU_SOURCE:
+
+
+ `0'
+ allows dot to match a null character.
+
+ `f'
+ enable GNU fastmaps.
+
+ - Function: regerror ERRNO
+ Returns a string describing the integer ERRNO returned when
+ `regcomp' fails.
+
+ - Function: regexec RE STRING
+ Returns `#f' or a vector of integers. These integers are in
+ doublets. The first of each doublet is the index of 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
+ STRING of the end of that expression. `#f' is returned if the
+ string does not match.
+
+ - Function: regmatch? RE STRING
+ Returns `#t' if the PATTERN such that REGEXP = (regcomp PATTERN)
+ matches STRING as a POSIX extended regular expressions. Returns
+ `#f' otherwise.
+
+ - Function: regsearch RE STRING [START [LEN]]
+ - Function: regsearchv RE STRING [START [LEN]]
+ - Function: regmatch RE STRING [START [LEN]]
+ - Function: regmatchv RE STRING [START [LEN]]
+ `Regsearch' searches for the pattern within the string.
+
+ `Regmatch' anchors the pattern and begins matching it against
+ string.
+
+ `Regsearch' returns the character position where RE starts, or
+ `#f' if not found.
+
+ `Regmatch' returns the number of characters matched, `#f' if not
+ matched.
+
+ `Regsearchv' and `regmatchv' return the match vector is returned
+ if RE is found, `#f' otherwise.
+
+ RE
+ may be either:
+ 1. a compiled regular expression returned by `regcomp';
+
+ 2. a string representing a regular expression;
+
+ 3. a list of a string and a set of option letters.
+
+ STRING
+ The string to be operated upon.
+
+ START
+ The character position at which to begin the search or match.
+ If absent, the default is zero.
+
+ _Compiled _GNU_SOURCE and using GNU libregex only:_
+
+
+ When searching, if START is negative, the absolute value of
+ START will be used as the start location and reverse searching
+ will be performed.
+
+ LEN
+ The search is allowed to examine only the first LEN
+ characters of STRING. If absent, the entire string may be
+ examined.
+
+ - Function: string-split RE STRING
+ - Function: string-splitv RE STRING
+ `String-split' splits a string into substrings that are separated
+ by RE, returning a vector of substrings.
+
+ `String-splitv' returns a vector of string positions that indicate
+ where the substrings are located.
+
+ - Function: string-edit RE EDIT-SPEC STRING [COUNT]
+ Returns the edited string.
+
+ EDIT-SPEC
+ Is a string used to replace occurances of RE. Backquoted
+ integers in the range of 1-9 may be used to insert
+ subexpressions in RE, as in `sed'.
+
+ COUNT
+ The number of substitutions for `string-edit' to perform. If
+ `#t', all occurances of RE will be replaced. The default is
+ to perform one substitution.
+
+
+File: scm.info, Node: Line Editing, Next: Curses, Prev: Regular Expression Pattern Matching, Up: Packages
+
+Line Editing
+============
+
+These procedures provide input line editing and recall.
+
+These functions are defined in `edline.c' and `Iedline.scm' using the
+"editline" or GNU "readline" (*note Overview: (readline)Top.) libraries
+available from:
+
+ * `ftp.sys.toronto.edu:/pub/rc/editline.shar'
+
+ * `ftp.gnu.org:/pub/gnu/readline-2.0.tar.gz'
+
+When `Iedline.scm' is loaded, if the current input port is the default
+input port and the environment variable EMACS is not defined,
+line-editing mode will be entered.
+
+ - Function: default-input-port
+ Returns the initial `current-input-port' SCM was invoked with
+ (stdin).
+
+ - Function: default-output-port
+ Returns the initial `current-output-port' SCM was invoked with
+ (stdout).
+
+ - Function: make-edited-line-port
+ Returns an input/output port that allows command line editing and
+ retrieval of history.
+
+ - Function: line-editing
+ Returns the current edited line port or `#f'.
+
+ - Function: line-editing bool
+ If BOOL is false, exits line-editing mode and returns the previous
+ value of `(line-editing)'. If BOOL is true, sets the current
+ input and output ports to an edited line port and returns the
+ previous value of `(line-editing)'.
+
+
+File: scm.info, Node: Curses, Next: Sockets, Prev: Line Editing, Up: Packages
+
+Curses
+======
+
+These functions are defined in `crs.c' using the "curses" library.
+Unless otherwise noted these routines return `#t' for successful
+completion and `#f' for failure.
+
+ - Function: initscr
+ Returns a port for a full screen window. This routine must be
+ called to initialize curses.
+
+ - Function: endwin
+ A program should call `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 *Note
+ refresh: Window Manipulation.
+
+* Menu:
+
+* Output Options Setting::
+* Terminal Mode Setting::
+* Window Manipulation::
+* Output::
+* Input::
+* Curses Miscellany::
+
+
+File: scm.info, Node: Output Options Setting, Next: Terminal Mode Setting, Prev: Curses, Up: Curses
+
+Output Options Setting
+----------------------
+
+These routines set options within curses that deal with output. All
+options are initially `#f', unless otherwise stated. It is not
+necessary to turn these options off before calling `endwin'.
+
+ - Function: clearok win bf
+ If enabled (BF is `#t'), the next call to `force-output' or
+ `refresh' with 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.
+
+ - Function: idlok win bf
+ If enabled (BF is `#t'), curses will consider using the hardware
+ "insert/delete-line" feature of terminals so equipped. If
+ disabled (BF is `#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.
+
+ - Function: 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.
+
+ - Function: scrollok win bf
+ This option controls what happens when the cursor of window 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 (BF is `#f'), the cursor is left on the
+ bottom line at the location where the offending character was
+ entered. If enabled (BF is `#t'), `force-output' is called on the
+ window WIN, and then the physical terminal and window WIN are
+ scrolled up one line.
+
+ _Note:_ in order to get the physical scrolling effect on the
+ terminal, it is also necessary to call `idlok'.
+
+ - Function: 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.
+
+
+File: scm.info, Node: Terminal Mode Setting, Next: Window Manipulation, Prev: Output Options Setting, Up: Curses
+
+Terminal Mode Setting
+---------------------
+
+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
+`endwin'. The routines in this section all return an unspecified value.
+
+ - Function: cbreak
+ - Function: nocbreak
+ These two routines put the terminal into and out of `CBREAK' mode,
+ respectively. In `CBREAK' mode, characters typed by the user are
+ immediately available to the program and erase/kill character
+ processing is not performed. When in `NOCBREAK' mode, the tty
+ driver will buffer characters typed until a <LFD> or <RET> is
+ typed. Interrupt and flowcontrol characters are unaffected by
+ this mode. Initially the terminal may or may not be in `CBREAK'
+ mode, as it is inherited, therefore, a program should call
+ `cbreak' or `nocbreak' explicitly. Most interactive programs
+ using curses will set `CBREAK' mode.
+
+ _Note:_ `cbreak' overrides `raw'. For a discussion of how these
+ routines interact with `echo' and `noecho' *Note read-char: Input.
+
+ - Function: raw
+ - Function: noraw
+ The terminal is placed into or out of `RAW' mode. `RAW' mode is
+ similar to `CBREAK' mode, in that characters typed are immediately
+ passed through to the user program. The differences are that in
+ `RAW' mode, the interrupt, quit, suspend, and flow control
+ characters are passed through uninterpreted, instead of generating
+ a signal. `RAW' mode also causes 8-bit input and output. The
+ behavior of the `BREAK' key depends on other bits in the terminal
+ driver that are not set by curses.
+
+ - Function: echo
+ - Function: noecho
+ These routines control whether characters typed by the user are
+ echoed by `read-char' as they are typed. Echoing by the tty
+ driver is always disabled, but initially `read-char' is in `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 `noecho'. For a discussion of how these routines interact
+ with `echo' and `noecho' *Note read-char: Input.
+
+ - Function: nl
+ - Function: nonl
+ These routines control whether <LFD> is translated into <RET> and
+ `LFD' on output, and whether <RET> is translated into <LFD> on
+ input. Initially, the translations do occur. By disabling these
+ translations using `nonl', curses is able to make better use of
+ the linefeed capability, resulting in faster cursor motion.
+
+ - Function: resetty
+ - Function: savetty
+ These routines save and restore the state of the terminal modes.
+ `savetty' saves the current state of the terminal in a buffer and
+ `resetty' restores the state to what it was at the last call to
+ `savetty'.
+
+
+File: scm.info, Node: Window Manipulation, Next: Output, Prev: Terminal Mode Setting, Up: Curses
+
+Window Manipulation
+-------------------
+
+ - Function: newwin nlines ncols begy begx
+ Create and return a new window with the given number of lines (or
+ rows), NLINES, and columns, NCOLS. The upper left corner of the
+ window is at line BEGY, column BEGX. If either NLINES or NCOLS is
+ 0, they will be set to the value of `LINES'-BEGY and `COLS'-BEGX.
+ A new full-screen window is created by calling `newwin(0,0,0,0)'.
+
+ - Function: subwin orig nlines ncols begy begx
+ Create and return a pointer to a new window with the given number
+ of lines (or rows), NLINES, and columns, NCOLS. The window is at
+ position (BEGY, BEGX) on the screen. This position is relative to
+ the screen, and not to the window ORIG. The window is made in the
+ middle of the window ORIG, so that changes made to one window will
+ affect both windows. When using this routine, often it will be
+ necessary to call `touchwin' or `touchline' on ORIG before calling
+ `force-output'.
+
+ - Function: close-port win
+ Deletes the window WIN, freeing up all memory associated with it.
+ In the case of sub-windows, they should be deleted before the main
+ window WIN.
+
+ - Function: refresh
+ - Function: force-output win
+ These routines are called to write output to the terminal, as most
+ other routines merely manipulate data structures. `force-output'
+ copies the window 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 `leaveok' has been enabled, the physical cursor of the
+ terminal is left at the location of window WIN's cursor. With
+ `refresh', the number of characters output to the terminal is
+ returned.
+
+ - Function: mvwin win y x
+ Move the window WIN so that the upper left corner will be at
+ position (Y, X). If the move would cause the window WIN to be off
+ the screen, it is an error and the window WIN is not moved.
+
+ - Function: overlay srcwin dstwin
+ - Function: overwrite srcwin dstwin
+ These routines overlay SRCWIN on top of DSTWIN; that is, all text
+ in SRCWIN is copied into DSTWIN. SRCWIN and DSTWIN need not be
+ the same size; only text where the two windows overlap is copied.
+ The difference is that `overlay' is non-destructive (blanks are
+ not copied), while `overwrite' is destructive.
+
+ - Function: touchwin win
+ - Function: touchline win start count
+ Throw away all optimization information about which parts of the
+ window WIN have been touched, by pretending that the entire window
+ 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. `touchline' only
+ pretends that COUNT lines have been changed, beginning with line
+ START.
+
+ - Function: wmove win y x
+ The cursor associated with the window WIN is moved to line (row) Y,
+ column X. This does not move the physical cursor of the terminal
+ until `refresh' (or `force-output') is called. The position
+ specified is relative to the upper left corner of the window WIN,
+ which is (0, 0).
+
+
+File: scm.info, Node: Output, Next: Input, Prev: Window Manipulation, Up: Curses
+
+Output
+------
+
+These routines are used to "draw" text on windows
+
+ - Function: display ch win
+ - Function: display str win
+ - Function: wadd win ch
+ - Function: wadd win str
+ The character CH or characters in STR are put into the window WIN
+ at the current cursor position of the window and the position of
+ 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 CH is a <TAB>, <LFD>, or backspace, the cursor will be moved
+ appropriately within the window WIN. A <LFD> also does a
+ `wclrtoeol' before moving. <TAB> characters are considered to be
+ at every eighth column. If CH is another control character, it
+ will be drawn in the `C-x' notation. (Calling `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 `standout', below.
+
+ _Note:_ For `wadd' CH can be an integer and will insert the
+ character of the corresponding value.
+
+ - Function: werase win
+ This routine copies blanks to every position in the window WIN.
+
+ - Function: wclear win
+ This routine is like `werase', but it also calls *Note clearok:
+ Output Options Setting, arranging that the screen will be cleared
+ completely on the next call to `refresh' or `force-output' for
+ window WIN, and repainted from scratch.
+
+ - Function: wclrtobot win
+ All lines below the cursor in window WIN are erased. Also, the
+ current line to the right of the cursor, inclusive, is erased.
+
+ - Function: wclrtoeol win
+ The current line to the right of the cursor, inclusive, is erased.
+
+ - Function: wdelch win
+ The character under the cursor in the window 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.
+
+ - Function: wdeleteln win
+ The line under the cursor in the window WIN is deleted. All lines
+ below the current line are moved up one line. The bottom line WIN
+ is cleared. The cursor position does not change. This does not
+ imply use of the hardware "deleteline" feature.
+
+ - Function: winsch win ch
+ The character CH is inserted before the character under the
+ cursor. All characters to the right are moved one <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.
+
+ - Function: 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.
+
+ - Function: scroll win
+ The window WIN is scrolled up one line. This involves moving the
+ lines in WIN's data structure. As an optimization, if WIN is
+ stdscr and the scrolling region is the entire window, the physical
+ screen will be scrolled at the same time.
+
+
+File: scm.info, Node: Input, Next: Curses Miscellany, Prev: Output, Up: Curses
+
+Input
+-----
+
+ - Function: read-char win
+ A character is read from the terminal associated with the window
+ WIN. Depending on the setting of `cbreak', this will be after one
+ character (`CBREAK' mode), or after the first newline (`NOCBREAK'
+ mode). Unless `noecho' has been set, the character will also be
+ echoed into WIN.
+
+ When using `read-char', do not set both `NOCBREAK' mode
+ (`nocbreak') and `ECHO' mode (`echo') at the same time. Depending
+ on the state of the terminal driver when each character is typed,
+ the program may produce undesirable results.
+
+ - Function: winch win
+ The character, of type chtype, at the current position in window
+ WIN is returned. If any attributes are set for that position,
+ their values will be OR'ed into the value returned.
+
+ - Function: getyx win
+ A list of the y and x coordinates of the cursor position of the
+ window WIN is returned
+
+
+File: scm.info, Node: Curses Miscellany, Prev: Input, Up: Curses
+
+Curses Miscellany
+-----------------
+
+ - Function: wstandout win
+ - Function: wstandend win
+ These functions set the current attributes of the window WIN. The
+ current attributes of 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.
+
+ `wstandout' sets the current attributes of the window WIN to be
+ visibly different from other text. `wstandend' turns off the
+ attributes.
+
+ - Function: box win vertch horch
+ A box is drawn around the edge of the window WIN. VERTCH and
+ HORCH are the characters the box is to be drawn with. If VERTCH
+ and HORCH are 0, then appropriate default characters, `ACS_VLINE'
+ and `ACS_HLINE', will be used.
+
+ _Note:_ VERTCH and HORCH can be an integers and will insert the
+ character (with attributes) of the corresponding values.
+
+ - Function: unctrl c
+ This macro expands to a character string which is a printable
+ representation of the character C. Control characters are
+ displayed in the `C-x' notation. Printing characters are displayed
+ as is.
+
+
+File: scm.info, Node: Sockets, Prev: Curses, Up: Packages
+
+Sockets
+=======
+
+These procedures (defined in `socket.c') provide a Scheme interface to
+most of the C "socket" library. For more information on sockets, *Note
+Sockets: (libc)Sockets.
+
+* Menu:
+
+* Host Data::
+* Internet Addresses and Socket Names::
+* Socket::
+
+
+File: scm.info, Node: Host Data, Next: Internet Addresses and Socket Names, Prev: Sockets, Up: Sockets
+
+Host Data, Network, Protocol, and Service Inquiries
+---------------------------------------------------
+
+ - Constant: af_inet
+ - Constant: af_unix
+ Integer family codes for Internet and Unix sockets, respectively.
+
+ - Function: gethost host-spec
+ - Function: gethost
+ Returns a vector of information for the entry for `HOST-SPEC' or
+ the next entry if `HOST-SPEC' isn't given. The information is:
+
+ 0. host name string
+
+ 1. list of host aliases strings
+
+ 2. integer address type (`AF_INET')
+
+ 3. integer size of address entries (in bytes)
+
+ 4. list of integer addresses
+
+ - Function: sethostent stay-open
+ - Function: sethostent
+ Rewinds the host entry table back to the begining if given an
+ argument. If the argument STAY-OPEN is `#f' queries will be be
+ done using `UDP' datagrams. Otherwise, a connected `TCP' socket
+ will be used. When called without an argument, the host table is
+ closed.
+
+ - Function: getnet name-or-number
+ - Function: getnet
+ Returns a vector of information for the entry for NAME-OR-NUMBER or
+ the next entry if an argument isn't given. The information is:
+
+ 0. official network name string
+
+ 1. list of network aliases strings
+
+ 2. integer network address type (`AF_INET')
+
+ 3. integer network number
+
+ - Function: setnetent stay-open
+ - Function: setnetent
+ Rewinds the network entry table back to the begining if given an
+ argument. If the argument STAY-OPEN is `#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.
+
+ - Function: getproto name-or-number
+ - Function: getproto
+ Returns a vector of information for the entry for NAME-OR-NUMBER or
+ the next entry if an argument isn't given. The information is:
+
+ 1. official protocol name string
+
+ 2. list of protocol aliases strings
+
+ 3. integer protocol number
+
+ - Function: setprotoent stay-open
+ - Function: setprotoent
+ Rewinds the protocol entry table back to the begining if given an
+ argument. If the argument STAY-OPEN is `#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.
+
+ - Function: getserv name-or-port-number protocol
+ - Function: getserv
+ Returns a vector of information for the entry for
+ NAME-OR-PORT-NUMBER and PROTOCOL or the next entry if arguments
+ aren't given. The information is:
+
+ 0. official service name string
+
+ 1. list of service aliases strings
+
+ 2. integer port number
+
+ 3. protocol
+
+ - Function: setservent stay-open
+ - Function: setservent
+ Rewinds the service entry table back to the begining if given an
+ argument. If the argument STAY-OPEN is `#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.
+
+
+File: scm.info, Node: Internet Addresses and Socket Names, Next: Socket, Prev: Host Data, Up: Sockets
+
+Internet Addresses and Socket Names
+-----------------------------------
+
+ - Function: inet:string->address string
+ Returns the host address number (integer) for host STRING or `#f'
+ if not found.
+
+ - Function: inet:address->string address
+ Converts an internet (integer) address to a string in numbers and
+ dots notation.
+
+ - Function: inet:network address
+ Returns the network number (integer) specified from ADDRESS or
+ `#f' if not found.
+
+ - Function: inet:local-network-address address
+ Returns the integer for the address of ADDRESS within its local
+ network or `#f' if not found.
+
+ - Function: inet:make-address network local-address
+ Returns the Internet address of LOCAL-ADDRESS in NETWORK.
+
+The type "socket-name" is used for inquiries about open sockets in the
+following procedures:
+
+ - Function: getsockname socket
+ Returns the socket-name of SOCKET. Returns `#f' if unsuccessful
+ or SOCKET is closed.
+
+ - Function: getpeername socket
+ Returns the socket-name of the socket connected to SOCKET.
+ Returns `#f' if unsuccessful or SOCKET is closed.
+
+ - Function: socket-name:family socket-name
+ Returns the integer code for the family of SOCKET-NAME.
+
+ - Function: socket-name:port-number socket-name
+ Returns the integer port number of SOCKET-NAME.
+
+ - Function: socket-name:address socket-name
+ Returns the integer Internet address for SOCKET-NAME.
+
+
+File: scm.info, Node: Socket, Prev: Internet Addresses and Socket Names, Up: Sockets
+
+Socket
+------
+
+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):
+ (require 'i/o-extensions)
+ (define i-port (duplicate-port sock-port "r"))
+ (define o-port (duplicate-port sock-port "w"))
+
+ - Function: make-stream-socket family
+ - Function: make-stream-socket family protocol
+ Returns a `SOCK_STREAM' socket of type FAMILY using PROTOCOL. If
+ FAMILY has the value `AF_INET', `SO_REUSEADDR' will be set. The
+ integer argument PROTOCOL corresponds to the integer protocol
+ numbers returned (as vector elements) from `(getproto)'. If the
+ PROTOCOL argument is not supplied, the default (0) for the
+ specified FAMILY is used. SCM sockets look like ports opened for
+ neither reading nor writing.
+
+ - Function: make-stream-socketpair family
+ - Function: make-stream-socketpair family protocol
+ Returns a pair (cons) of connected `SOCK_STREAM' (socket) ports of
+ type FAMILY using PROTOCOL. Many systems support only socketpairs
+ of the `af-unix' FAMILY. The integer argument PROTOCOL
+ corresponds to the integer protocol numbers returned (as vector
+ elements) from (getproto). If the PROTOCOL argument is not
+ supplied, the default (0) for the specified FAMILY is used.
+
+ - Function: socket:shutdown socket how
+ Makes SOCKET no longer respond to some or all operations depending
+ on the integer argument HOW:
+
+ 0. Further input is disallowed.
+
+ 1. Further output is disallowed.
+
+ 2. Further input or output is disallowed.
+
+ `Socket:shutdown' returns SOCKET if successful, `#f' if not.
+
+ - Function: socket:connect inet-socket host-number port-number
+ - Function: socket:connect unix-socket pathname
+ Returns SOCKET (changed to a read/write port) connected to the
+ Internet socket on host HOST-NUMBER, port PORT-NUMBER or the Unix
+ socket specified by PATHNAME. Returns `#f' if not successful.
+
+ - Function: socket:bind inet-socket port-number
+ - Function: socket:bind unix-socket pathname
+ Returns INET-SOCKET bound to the integer PORT-NUMBER or the
+ UNIX-SOCKET bound to new socket in the file system at location
+ PATHNAME. Returns `#f' if not successful. Binding a UNIX-SOCKET
+ creates a socket in the file system that must be deleted by the
+ caller when it is no longer needed (using `delete-file').
+
+ - Function: socket:listen socket backlog
+ The bound (*note bind: Socket.) SOCKET is readied to accept
+ connections. The positive integer BACKLOG specifies how many
+ pending connections will be allowed before further connection
+ requests are refused. Returns SOCKET (changed to a read-only
+ port) if successful, `#f' if not.
+
+ - Function: char-ready? listen-socket
+ The input port returned by a successful call to `socket:listen' can
+ be polled for connections by `char-ready?' (*note char-ready?:
+ Files and Ports.). This avoids blocking on connections by
+ `socket:accept'.
+
+ - Function: socket:accept socket
+ Accepts a connection on a bound, listening SOCKET. Returns an
+ input/output port for the connection.
+
+The following example is not too complicated, yet shows the use of
+sockets for multiple connections without input blocking.
+
+ ;;;; 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)
+ (let ((actives (or (apply wait-for-input 5 listener-socket connections)
+ '())))
+ (cond ((null? actives))
+ ((memq listener-socket actives)
+ (set! actives (cdr (memq listener-socket actives)))
+ (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 ((memq con actives)
+ (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)))))))))))))
+
+You can use `telnet localhost 8001' to connect to the chat server, or
+you can use a client written in scheme:
+
+ ;;;; 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))
+
+ (define (go)
+ (define actives (wait-for-input (* 30 60) con (current-input-port)))
+ (let ((cs (and actives (memq con actives) (read-char con)))
+ (ct (and actives (memq (current-input-port) actives) (read-char))))
+ (cond ((or (eof-object? cs) (eof-object? ct)) (close-port con))
+ (else (cond (cs (display cs)))
+ (cond (ct (file-set-position con 0)
+ (display ct con)
+ (file-set-position con 0)))
+ (go)))))
+ (cond (con (display "Connecting to ")
+ (display (getpeername con))
+ (newline)
+ (go))
+ (else (display "Server not listening on port 8001")
+ (newline)))
+
+
+File: scm.info, Node: The Implementation, Next: Index, Prev: Packages, Up: Top
+
+The Implementation
+******************
+
+* Menu:
+
+* Data Types::
+* Operations::
+* Program Self-Knowledge:: What SCM needs to know about itself.
+* Improvements To Make::
+
+
+File: scm.info, Node: Data Types, Next: Operations, Prev: The Implementation, Up: The Implementation
+
+Data Types
+==========
+
+In the descriptions below it is assumed that `long int's are 32 bits in
+length. Acutally, SCM is written to work with any `long int' size
+larger than 31 bits. With some modification, SCM could work with word
+sizes as small as 24 bits.
+
+All SCM objects are represented by type "SCM". Type `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
+
+
+File: scm.info, Node: Immediates, Next: Cells, Prev: Data Types, Up: Data Types
+
+Immediates
+----------
+
+An "immediate" is a data type contained in type `SCM' (`long int').
+The type codes distinguishing immediate types from each other vary in
+length, but reside in the low order bits.
+
+ - Macro: IMP x
+ - Macro: NIMP x
+ Return non-zero if the `SCM' object X is an immediate or
+ non-immediate type, respectively.
+
+ - Immediate: inum
+ immediate 30 bit signed integer. An INUM is flagged by a `1' in
+ the second to low order bit position. The high order 30 bits are
+ used for the integer's value.
+
+ - Macro: INUMP x
+ - Macro: NINUMP x
+ Return non-zero if the `SCM' X is an immediate integer or not
+ an immediate integer, respectively.
+
+ - Macro: INUM x
+ Returns the C `long integer' corresponding to `SCM' X.
+
+ - Macro: MAKINUM x
+ Returns the `SCM' inum corresponding to C `long integer' x.
+
+ - Immediate Constant: INUM0
+ is equivalent to `MAKINUM(0)'.
+
+ 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 `scmfig.h' and a signed right shift,
+ `SRS', is constructed in terms of unsigned right shift.
+
+ - Immediate: ichr
+ characters.
+
+ - Macro: ICHRP x
+ Return non-zero if the `SCM' object X is a character.
+
+ - Macro: ICHR x
+ Returns corresponding `unsigned char'.
+
+ - Macro: MAKICHR x
+ Given `char' X, returns `SCM' character.
+
+
+ - Immediate: iflags
+ These are frequently used immediate constants.
+
+ - Immediate Constant: SCM BOOL_T
+ `#t'
+
+ - Immediate Constant: SCM BOOL_F
+ `#f'
+
+ - Immediate Constant: SCM EOL
+ `()'. If `SICP' is `#define'd, `EOL' is `#define'd to be
+ identical with `BOOL_F'. In this case, both print as `#f'.
+
+ - Immediate Constant: SCM EOF_VAL
+ end of file token, `#<eof>'.
+
+ - Immediate Constant: SCM UNDEFINED
+ `#<undefined>' used for variables which have not been defined
+ and absent optional arguments.
+
+ - Immediate Constant: SCM UNSPECIFIED
+ `#<unspecified>' is returned for those procedures whose return
+ values are not specified.
+
+
+ - Macro: IFLAGP n
+ Returns non-zero if N is an ispcsym, isym or iflag.
+
+ - Macro: ISYMP n
+ Returns non-zero if N is an ispcsym or isym.
+
+ - Macro: ISYMNUM n
+ Given ispcsym, isym, or iflag N, returns its index in the C array
+ `isymnames[]'.
+
+ - Macro: ISYMCHARS n
+ Given ispcsym, isym, or iflag N, returns its `char *'
+ representation (from `isymnames[]').
+
+ - Macro: MAKSPCSYM n
+ Returns `SCM' ispcsym N.
+
+ - Macro: MAKISYM n
+ Returns `SCM' iisym N.
+
+ - Macro: MAKIFLAG n
+ Returns `SCM' iflag N.
+
+ - Variable: isymnames
+ An array of strings containing the external representations of all
+ the ispcsym, isym, and iflag immediates. Defined in `repl.c'.
+
+ - Constant: NUM_ISPCSYM
+ - Constant: NUM_ISYMS
+ The number of ispcsyms and ispcsyms+isyms, respectively. Defined
+ in `scm.h'.
+
+ - Immediate: isym
+ `and', `begin', `case', `cond', `define', `do', `if', `lambda',
+ `let', `let*', `letrec', `or', `quote', `set!', `#f', `#t',
+ `#<undefined>', `#<eof>', `()', and `#<unspecified>'.
+
+ - CAR Immediate: ispcsym
+ special symbols: syntax-checked versions of first 14 isyms
+
+ - CAR Immediate: iloc
+ indexes to a variable's location in environment
+
+ - CAR Immediate: gloc
+ pointer to a symbol's value cell
+
+ - 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 `0'.
+
+ There is one exception to this rule, _CAR Immediate_s, described
+ next.
+
+A "CAR Immediate" is an Immediate point which can only occur in the
+`CAR's of evaluated code (as a result of `ceval''s memoization process).
+
+
+File: scm.info, Node: Cells, Next: Header Cells, Prev: Immediates, Up: Data Types
+
+Cells
+-----
+
+"Cell"s represent all SCM objects other than immediates. A cell has a
+`CAR' and a `CDR'. Low-order bits in `CAR' identify the type of
+object. The rest of `CAR' and `CDR' hold object data. The number
+after `tc' specifies how many bits are in the type code. For instance,
+`tc7' indicates that the type code is 7 bits.
+
+ - Macro: NEWCELL x
+ Allocates a new cell and stores a pointer to it in `SCM' local
+ variable X.
+
+ Care needs to be taken that stores into the new cell pointed to by
+ X do not create an inconsistent object. *Note Signals::.
+
+All of the C macros decribed in this section assume that their argument
+is of type `SCM' and points to a cell (`CELLPTR').
+
+ - Macro: CAR x
+ - Macro: CDR x
+ Returns the `car' and `cdr' of cell X, respectively.
+
+ - Macro: TYP3 x
+ - Macro: TYP7 x
+ - Macro: TYP16 x
+ Returns the 3, 7, and 16 bit type code of a cell.
+
+ - Cell: tc3_cons
+ scheme cons-cell returned by (cons arg1 arg2).
+
+ - Macro: CONSP x
+ - Macro: NCONSP x
+ Returns non-zero if X is a `tc3_cons' or isn't, respectively.
+
+ - Cell: tc3_closure
+ applicable object returned by (lambda (args) ...). `tc3_closure's
+ have a pointer to the body of the procedure in the `CAR' and a
+ pointer to the environment in the `CDR'. Bits 1 and 2
+ (zero-based) in the `CDR' indicate a lower bound on the number of
+ required arguments to the closure, which is used to avoid
+ allocating rest argument lists in the environment cache. This
+ encoding precludes an immediate value for the `CDR': In the case
+ of an empty environment all bits above 2 in the `CDR' are zero.
+
+ - Macro: CLOSUREP x
+ Returns non-zero if X is a `tc3_closure'.
+
+ - Macro: CODE x
+ - Macro: ENV x
+ Returns the code body or environment of closure X,
+ respectively.
+
+ - Macro: ARGC x
+ Returns the a lower bound on the number of required arguments
+ to closure X, it cannot exceed 3.
+
+
+
+File: scm.info, Node: Header Cells, Next: Subr Cells, Prev: Cells, Up: Data Types
+
+Header Cells
+------------
+
+"Header"s are Cells whose `CDR's point elsewhere in memory, such as to
+memory allocated by `malloc'.
+
+ - Header: spare
+ spare `tc7' type code
+
+ - Header: tc7_vector
+ scheme vector.
+
+ - Macro: VECTORP x
+ - Macro: NVECTORP x
+ Returns non-zero if X is a `tc7_vector' or if not,
+ respectively.
+
+ - Macro: VELTS x
+ - Macro: LENGTH x
+ Returns the C array of `SCM's holding the elements of vector
+ X or its length, respectively.
+
+ - Header: tc7_ssymbol
+ static scheme symbol (part of initial system)
+
+ - Header: tc7_msymbol
+ `malloc'ed scheme symbol (can be GCed)
+
+ - Macro: SYMBOLP x
+ Returns non-zero if X is a `tc7_ssymbol' or `tc7_msymbol'.
+
+ - Macro: CHARS x
+ - Macro: UCHARS x
+ - Macro: LENGTH x
+ Returns the C array of `char's or as `unsigned char's holding
+ the elements of symbol X or its length, respectively.
+
+ - Header: tc7_string
+ scheme string
+
+ - Macro: STRINGP x
+ - Macro: NSTRINGP x
+ Returns non-zero if X is a `tc7_string' or isn't,
+ respectively.
+
+ - Macro: CHARS x
+ - Macro: UCHARS x
+ - Macro: LENGTH x
+ Returns the C array of `char's or as `unsigned char's holding
+ the elements of string X or its length, respectively.
+
+ - Header: tc7_bvect
+ uniform vector of booleans (bit-vector)
+
+ - Header: tc7_ivect
+ uniform vector of integers
+
+ - Header: tc7_uvect
+ uniform vector of non-negative integers
+
+ - Header: tc7_svect
+ uniform vector of short integers
+
+ - Header: tc7_fvect
+ uniform vector of short inexact real numbers
+
+ - Header: tc7_dvect
+ uniform vector of double precision inexact real numbers
+
+ - Header: tc7_cvect
+ uniform vector of double precision inexact complex numbers
+
+ - Header: tc7_contin
+ applicable object produced by call-with-current-continuation
+
+ - Header: tc7_specfun
+ subr that is treated specially within the evaluator
+
+ `apply' and `call-with-current-continuation' are denoted by these
+ objects. Their behavior as functions is built into the evaluator;
+ they are not directly associated with C functions. This is
+ necessary in order to make them properly tail recursive.
+
+ tc16_cclo is a subtype of tc7_specfun, a cclo is similar to a
+ vector (and is GCed like one), but can be applied as a function:
+
+ 1. the cclo itself is consed onto the head of the argument list
+
+ 2. the first element of the cclo is applied to that list. Cclo
+ invocation is currently not tail recursive when given 2 or
+ more arguments.
+
+ - Function: makcclo proc len
+ makes a closure from the _subr_ PROC with LEN-1 extra
+ locations for `SCM' data. Elements of a CCLO are referenced
+ using `VELTS(cclo)[n]' just as for vectors.
+
+ - Macro: CCLO_LENGTH cclo
+ Expands to the length of CCLO.
+
+
+File: scm.info, Node: Subr Cells, Next: Ptob Cells, Prev: Header Cells, Up: Data Types
+
+Subr Cells
+----------
+
+A "Subr" is a header whose `CDR' points to a C code procedure. Scheme
+primitive procedures are subrs. Except for the arithmetic `tc7_cxr's,
+the C code procedures will be passed arguments (and return results) of
+type `SCM'.
+
+ - Subr: tc7_asubr
+ associative C function of 2 arguments. Examples are `+', `-',
+ `*', `/', `max', and `min'.
+
+ - Subr: tc7_subr_0
+ C function of no arguments.
+
+ - Subr: tc7_subr_1
+ C function of one argument.
+
+ - Subr: tc7_cxr
+ These subrs are handled specially. If inexact numbers are
+ enabled, the `CDR' should be a function which takes and returns
+ type `double'. Conversions are handled in the interpreter.
+
+ `floor', `ceiling', `truncate', `round', `$sqrt', `$abs', `$exp',
+ `$log', `$sin', `$cos', `$tan', `$asin', `$acos', `$atan',
+ `$sinh', `$cosh', `$tanh', `$asinh', `$acosh', `$atanh', and
+ `exact->inexact' are defined this way.
+
+ If the `CDR' is `0' (`NULL'), the name string of the procedure is
+ used to control traversal of its list structure argument.
+
+ `car', `cdr', `caar', `cadr', `cdar', `cddr', `caaar', `caadr',
+ `cadar', `caddr', `cdaar', `cdadr', `cddar', `cdddr', `caaaar',
+ `caaadr', `caadar', `caaddr', `cadaar', `cadadr', `caddar',
+ `cadddr', `cdaaar', `cdaadr', `cdadar', `cdaddr', `cddaar',
+ `cddadr', `cdddar', and `cddddr' are defined this way.
+
+ - Subr: tc7_subr_3
+ C function of 3 arguments.
+
+ - Subr: tc7_subr_2
+ C function of 2 arguments.
+
+ - Subr: tc7_rpsubr
+ transitive relational predicate C function of 2 arguments. The C
+ function should return either `BOOL_T' or `BOOL_F'.
+
+ - Subr: tc7_subr_1o
+ C function of one optional argument. If the optional argument is
+ not present, `UNDEFINED' is passed in its place.
+
+ - Subr: tc7_subr_2o
+ C function of 1 required and 1 optional argument. If the optional
+ argument is not present, `UNDEFINED' is passed in its place.
+
+ - Subr: tc7_lsubr_2
+ C function of 2 arguments and a list of (rest of) `SCM' arguments.
+
+ - Subr: tc7_lsubr
+ C function of list of `SCM' arguments.
+
+
+File: scm.info, Node: Ptob Cells, Next: Smob Cells, Prev: Subr Cells, Up: Data Types
+
+Ptob Cells
+----------
+
+A "ptob" is a port object, capable of delivering or accepting
+characters. *Note Ports: (r5rs)Ports. Unlike the types described so
+far, new varieties of ptobs can be defined dynamically (*note Defining
+Ptobs::). These are the initial ptobs:
+
+ - ptob: tc16_inport
+ input port.
+
+ - ptob: tc16_outport
+ output port.
+
+ - ptob: tc16_ioport
+ input-output port.
+
+ - ptob: tc16_inpipe
+ input pipe created by `popen()'.
+
+ - ptob: tc16_outpipe
+ output pipe created by `popen()'.
+
+ - ptob: tc16_strport
+ String port created by `cwos()' or `cwis()'.
+
+ - ptob: tc16_sfport
+ Software (virtual) port created by `mksfpt()' (*note Soft Ports::).
+
+ - Macro: PORTP x
+ - Macro: OPPORTP x
+ - Macro: OPINPORTP x
+ - Macro: OPOUTPORTP x
+ - Macro: INPORTP x
+ - Macro: OUTPORTP x
+ Returns non-zero if X is a port, open port, open input-port, open
+ output-port, input-port, or output-port, respectively.
+
+ - Macro: OPENP x
+ - Macro: CLOSEDP x
+ Returns non-zero if port X is open or closed, respectively.
+
+ - Macro: STREAM x
+ Returns the `FILE *' stream for port X.
+
+Ports which are particularly well behaved are called "fport"s.
+Advanced operations like `file-position' and `reopen-file' only work
+for fports.
+
+ - Macro: FPORTP x
+ - Macro: OPFPORTP x
+ - Macro: OPINFPORTP x
+ - Macro: OPOUTFPORTP x
+ Returns non-zero if X is a port, open port, open input-port, or
+ open output-port, respectively.
+
+
+File: scm.info, Node: Smob Cells, Next: Data Type Representations, Prev: Ptob Cells, Up: Data Types
+
+Smob Cells
+----------
+
+A "smob" is a miscellaneous datatype. The type code and GCMARK bit
+occupy the lower order 16 bits of the `CAR' half of the cell. The rest
+of the `CAR' can be used for sub-type or other information. The `CDR'
+contains data of size long and is often a pointer to allocated memory.
+
+Like ptobs, new varieties of smobs can be defined dynamically (*note
+Defining Smobs::). These are the initial smobs:
+
+ - smob: tc_free_cell
+ unused cell on the freelist.
+
+ - smob: tc16_flo
+ single-precision float.
+
+ Inexact number data types are subtypes of type `tc16_flo'. If the
+ sub-type is:
+
+ 0. a single precision float is contained in the `CDR'.
+
+ 1. `CDR' is a pointer to a `malloc'ed double.
+
+ 3. `CDR' is a pointer to a `malloc'ed pair of doubles.
+
+ - smob: tc_dblr
+ double-precision float.
+
+ - smob: tc_dblc
+ double-precision complex.
+
+ - smob: tc16_bigpos
+ - 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
+ `malloc'ed array of type `BIGDIG' which must be an unsigned
+ integral type with size smaller than `long'. `BIGRAD' is the
+ radix associated with `BIGDIG'.
+
+ `NUMDIGS_MAX' (defined in `scmfig.h') limits the number of digits
+ of a bignum to 1000. These digits are base `BIGRAD', which is
+ typically 65536, giving 4816 decimal digits.
+
+ Why only 4800 digits? The simple multiplication algorithm SCM
+ uses is O(n^2); this means the number of processor instructions
+ required to perform a multiplication is _some multiple_ of the
+ product of the number of digits of the two multiplicands.
+
+ digits * digits ==> operations
+ 5 x
+ 50 100 * x
+ 500 10000 * x
+ 5000 1000000 * x
+
+ To calculate numbers larger than this, FFT multiplication
+ [O(n*log(n))] and other specialized algorithms are required. You
+ should obtain a package which specializes in number-theoretical
+ calculations:
+
+ <ftp://megrez.math.u-bordeaux.fr/pub/pari/>
+
+
+ - smob: tc16_promise
+ made by DELAY. *Note Control features: (r5rs)Control features.
+
+ - smob: tc16_arbiter
+ synchronization object. *Note Process Synchronization::.
+
+ - smob: tc16_macro
+ macro expanding function. *Note Low Level Syntactic Hooks::.
+
+ - smob: tc16_array
+ multi-dimensional array. *Note Arrays::.
+
+ This type implements both conventional arrays (those with
+ arbitrary data as elements *note Conventional Arrays::) and
+ uniform arrays (those with elements of a uniform type *note
+ Uniform Array::).
+
+ Conventional Arrays have a pointer to a vector for their `CDR'.
+ Uniform Arrays have a pointer to a Uniform Vector type (string,
+ bvect, ivect, uvect, fvect, dvect, or cvect) in their `CDR'.
+
+
+File: scm.info, Node: Data Type Representations, Prev: Smob Cells, Up: Data Types
+
+Data Type Representations
+-------------------------
+
+IMMEDIATE: B,D,E,F=data bit, C=flag code, P=pointer address bit
+ ................................
+inum BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB10
+ichr BBBBBBBBBBBBBBBBBBBBBBBB11110100
+iflag CCCCCCC101110100
+isym CCCCCCC001110100
+ IMCAR: only in car of evaluated code, cdr has cell's GC bit
+ispcsym 000CCCC00CCCC100
+iloc 0DDDDDDDDDDDEFFFFFFFFFFF11111100
+pointer PPPPPPPPPPPPPPPPPPPPPPPPPPPPP000
+gloc PPPPPPPPPPPPPPPPPPPPPPPPPPPPP001
+
+ 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:
+cons ..........SCM car..............0 ...........SCM cdr.............G
+closure ..........SCM code...........011 ...........SCM env...........CCG
+ 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
+svect .........long length....G0100111 ........ short *words...........
+fvect .........long length....G0101101 .........float *words...........
+dvect .........long length....G0101111 ........double *words...........
+cvect .........long length....G0110101 ........double *words...........
+
+contin .........long length....G0111101 .............*regs..............
+specfun ................xxxxxxxxG1111111 ...........SCM name.............
+cclo ..short length..xxxxxx10G1111111 ...........SCM **elts...........
+ PTOBs:
+ port 0bwroxxxxxxxxG0110111 ..........FILE *stream..........
+ socket ttttttt 00001xxxxxxxxG0110111 ..........FILE *stream..........
+ inport uuuuuuuuuuU00011xxxxxxxxG0110111 ..........FILE *stream..........
+outport 0000000000000101xxxxxxxxG0110111 ..........FILE *stream..........
+ ioport uuuuuuuuuuU00111xxxxxxxxG0110111 ..........FILE *stream..........
+fport 00 00000000G0110111 ..........FILE *stream..........
+pipe 00 00000001G0110111 ..........FILE *stream..........
+strport 00 00000010G0110111 ..........FILE *stream..........
+sfport 00 00000011G0110111 ..........FILE *stream..........
+ SUBRs:
+ 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 ..........int hpoff.....01110111 ...........SCM (*f)()...........
+rpsubr ..........int hpoff.....01111101 ...........SCM (*f)()...........
+ SMOBs:
+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..............
+
+
+File: scm.info, Node: Operations, Next: Program Self-Knowledge, Prev: Data Types, Up: The Implementation
+
+Operations
+==========
+
+* Menu:
+
+* Garbage Collection:: Automatically reclaims unused storage
+* Memory Management for Environments::
+* Signals::
+* C Macros::
+* Changing Scm::
+* Defining Subrs::
+* Defining Smobs::
+* Defining Ptobs::
+* Allocating memory::
+* Embedding SCM:: In other programs
+* Callbacks::
+* Type Conversions:: For use with C code.
+* Continuations:: For C and SCM
+* Evaluation:: Why SCM is fast
+
+
+File: scm.info, Node: Garbage Collection, Next: Memory Management for Environments, Prev: Operations, Up: Operations
+
+Garbage Collection
+------------------
+
+The garbage collector is in the latter half of `sys.c'. The primary
+goal of "garbage collection" (or "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 "heap" (composed of "heap segments"). Note
+that this is different from what Computer Science usually defines as a
+heap.
+
+* Menu:
+
+* Marking Cells::
+* Sweeping the Heap::
+
+
+File: scm.info, Node: Marking Cells, Next: Sweeping the Heap, Prev: Garbage Collection, Up: Garbage Collection
+
+Marking Cells
+.............
+
+The first step in garbage collection is to "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 `scm.h' to
+allow easy manipulation when GC bits are possibly set. `CAR', `TYP3',
+and `TYP7' can be used on GC marked cells as they are.
+
+ - Macro: GCCDR x
+ Returns the CDR of a cons cell, even if that cell has been GC
+ marked.
+
+ - Macro: GCTYP16 x
+ Returns the 16 bit type code of a cell.
+
+We need to (recursively) mark only a few objects in order to assure that
+all accessible objects are marked. Those objects are `sys_protects[]'
+(for example, `dynwinds'), the current C-stack and the hash table for
+symbols, "symhash".
+
+ - Function: void gc_mark (SCM OBJ)
+ The function `gc_mark()' is used for marking SCM cells. If OBJ is
+ marked, `gc_mark()' returns. If OBJ is unmarked, gc_mark sets the
+ mark bit in OBJ, then calls `gc_mark()' on any SCM components of
+ OBJ. The last call to `gc_mark()' is tail-called (looped).
+
+ - Function: void mark_locations (STACKITEM X[], sizet LEN))
+ The function `mark_locations' is used for marking segments of
+ C-stack or saved segments of C-stack (marked continuations). The
+ argument LEN is the size of the stack in units of size
+ `(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 `gc_mark'. If the stack is
+ word rather than longword aligned `(#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.
+
+
+File: scm.info, Node: Sweeping the Heap, Prev: Marking Cells, Up: Garbage Collection
+
+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.
+
+ - Function: static void gc_sweep ()
+ The function `gc_sweep' scans through all heap segments. The mark
+ bit is cleared from marked cells. Unmarked cells are spliced into
+ FREELIST, where they can again be returned by invocations of
+ `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 `free' procedure is called to free its storage.
+
+
+File: scm.info, Node: Memory Management for Environments, Next: Signals, Prev: Garbage Collection, Up: Operations
+
+Memory Management for Environments
+----------------------------------
+
+ * "Ecache" was designed and implemented by Radey Shouman.
+
+ * This documentation of ecache was written by Tom Lord.
+
+The memory management component of SCM contains special features which
+optimize the allocation and garbage collection of environments.
+
+The optimizations are based on certain facts and assumptions:
+
+The SCM evaluator creates many environments with short lifetimes and
+these account of a _large portion_ of the total number of objects
+allocated.
+
+The general purpose allocator allocates objects from a freelist, and
+collects using a mark/sweep algorithm. Research into garbage
+collection suggests that such an allocator is sub-optimal for object
+populations containing a large portion of short-lived members and that
+allocation strategies involving a copying collector are more
+appropriate.
+
+It is a property of SCM, reflected throughout the source code, that a
+simple copying collector can not be used as the general purpose memory
+manager: much code assumes that the run-time stack can be treated as a
+garbage collection root set using "conservative garbage collection"
+techniques, which are incompatible with objects that change location.
+
+Nevertheless, it is possible to use a mostly-separate
+copying-collector, just for environments. Roughly speaking, cons pairs
+making up environments are initially allocated from a small heap that
+is collected by a precise copying collector. These objects must be
+handled specially for the collector to work. The (presumably) small
+number of these objects that survive one collection of the copying heap
+are copied to the general purpose heap, where they will later be
+collected by the mark/sweep collector. The remaining pairs are more
+rapidly collected than they would otherwise be and all of this
+collection is accomplished without having to mark or sweep any other
+segment of the heap.
+
+Allocating cons pairs for environments from this special heap is a
+heuristic that approximates the (unachievable) goal:
+
+ allocate all short-lived objects from the copying-heap, at no
+ extra cost in allocation time.
+
+Implementation Details
+......................
+
+A separate heap (`ecache_v') is maintained for the copying collector.
+Pairs are allocated from this heap in a stack-like fashion. Objects in
+this heap may be protected from garbage collection by:
+
+ 1. Pushing a reference to the object on a stack specially maintained
+ for that purpose. This stack (`scm_estk') is used in place of the
+ C run-time stack by the SCM evaluator to hold local variables
+ which refer to the copying heap.
+
+ 2. Saving a reference to every object in the mark/sweep heap which
+ directly references the copying heap in a root set that is
+ specially maintained for that purpose (`scm_egc_roots'). If no
+ object in the mark/sweep heap directly references an object from
+ the copying heap, that object can be preserved by storing a direct
+ reference to it in the copying-collector root set.
+
+ 3. Keeping no other references to these objects, except references
+ between the objects themselves, during copying collection.
+
+When the copying heap or root-set becomes full, the copying collector is
+invoked. All protected objects are copied to the mark-sweep heap. All
+references to those objects are updated. The copying collector root-set
+and heap are emptied.
+
+References to pairs allocated specificly for environments are
+inaccessible to the Scheme procedures evaluated by SCM. These pairs
+are manipulated by only a small number of code fragments in the
+interpreter. To support copying collection, those code fragments
+(mostly in `eval.c') have been modified to protect environments from
+garbage collection using the three rules listed above.
+
+During a mark-sweep collection, the copying collector heap is marked
+and swept almost like any ordinary segment of the general purpose heap.
+The only difference is that pairs from the copying heap that become
+free during a sweep phase are not added to the freelist.
+
+The environment cache is disabled by adding `#define NO_ENV_CACHE' to
+`eval.c'; all environment cells are then allocated from the regular
+heap.
+
+Relation to Other Work
+......................
+
+This work seems to build upon a considerable amount of previous work
+into garbage collection techniques about which a considerable amount of
+literature is available.
+
+
+File: scm.info, Node: Signals, Next: C Macros, Prev: Memory Management for Environments, Up: Operations
+
+Signals
+-------
+
+ - Function: init_signals
+ (in `scm.c') initializes handlers for `SIGINT' and `SIGALRM' if
+ they are supported by the C implementation. All of the signal
+ handlers immediately reestablish themselves by a call to
+ `signal()'.
+
+ - Function: int_signal sig
+ - Function: alrm_signal sig
+ The low level handlers for `SIGINT' and `SIGALRM'.
+
+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. `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 `DEFER_INTS' and `ALLOW_INTS'.
+
+ - Macro: DEFER_INTS
+ sets the global variable `ints_disabled' to 1. If an interrupt
+ occurs during a time when `ints_disabled' is 1, then
+ `deferred_proc' is set to non-zero, one of the global variables
+ `SIGINT_deferred' or `SIGALRM_deferred' is set to 1, and the
+ handler returns.
+
+ - Macro: ALLOW_INTS
+ Checks the deferred variables and if set the appropriate handler is
+ called.
+
+ Calls to `DEFER_INTS' can not be nested. An `ALLOW_INTS' must
+ happen before another `DEFER_INTS' can be done. In order to check
+ that this constraint is satisfied `#define CAREFUL_INTS' in
+ `scmfig.h'.
+
+
+File: scm.info, Node: C Macros, Next: Changing Scm, Prev: Signals, Up: Operations
+
+C Macros
+--------
+
+ - Macro: ASSERT cond arg pos subr
+ signals an error if the expression (COND) is 0. ARG is the
+ offending object, SUBR is the string naming the subr, and POS
+ indicates the position or type of error. POS can be one of
+
+ * `ARGn' (> 5 or unknown ARG number)
+
+ * `ARG1'
+
+ * `ARG2'
+
+ * `ARG3'
+
+ * `ARG4'
+
+ * `ARG5'
+
+ * `WNA' (wrong number of args)
+
+ * `OVFLOW'
+
+ * `OUTOFRANGE'
+
+ * `NALLOC'
+
+ * `EXIT'
+
+ * `HUP_SIGNAL'
+
+ * `INT_SIGNAL'
+
+ * `FPE_SIGNAL'
+
+ * `BUS_SIGNAL'
+
+ * `SEGV_SIGNAL'
+
+ * `ALRM_SIGNAL'
+
+ * a C string `(char *)'
+
+ Error checking is not done by `ASSERT' if the flag `RECKLESS' is
+ defined. An error condition can still be signaled in this case
+ with a call to `wta(arg, pos, subr)'.
+
+ - Macro: ASRTGO cond label
+ `goto' LABEL if the expression (COND) is 0. Like `ASSERT',
+ `ASRTGO' does is not active if the flag `RECKLESS' is defined.
+
+
+File: scm.info, Node: Changing Scm, Next: Defining Subrs, Prev: C Macros, Up: Operations
+
+Changing Scm
+------------
+
+When writing C-code for SCM, a precaution is recommended. If your
+routine allocates a non-cons cell which will _not_ be incorporated into
+a `SCM' object which is returned, you need to make sure that a `SCM'
+variable in your routine points to that cell as long as part of it
+might be referenced by your code.
+
+In order to make sure this `SCM' variable does not get optimized out
+you can put this assignment after its last possible use:
+
+ SCM_dummy1 = foo;
+
+or put this assignment somewhere in your routine:
+
+ SCM_dummy1 = (SCM) &foo;
+
+`SCM_dummy' variables are not currently defined. Passing the address
+of the local `SCM' variable to _any_ procedure also protects it. The
+procedure `scm_protect_temp' is provided for this purpose.
+
+Also, if you maintain a static pointer to some (non-immediate) `SCM'
+object, you must either make your pointer be the value cell of a symbol
+(see `errobj' for an example) or make your pointer be one of the
+`sys_protects' (see `dynwinds' for an example). The former method is
+prefered since it does not require any changes to the SCM distribution.
+
+To add a C routine to scm:
+
+ 1. choose the appropriate subr type from the type list.
+
+ 2. write the code and put into `scm.c'.
+
+ 3. add a `make_subr' or `make_gsubr' call to `init_scm'. Or put an
+ entry into the appropriate `iproc' structure.
+
+To add a package of new procedures to scm (see `crs.c' for example):
+
+ 1. create a new C file (`foo.c').
+
+ 2. at the front of `foo.c' put declarations for strings for your
+ procedure names.
+
+ static char s_twiddle_bits[]="twiddle-bits!";
+ static char s_bitsp[]="bits?";
+
+ 3. choose the appropriate subr types from the type list in `code.doc'.
+
+ 4. write the code for the procedures and put into `foo.c'
+
+ 5. create one `iproc' structure for each subr type used in `foo.c'
+
+ static iproc subr3s[]= {
+ {s_twiddle-bits,twiddle-bits},
+ {s_bitsp,bitsp},
+ {0,0} };
+
+ 6. create an `init_<name of file>' routine at the end of the file
+ which calls `init_iprocs' with the correct type for each of the
+ `iproc's created in step 5.
+
+ void init_foo()
+ {
+ init_iprocs(subr1s, tc7_subr_1);
+ init_iprocs(subr3s, tc7_subr_3);
+ }
+
+ If your package needs to have a "finalization" routine called to
+ free up storage, close files, etc, then also have a line in
+ `init_foo' like:
+
+ add_final(final_foo);
+
+ `final_foo' should be a (void) procedure of no arguments. The
+ finals will be called in opposite order from their definition.
+
+ The line:
+
+ add_feature("foo");
+
+ will append a symbol `'foo' to the (list) value of `*features*'.
+
+ 7. put any scheme code which needs to be run as part of your package
+ into `Ifoo.scm'.
+
+ 8. put an `if' into `Init5d6.scm' which loads `Ifoo.scm' if your
+ package is included:
+
+ (if (defined? twiddle-bits!)
+ (load (in-vicinity (implementation-vicinity)
+ "Ifoo"
+ (scheme-file-suffix))))
+
+ or use `(provided? 'foo)' instead of `(defined? twiddle-bits!)'
+ if you have added the feature.
+
+ 9. put documentation of the new procedures into `foo.doc'
+
+ 10. add lines to your `Makefile' to compile and link SCM with your
+ object file. Add a `init_foo\(\)\;' to the `INITS=...' line at
+ the beginning of the makefile.
+
+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.
+
+ 1. define a new `MAKISYM' in `scm.h' and increment `NUM_ISYMS'.
+
+ 2. add a string with the new name in the corresponding place in
+ `isymnames' in `repl.c'.
+
+ 3. add `case:' clause to `ceval()' near `i_quasiquote' (in `eval.c').
+
+New syntax can now be added without recompiling SCM by the use of the
+`procedure->syntax', `procedure->macro', `procedure->memoizing-macro',
+and `defmacro'. For details, *Note Syntax Extensions::.
+
+
+File: scm.info, Node: Defining Subrs, Next: Defining Smobs, Prev: Changing Scm, Up: Operations
+
+Defining Subrs
+--------------
+
+If "CCLO" is `#define'd when compiling, the compiled closure feature
+will be enabled. It is automatically enabled if dynamic linking is
+enabled.
+
+The SCM interpreter directly recognizes subrs taking small numbers of
+arguments. In order to create subrs taking larger numbers of arguments
+use:
+
+ - Function: make_gsubr name req opt rest fcn
+ returns a cclo (compiled closure) object of name `char *' NAME
+ which takes `int' REQ required arguments, `int' OPT optional
+ arguments, and a list of rest arguments if `int' REST is 1 (0 for
+ not).
+
+ `SCM (*fcn)()' is a pointer to a C function to do the work.
+
+ The C function will always be called with REQ + OPT + REST
+ arguments, optional arguments not supplied will be passed
+ `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.
+
+ /* 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);
+ }
+
+
+File: scm.info, Node: Defining Smobs, Next: Defining Ptobs, Prev: Defining Subrs, Up: Operations
+
+Defining Smobs
+--------------
+
+Here is an example of how to add a new type named `foo' to SCM. The
+following lines need to be added to your code:
+
+`long tc16_foo;'
+ The type code which will be used to identify the new type.
+
+`static smobfuns foosmob = {markfoo,freefoo,printfoo,equalpfoo};'
+ smobfuns is a structure composed of 4 functions:
+
+ 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;
+
+ `smob.mark'
+ is a function of one argument of type `SCM' (the cell to
+ mark) and returns type `SCM' which will then be marked. If
+ no further objects need to be marked then return an immediate
+ object such as `BOOL_F'. The smob cell itself will already
+ have been marked. _Note:_ This is different from SCM
+ versions prior to 5c5. Only additional data specific to a
+ smob type need be marked by `smob.mark'.
+
+ 2 functions are provided:
+
+ `markcdr(ptr)'
+ returns `CDR(ptr)'.
+
+ `mark0(ptr)'
+ is a no-op used for smobs containing no additional `SCM'
+ data. 0 may also be used in this case.
+
+ `smob.free'
+ is a function of one argument of type `CELLPTR' (the cell to
+ collected) and returns type `sizet' which is the number of
+ `malloc'ed bytes which were freed. `Smob.free' should free
+ any `malloc'ed storage associated with this object. The
+ function free0(ptr) is provided which does not free any
+ storage and returns 0.
+
+ `smob.print'
+ is 0 or a function of 3 arguments. The first, of type `SCM',
+ is the smob object. The second, of type `SCM', is the stream
+ on which to write the result. The third, of type int, is 1
+ if the object should be `write'n, 0 if it should be
+ `display'ed, and 2 if it should be `write'n for an error
+ report. This function should return non-zero if it printed,
+ and zero otherwise (in which case a hexadecimal number will
+ be printed).
+
+ `smob.equalp'
+ is 0 or a function of 2 `SCM' arguments. Both of these
+ arguments will be of type `tc16foo'. This function should
+ return `BOOL_T' if the smobs are equal, `BOOL_F' if they are
+ not. If `smob.equalp' is 0, `equal?' will return `BOOL_F' if
+ they are not `eq?'.
+
+`tc16_foo = newsmob(&foosmob);'
+ Allocates the new type with the functions from `foosmob'. This
+ line goes in an `init_' routine.
+
+Promises and macros in `eval.c' and arbiters in `repl.c' provide
+examples of SMOBs. There are a maximum of 256 SMOBs. Smobs that must
+allocate blocks of memory should use, for example, `must_malloc' rather
+than `malloc' *Note Allocating memory::.
+
+
+File: scm.info, Node: Defining Ptobs, Next: Allocating memory, Prev: Defining Smobs, Up: Operations
+
+Defining Ptobs
+--------------
+
+"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 `ptobfuns':
+
+ 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;
+
+The `.free' component to the structure takes a `FILE *' or other C
+construct as its argument, unlike `.free' in a smob, which takes the
+whole smob cell. Often, `.free' and `.fclose' can be the same
+function. See `fptob' and `pipob' in `sys.c' for examples of how to
+define ptobs. Ptobs that must allocate blocks of memory should use,
+for example, `must_malloc' rather than `malloc' *Note Allocating
+memory::.
+
+
+File: scm.info, Node: Allocating memory, Next: Embedding SCM, Prev: Defining Ptobs, Up: Operations
+
+Allocating memory
+-----------------
+
+SCM maintains a count of bytes allocated using malloc, and calls the
+garbage collector when that number exceeds a dynamically managed limit.
+In order for this to work properly, `malloc' and `free' should not be
+called directly to manage memory freeable by garbage collection. The
+following functions are provided for that purpose:
+
+ - Function: SCM must_malloc_cell (long LEN, SCM C, char *WHAT)
+ - Function: char * must_malloc (long LEN, char *WHAT)
+ LEN is the number of bytes that should be allocated, WHAT is a
+ string to be used in error or gc messages. `must_malloc' returns
+ a pointer to newly allocated memory. `must_malloc_cell' returns a
+ newly allocated cell whose `car' is C and whose `cdr' is a pointer
+ to newly allocated memory.
+
+ - Function: void must_realloc_cell (SCM Z, long OLEN, long LEN, char
+ *WHAT)
+ - Function: char * must_realloc (char *WHERE, long OLEN, long LEN,
+ char *WHAT)
+ `must_realloc_cell' takes as argument Z a cell whose `cdr' should
+ be a pointer to a block of memory of length OLEN allocated with
+ `must_malloc_cell' and modifies the `cdr' to point to a block of
+ memory of length LEN. `must_realloc' takes as argument WHERE the
+ address of a block of memory of length OLEN allocated by
+ `must_malloc' and returns the address of a block of length LEN.
+
+ The contents of the reallocated block will be unchanged up to the
+ minimum of the old and new sizes.
+
+ WHAT is a pointer to a string used for error and gc messages.
+
+`must_malloc', `must_malloc_cell', `must_realloc', and
+`must_realloc_cell' must be called with interrupts deferred *Note
+Signals::. `must_realloc' and `must_realloc_cell' must not be called
+during initialization (non-zero errjmp_bad) - the initial allocations
+must be large enough.
+
+ - Function: void must_free (char *PTR, sizet LEN)
+ `must_free' is used to free a block of memory allocated by the
+ above functions and pointed to by PTR. LEN is the length of the
+ block in bytes, but this value is used only for debugging purposes.
+ If it is difficult or expensive to calculate then zero may be used
+ instead.
+
+
+File: scm.info, Node: Embedding SCM, Next: Callbacks, Prev: Allocating memory, Up: Operations
+
+Embedding SCM
+-------------
+
+The file `scmmain.c' contains the definition of main(). When SCM is
+compiled as a library `scmmain.c' is not included in the library; a
+copy of `scmmain.c' can be modified to use SCM as an embedded library
+module.
+
+ - Function: int main (int ARGC, char **ARGV)
+ This is the top level C routine. The value of the ARGC argument
+ is the number of command line arguments. The ARGV argument is a
+ vector of C strings; its elements are the individual command line
+ argument strings. A null pointer always follows the last element:
+ `ARGV[ARGC]' is this null pointer.
+
+ - Variable: char *execpath
+ This string is the pathname of the executable file being run. This
+ variable can be examined and set from Scheme (*note Internal
+ State::). EXECPATH must be set to executable's path in order to
+ use DUMP (*note Dump::) or DLD.
+
+Rename main() and arrange your code to call it with an ARGV which sets
+up SCM as you want it.
+
+If you need more control than is possible through ARGV, here are
+descriptions of the functions which main() calls.
+
+ - Function: void init_sbrk (void)
+ Call this before SCM calls malloc(). Value returned from sbrk()
+ is used to gauge how much storage SCM uses.
+
+ - Function: char * scm_find_execpath (int ARGC, char **ARGV, char
+ *SCRIPT_ARG)
+ ARGC and ARGV are as described in main(). SCRIPT_ARG is the
+ pathname of the SCSH-style script (*note Scripting::) being
+ invoked; 0 otherwise. `scm_find_execpath' returns the pathname of
+ the executable being run; if `scm_find_execpath' cannot determine
+ the pathname, then it returns 0.
+
+`scm_find_implpath' is defined in `scmmain.c'. Preceeding this are
+definitions ofGENERIC_NAME and INIT_GETENV. These, along with IMPLINIT
+and DIRSEP control scm_find_implpath()'s operation.
+
+If your application has an easier way to locate initialization code for
+SCM, then you can replace `scm_find_implpath'.
+
+ - Function: char * scm_find_implpath (char *EXECPATH)
+ Returns the full pathname of the Scheme initialization file or 0
+ if it cannot find it.
+
+ The string value of the preprocessor variable INIT_GETENV names an
+ environment variable (default `"SCM_INIT_PATH"'). If this
+ environment variable is defined, its value will be returned from
+ `scm_find_implpath'. Otherwise find_impl_file() is called with the
+ arguments EXECPATH, GENERIC_NAME (default "scm"), INIT_FILE_NAME
+ (default "Init5d6_scm"), and the directory separator string
+ DIRSEP. If find_impl_file() returns 0 and IMPLINIT is defined,
+ then a copy of the string IMPLINIT is returned.
+
+ - Function: int init_buf0 (FILE *INPORT)
+ Tries to determine whether INPORT (usually stdin) is an
+ interactive input port which should be used in an unbuffered mode.
+ If so, INPORT is set to unbuffered and non-zero is returned.
+ Otherwise, 0 is returned.
+
+ `init_buf0' should be called before any input is read from INPORT.
+ Its value can be used as the last argument to
+ scm_init_from_argv().
+
+ - Function: void scm_init_from_argv (int ARGC, char **ARGV, char
+ *SCRIPT_ARG, int IVERBOSE, int BUF0STDIN)
+ Initializes SCM storage and creates a list of the argument strings
+ PROGRAM-ARGUMENTS from ARGV. ARGC and ARGV must already be
+ processed to accomodate Scheme Scripts (if desired). The scheme
+ variable *SCRIPT* is set to the string SCRIPT_ARG, or #f if
+ SCRIPT_ARG is 0. IVERBOSE is the initial prolixity level. If
+ BUF0STDIN is non-zero, stdin is treated as an unbuffered port.
+
+Call `init_signals' and `restore_signals' only if you want SCM to
+handle interrupts and signals.
+
+ - Function: void init_signals (void)
+ Initializes handlers for `SIGINT' and `SIGALRM' if they are
+ supported by the C implementation. All of the signal handlers
+ immediately reestablish themselves by a call to `signal()'.
+
+ - Function: void restore_signals (void)
+ Restores the handlers in effect when `init_signals' was called.
+
+ - Function: SCM scm_top_level (char *INITPATH, SCM (*toplvl_fun)())
+ This is SCM's top-level. Errors longjmp here. TOPLVL_FUN is a
+ callback function of zero arguments that is called by
+ `scm_top_level' to do useful work - if zero, then `repl', which
+ implements a read-eval-print loop, is called.
+
+ If TOPLVL_FUN returns, then `scm_top_level' will return as well.
+ If the return value of TOPLVL_FUN is an immediate integer then it
+ will be used as the return value of `scm_top_level'. In the main
+ function supplied with SCM, this return value is the exit status
+ of the process.
+
+ If the first character of string INITPATH is `;', `(' or
+ whitespace, then scm_ldstr() is called with INITPATH to initialize
+ SCM; otherwise INITPATH names a file of Scheme code to be loaded
+ to initialize SCM.
+
+ When a Scheme error is signaled; control will pass into
+ `scm_top_level' by `longjmp', error messages will be printed to
+ `current-error-port', and then TOPLVL_FUN will be called again.
+ TOPLVL_FUN must maintain enough state to prevent errors from being
+ resignalled. If `toplvl_fun' can not recover from an error
+ situation it may simply return.
+
+ - Function: void final_scm (int FREEALL)
+ Calls all finalization routines registered with add_final(). If
+ FREEALL is non-zero, then all memory which SCM allocated with
+ malloc() will be freed.
+
+You can call indivdual Scheme procedures from C code in the TOPLVL_FUN
+argument passed to scm_top_level(), or from module subrs (registered by
+an `init_' function, *note Changing Scm::).
+
+Use `apply' to call Scheme procedures from your C code. For 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);
+
+Functions for loading Scheme files and evaluating Scheme code given as
+C strings are described in the next section, (*note Callbacks::).
+
+Here is a minimal embedding program `libtest.c':
+
+ /* gcc -o libtest libtest.c libscm.a -ldl -lm -lc */
+ #include "scm.h"
+ /* include patchlvl.h for SCM's INIT_FILE_NAME. */
+ #include "patchlvl.h"
+
+ void init_user_scm()
+ {
+ fputs("This is init_user_scm\n", stderr); fflush(stderr);
+ sysintern("*the-string*", makfrom0str("hello world\n"));
+ }
+
+ SCM user_main()
+ {
+ static int done = 0;
+ if (done++) return MAKINUM(EXIT_FAILURE);
+ scm_ldstr("(display *the-string*)");
+ return MAKINUM(EXIT_SUCCESS);
+ }
+
+ int main(argc, argv)
+ int argc;
+ char **argv;
+ {
+ SCM retval;
+ char *implpath, *execpath;
+
+ execpath = dld_find_executable(argv[0]);
+ fprintf(stderr, "dld_find_executable(%s): %s\n", argv[0], execpath);
+ implpath = find_impl_file(execpath, "scm", INIT_FILE_NAME, dirsep);
+ fprintf(stderr, "implpath: %s\n", implpath);
+ scm_init_from_argv(argc, argv, 0L, 0, 0);
+
+ retval = scm_top_level(implpath, user_main);
+
+ final_scm(!0);
+ return (int)INUM(retval);
+ }
+
+ -|
+ dld_find_executable(./libtest): /home/jaffer/scm/libtest
+ implpath: /home/jaffer/scm/Init5d6.scm
+ This is init_user_scm
+ hello world
+
+
+File: scm.info, Node: Callbacks, Next: Type Conversions, Prev: Embedding SCM, Up: Operations
+
+Callbacks
+---------
+
+SCM now has routines to make calling back to Scheme procedures easier.
+The source code for these routines are found in `rope.c'.
+
+ - Function: int scm_ldfile (char *FILE)
+ Loads the Scheme source file FILE. Returns 0 if successful, non-0
+ if not. This function is used to load SCM's initialization file
+ `Init5d6.scm'.
+
+ - Function: int scm_ldprog (char *FILE)
+ Loads the Scheme source file `(in-vicinity (program-vicinity)
+ 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. `program-vicinity' is the
+ directory from which the calling code was loaded (*note Vicinity:
+ (slib)Vicinity.).
+
+ - Function: SCM scm_evstr (char *STR)
+ Returns the result of reading an expression from STR and
+ evaluating it.
+
+ - Function: void scm_ldstr (char *STR)
+ Reads and evaluates all the expressions from STR.
+
+If you wish to catch errors during execution of Scheme code, then you
+can use a wrapper like this for your Scheme procedures:
+
+ (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))
+
+Calls to procedures so wrapped will return even if an error occurs.
+
+
+File: scm.info, Node: Type Conversions, Next: Continuations, Prev: Callbacks, Up: Operations
+
+Type Conversions
+----------------
+
+These type conversion functions are very useful for connecting SCM and C
+code. Most are defined in `rope.c'.
+
+ - Function: SCM long2num (long N)
+ - Function: SCM ulong2num (unsigned long N)
+ Return an object of type `SCM' corresponding to the `long' or
+ `unsigned long' argument N. If N cannot be converted, `BOOL_F' is
+ returned. Which numbers can be converted depends on whether SCM
+ was compiled with the `BIGDIG' or `FLOATS' flags.
+
+ To convert integer numbers of smaller types (`short' or `char'),
+ use the macro `MAKINUM(n)'.
+
+ - Function: long num2long (SCM NUM, char *POS, char *S_CALLER)
+ - Function: unsigned long num2ulong (SCM NUM, char *POS, char
+ *S_CALLER)
+ - Function: unsigned short num2ushort (SCM NUM, char *POS, char
+ *S_CALLER)
+ - Function: unsigned char num2uchar (SCM NUM, char *POS, char
+ *S_CALLER)
+ These functions are used to check and convert `SCM' arguments to
+ the named C type. The first argument 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 `ASSERT' macro calls `wta' with
+ NUM and strings POS and S_CALLER. For a listing of useful
+ predefined POS macros, *Note C Macros::.
+
+ _Note:_ Inexact numbers are accepted only by `num2long' and
+ `num2ulong' (for when `SCM' is compiled without bignums). To
+ convert inexact numbers to exact numbers, *Note inexact->exact:
+ (r5rs)Numerical operations.
+
+ - Function: unsigned long scm_addr (SCM ARGS, char *S_NAME)
+ Returns a pointer (cast to an `unsigned long') to the storage
+ corresponding to the location accessed by
+ `aref(CAR(args),CDR(args))'. The string S_NAME is used in any
+ messages from error calls by `scm_addr'.
+
+ `scm_addr' is useful for performing C operations on strings or
+ other uniform arrays (*note Uniform Array::).
+
+ _Note:_ While you use a pointer returned from `scm_addr' you must
+ keep a pointer to the associated `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.
+
+ - Function: SCM makfrom0str (char *SRC)
+ - Function: SCM makfromstr (char *SRC, sizet LEN)
+ Return a newly allocated string `SCM' object copy of the
+ null-terminated string SRC or the string SRC of length LEN,
+ respectively.
+
+ - Function: SCM makfromstrs (int ARGC, char **ARGV)
+ Returns a newly allocated `SCM' list of strings corresponding to
+ the ARGC length array of null-terminated strings ARGV. If ARGV is
+ less than `0', ARGV is assumed to be `NULL' terminated.
+ `makfromstrs' is used by `scm_init_from_argv' to convert the
+ arguments SCM was called with to a `SCM' list which is the value
+ of SCM procedure calls to `program-arguments' (*note
+ program-arguments: SCM Session.).
+
+ - Function: char ** makargvfrmstrs (SCM ARGS, char *S_NAME)
+ Returns a `NULL' terminated list of null-terminated strings copied
+ from the `SCM' list of strings ARGS. The string S_NAME is used in
+ messages from error calls by `makargvfrmstrs'.
+
+ `makargvfrmstrs' is useful for constructing argument lists suitable
+ for passing to `main' functions.
+
+ - Function: void must_free_argv (char **ARGV)
+ Frees the storage allocated to create ARGV by a call to
+ `makargvfrmstrs'.
+
+
+File: scm.info, Node: Continuations, Next: Evaluation, Prev: Type Conversions, Up: Operations
+
+Continuations
+-------------
+
+The source files `continue.h' and `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 *Note call-with-current-continuation:
+(r5rs)Control features.
+
+The C constructs `jmp_buf', `setjmp', and `longjmp' implement escape
+continuations. On VAX and Cray platforms, the setjmp provided does not
+save all the registers. The source files `setjump.mar', `setjump.s',
+and `ugsetjump.s' provide implementations which do meet this criteria.
+
+SCM uses the names `jump_buf', `setjump', and `longjump' in lieu of
+`jmp_buf', `setjmp', and `longjmp' to prevent name and declaration
+conflicts.
+
+ - Data type: CONTINUATION jmpbuf length stkbse other parent
+ is a `typedef'ed structure holding all the information needed to
+ represent a continuation. The OTHER slot can be used to hold any
+ data the user wishes to put there by defining the macro
+ `CONTINUATION_OTHER'.
+
+ - Macro: SHORT_ALIGN
+ If `SHORT_ALIGN' is `#define'd (in `scmfig.h'), then the it is
+ assumed that pointers in the stack can be aligned on `short int'
+ boundaries.
+
+ - Data type: STACKITEM
+ is a pointer to objects of the size specified by `SHORT_ALIGN'
+ being `#define'd or not.
+
+ - Macro: CHEAP_CONTINUATIONS
+ If `CHEAP_CONTINUATIONS' is `#define'd (in `scmfig.h') each
+ `CONTINUATION' has size `sizeof CONTINUATION'. Otherwise, all but
+ "root" `CONTINUATION's have additional storage (immediately
+ following) to contain a copy of part of the stack.
+
+ _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
+ `CHEAP_CONTINUATIONS' in `scmfig.h'.
+
+ - Macro: STACK_GROWS_UP
+ Expresses which way the stack grows by its being `#define'd or not.
+
+ - Variable: long thrown_value
+ Gets set to the VALUE passed to `throw_to_continuation'.
+
+ - Function: long stack_size (STACKITEM *START)
+ Returns the number of units of size `STACKITEM' which fit between
+ START and the current top of stack. No check is done in this
+ routine to ensure that START is actually in the current stack
+ segment.
+
+ - Function: CONTINUATION * make_root_continuation (STACKITEM
+ *STACK_BASE)
+ Allocates (`malloc') storage for a `CONTINUATION' of the current
+ extent of stack. This newly allocated `CONTINUATION' is returned
+ if successful, `0' if not. After `make_root_continuation'
+ returns, the calling routine still needs to
+ `setjump(NEW_CONTINUATION->jmpbuf)' in order to complete the
+ capture of this continuation.
+
+ - Function: CONTINUATION * make_continuation (CONTINUATION
+ *PARENT_CONT)
+ Allocates storage for the current `CONTINUATION', copying (or
+ encapsulating) the stack state from `PARENT_CONT->stkbse' to the
+ current top of stack. The newly allocated `CONTINUATION' is
+ returned if successful, `0'q if not. After `make_continuation'
+ returns, the calling routine still needs to
+ `setjump(NEW_CONTINUATION->jmpbuf)' in order to complete the
+ capture of this continuation.
+
+ - Function: void free_continuation (CONTINUATION *CONT)
+ Frees the storage pointed to by CONT. Remember to free storage
+ pointed to by `CONT->other'.
+
+ - Function: void throw_to_continuation (CONTINUATION *CONT, long
+ VALUE, CONTINUATION *ROOT_CONT)
+ Sets `thrown_value' to VALUE and returns from the continuation
+ CONT.
+
+ If `CHEAP_CONTINUATIONS' is `#define'd, then
+ `throw_to_continuation' does `longjump(CONT->jmpbuf, val)'.
+
+ If `CHEAP_CONTINUATIONS' is not `#define'd, the CONTINUATION CONT
+ contains a copy of a portion of the C stack (whose bound must be
+ `CONT(ROOT_CONT)->stkbse'). Then:
+
+ * the stack is grown larger than the saved stack, if neccessary.
+
+ * the saved stack is copied back into it's original position.
+
+ * `longjump(CONT->jmpbuf, val)';
+
+
+File: scm.info, Node: Evaluation, Prev: Continuations, Up: Operations
+
+Evaluation
+----------
+
+SCM uses its type representations to speed evaluation. All of the
+`subr' types (*note Subr Cells::) are `tc7' types. Since the `tc7'
+field is in the low order bit position of the `CAR' it can be retrieved
+and dispatched on quickly by dereferencing the SCM pointer pointing to
+it and masking the result.
+
+All the SCM "Special Forms" get translated to immediate symbols
+(`isym') the first time they are encountered by the interpreter
+(`ceval'). The representation of these immediate symbols is engineered
+to occupy the same bits as `tc7'. All the `isym's occur only in the
+`CAR' of lists.
+
+If the `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 `ILOC' or `GLOC' (*note Immediates::).
+The codes for `ILOC' and `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,
+`ceval' need only retrieve and dispatch on the low order 7 bits of the
+`CAR' of that cell, regardless of whether that cell is a closure,
+header, or subr, or a cons containing `ILOC' or `GLOC'.
+
+In order to be able to convert a SCM symbol pointer to an immediate
+`ILOC' or `GLOC', the evaluator must be holding the pointer to the list
+in which that symbol pointer occurs. Turning this requirement to an
+advantage, `ceval' does not recursively call itself to evaluate symbols
+in lists; It instead calls the macro "EVALCAR". `EVALCAR' does symbol
+lookup and memoization for symbols, retrieval of values for `ILOC's and
+`GLOC's, returns other immediates, and otherwise recursively calls
+itself with the `CAR' of the list.
+
+`ceval' inlines evaluation (using `EVALCAR') of almost all procedure
+call arguments. When `ceval' needs to evaluate a list of more than
+length 3, the procedure `eval_args' is called. So `ceval' can be said
+to have one level lookahead. The avoidance of recursive invocations of
+`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
+`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 `evalcar'.
+
+ - Variable: symhash
+ Top level symbol values are stored in the `symhash' table.
+ `symhash' is an array of lists of `ISYM's and pairs of symbols and
+ values.
+
+ - 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 (`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.
+
+`ILOC's work up to a maximum depth of 4096 frames or 4096 identifiers
+in a frame. Radey Shouman added "FARLOC" to handle cases exceeding
+these limits. A `FARLOC' consists of a pair whose CAR is the immediate
+type `IM_FARLOC_CAR' or `IM_FARLOC_CDR', and whose CDR is a pair of
+INUMs specifying the frame and distance with a larger range than
+`ILOC's span.
+
+Adding `#define TEST_FARLOC' to `eval.c' causes `FARLOC's to be
+generated for all local identifiers; this is useful only for testing
+memoization.
+
+ - 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 `GLOC'. The low order bit is normally
+ reserved for GCmark; But, since references to variables in the
+ code always occur in the `CAR' position and the GCmark is in the
+ `CDR', there is no conflict.
+
+If the compile FLAG `CAUTIOUS' is #defined then the number of arguments
+is always checked for application of closures. If the compile FLAG
+`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 `ILOC' or
+`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 `ILOC' or `GLOC'.
+
+ - Macro: EVAL expression env
+ - Macro: SIDEVAL expression env
+ `EVAL' Returns the result of evaluating EXPRESSION in ENV.
+ `SIDEVAL' evaluates EXPRESSION in ENV when the value of the
+ expression is not used.
+
+ Both of these macros alter the list structure of EXPRESSION as it
+ is memoized and hence should be used only when it is known that
+ EXPRESSION will not be referenced again. The C function `eval' is
+ safe from this problem.
+
+ - Function: SCM eval (SCM EXPRESSION)
+ Returns the result of evaluating EXPRESSION in the top-level
+ environment. `eval' copies `expression' so that memoization does
+ not modify `expression'.
+
+
+File: scm.info, Node: Program Self-Knowledge, Next: Improvements To Make, Prev: Operations, Up: The Implementation
+
+Program Self-Knowledge
+======================
+
+* Menu:
+
+* File-System Habitat::
+* Executable Pathname::
+* Script Support::
+
+
+File: scm.info, Node: File-System Habitat, Next: Executable Pathname, Prev: Program Self-Knowledge, Up: Program Self-Knowledge
+
+File-System Habitat
+-------------------
+
+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.
+
+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.
+
+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.
+
+ Programs of the world unite! You have nothing to lose but loss
+ itself.
+
+The function `find_impl_file' in `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.
+
+ - Function: char * find_impl_file (char *EXEC_PATH, char
+ *GENERIC_NAME, char *INITNAME, char *SEP)
+ Given the pathname of this executable (EXEC_PATH), test for the
+ existence of INITNAME in the implementation-vicinity of this
+ program. Return a newly allocated string of the path if
+ successful, 0 if not. The SEP argument is a _null-terminated
+ string_ of the character used to separate directory components.
+
+ * 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.
+
+ * Another convention is to install the executables in a directory
+ named `bin', `BIN', `exe', or `EXE' and support files in a
+ directroy named `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
+ `/usr/local/bin/' and initialization file in `/usr/local/lib/'.
+
+ If the executable directory name matches, the peer directroy `lib'
+ is tested for INITNAME.
+
+ * Sometimes `lib' directories become too crowded. So we look in any
+ subdirectories of `lib' or `src' having the name (sans type suffix
+ such as `.EXE') of the program we are running. For example, the
+ executable might be `/usr/local/bin/foo' and initialization file
+ in `/usr/local/lib/foo/'.
+
+ * But the executable name may not be the usual program name; So also
+ look in any GENERIC_NAME subdirectories of `lib' or `src' peers.
+
+ * 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
+ GENERIC_NAME subdirectory. For example, the executable might be
+ `C:\foo\bar.exe' and the initialization file in `C:\foo\bar\'.
+
+
+File: scm.info, Node: Executable Pathname, Next: Script Support, Prev: File-System Habitat, Up: Program Self-Knowledge
+
+Executable Pathname
+-------------------
+
+For purposes of finding `Init5d6.scm', dumping an executable, and
+dynamic linking, a SCM session needs the pathname of its executable
+image.
+
+When a program is executed by MS-DOS, the full pathname of that
+executable is available in `argv[0]'. This value can be passed
+directly to `find_impl_file' (*note 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.
+
+ - Function: char * dld_find_executable (const char *COMMAND)
+ `dld_find_executable' returns the absolute path name of the file
+ that would be executed if COMMAND were given as a command. It
+ looks up the environment variable PATH, searches in each of the
+ directory listed for COMMAND, and returns the absolute path name
+ for the first occurrence. Thus, it is advisable to invoke
+ `dld_init' as:
+
+ main (int argc, char **argv)
+ {
+ ...
+ if (dld_init (dld_find_executable (argv[0]))) {
+ ...
+ }
+ ...
+ }
+
+ *Note:* If the current process is executed using the `execve'
+ call without passing the correct path name as argument 0,
+ `dld_find_executable (argv[0]) ' will also fail to locate the
+ executable file.
+
+ `dld_find_executable' returns zero if `command' is not found in
+ any of the directories listed in `PATH'.
+
+
+File: scm.info, Node: Script Support, Prev: Executable Pathname, Up: Program Self-Knowledge
+
+Script Support
+--------------
+
+Source code for these C functions is in the file `script.c'. *Note
+Scripting:: for a description of script argument processing.
+
+`script_find_executable' is only defined on unix systems.
+
+ - Function: char * script_find_executable (const char *NAME)
+ `script_find_executable' returns the path name of the executable
+ which is invoked by the script file NAME; NAME if it is a binary
+ executable (not a script); or 0 if NAME does not exist or is not
+ executable.
+
+ - Function: char ** script_process_argv (int ARGC; char **ARGV)
+ Given an "main" style argument vector ARGV and the number of
+ arguments, ARGC, `script_process_argv' returns a newly allocated
+ argument vector in which the second line of the script being
+ invoked is substituted for the corresponding meta-argument.
+
+ If the script does not have a meta-argument, or if the file named
+ by the argument following a meta-argument cannot be opened for
+ reading, then 0 is returned.
+
+ `script_process_argv' correctly processes argument vectors of
+ nested script invocations.
+
+ - Function: int script_count_argv (char **ARGV)
+ Returns the number of argument strings in ARGV.
+
+
+File: scm.info, Node: Improvements To Make, Prev: Program Self-Knowledge, Up: The Implementation
+
+Improvements To Make
+====================
+
+ * Allow users to set limits for `malloc()' storage.
+
+ * Prefix and make more uniform all C function, variable, and constant
+ names. Provide a file full of #define's to provide backward
+ compatability.
+
+ * `lgcd()' _needs_ to generate at most one bignum, but currently
+ generates more.
+
+ * `divide()' could use shifts instead of multiply and divide when
+ scaling.
+
+ * Currently, `dump'ing an executable does not preserve ports. When
+ loading a `dump'ed executable, disk files could be reopened to the
+ same file and position as they had when the executable was dumped.
+
+ * 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.
+
+ * In the quest for speed, there has been some discussion about a
+ "Forth" style Scheme interpreter.
+
+ 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 `GLOC' or `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 `CAR', `CDR', etc.
+ Since the actual operation code is localized in the
+ interpreter, it is much easier than uncompilation and then
+ recompilation to handle `(trace car)'; For instance a switch
+ gets set which tells the interpreter to instead always look
+ up the values of the associated symbols.
+
+
+* Menu:
+
+* Finishing Dynamic Linking::
+
+
+File: scm.info, Node: Finishing Dynamic Linking, Prev: Improvements To Make, Up: Improvements To Make
+
+Finishing Dynamic Linking
+-------------------------
+
+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.
+
+VMS
+...
+
+George Carrette (gjc@mitech.com) outlines how to dynamically link on
+VMS. There is already some code in `dynl.c' to do this, but someone
+with a VMS system needs to finish and debug it.
+
+ 1. Say you have this `main.c' program:
+
+ main()
+ {init_lisp();
+ lisp_repl();}
+
+ 2. and you have your lisp in files `repl.c', `gc.c', `eval.c' and
+ there are some toplevel non-static variables in use called
+ `the_heap', `the_environment', and some read-only toplevel
+ structures, such as `the_subr_table'.
+
+ $ LINK/SHARE=LISPRTL.EXE/DEBUG REPL.OBJ,GC.OBJ,EVAL.OBJ,LISPRTL.OPT/OPT
+
+ 3. where `LISPRTL.OPT' must contain at least this:
+
+ 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
+
+ _Notice:_ The "psect" (Program Section) attributes.
+ `LCL'
+ means to keep the name local to the shared library. You
+ almost always want to do that for a good clean library.
+
+ `SHR,NOWRT'
+ means shared-read-only. Which is the default for code, and
+ is also good for efficiency of some data structures.
+
+ `NOSHR,LCL'
+ is what you want for everything else.
+
+ 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,
+
+ $SEARCH/OUT=LISPRTL.LOSERS LISPRTL.MAP ", SHR,NOEXE, RD, WRT"
+
+ 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.
+
+ 4. Now MAIN.EXE would be linked thusly:
+
+ $ DEFINE LISPRTL USER$DISK:[JAFFER]LISPRTL.EXE
+
+ $LINK MAIN.OBJ,SYS$INPUT:/OPT
+ SYS$LIBRARY:VAXCRTL/SHARE
+ LISPRTL/SHARE
+
+ Note the definition of the `LISPRTL' logical name. Without such a
+ definition you will need to copy `LISPRTL.EXE' over to
+ `SYS$SHARE:' (aka `SYS$LIBRARY:') in order to invoke the main
+ program once it is linked.
+
+ 5. Now say you have a file of optional subrs, `MYSUBRS.C'. And there
+ is a routine `INIT_MYSUBRS' that must be called before using it.
+
+ $ CC MYSUBRS.C
+ $ LINK/SHARE=MYSUBRS.EXE MYSUBRS.OBJ,SYS$INPUT:/OPT
+ SYS$LIBRARY:VAXCRTL/SHARE
+ LISPRTL/SHARE
+ UNIVERSAL=INIT_MYSUBRS
+
+ Ok. Another hint is that you can avoid having to add the `PSECT'
+ declaration of `NOSHR,LCL' by declaring variables `status' in the
+ C language source. That works great for most things.
+
+ 6. Then the dynamic loader would have to do this:
+
+ {void (*init_fcn)();
+ long retval;
+ retval = lib$find_image_symbol("MYSUBRS","INIT_MYSUBRS",&init_fcn,
+ "SYS$DISK:[].EXE");
+ if (retval != SS$_NORMAL) error(...);
+ (*init_fcn)();}
+
+ But of course all string arguments must be `(struct dsc$descriptor
+ *)' and the last argument is optional if `MYSUBRS' is defined as a
+ logical name or if `MYSUBRS.EXE' has been copied over to
+ `SYS$SHARE'. The other consideration is that you will want to turn
+ off <C-c> or other interrupt handling while you are inside most
+ `lib$' calls.
+
+ As far as the generation of all the `UNIVERSAL=...' declarations.
+ Well, you could do well to have that automatically generated from
+ the public `LISPRTL.H' file, of course.
+
+ VMS has a good manual called the `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 `LISPRTL' you
+ probably don't need that hair.
+
+ One fancier option that is useful under VMS for `LISPLIB.EXE' is to
+ define all your exported procedures through an "call vector"
+ instead of having them just be pointers into random places in the
+ image, which is what you get by using `UNIVERSAL'.
+
+ If you set up the call vector thing correctly it will allow you to
+ modify and relink `LISPLIB.EXE' without having to relink programs
+ that have been linked against it.
+
+Windows NT
+..........
+
+George Carrette (gjc@mitech.com) outlines how to dynamically link on
+Windows NT:
+
+ * 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)
+
+ 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)
+
+ * The `LISPDEF.DEF' file has this:
+
+ LIBRARY lisplib
+ EXPORT
+ init_lisp
+ init_repl
+
+ * And `MAIN.EXE' using:
+
+ CLINK = $(link) $(ldebug) $(conflags) -out:$*.exe $** $(conlibsdll)
+
+ MAIN.EXE : MAIN.OBJ LISPLIB.LIB
+ $(CLINK)
+
+ * And `MYSUBRS.DLL' is produced using:
+
+ 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)
+
+ * Where `MYSUBRS.DEF' has
+
+ LIBRARY mysubrs
+ EXPORT
+ INIT_MYSUBRS
+
+ * And the dynamic loader looks something like this, calling the two
+ procedures `LoadLibrary' and `GetProcAddress'.
+
+ 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);}
+
+ * _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.
+
+ * _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.
+
+
+File: scm.info, Node: Index, Prev: The Implementation, Up: Top
+
+Procedure and Macro Index
+*************************
+
+This is an alphabetical list of all the procedures and macros in SCM.
+
+* Menu:
+
+* #!: Unix Scheme Scripts.
+* #': Syntax Extensions.
+* #+: Syntax Extensions.
+* #-: Syntax Extensions.
+* #.: Syntax Extensions.
+* #;text-till-end-of-line: Syntax Extensions.
+* #\token: Syntax Extensions.
+* #|: Syntax Extensions.
+* $abs: Numeric.
+* $acos: Numeric.
+* $acosh: Numeric.
+* $asin: Numeric.
+* $asinh: Numeric.
+* $atan: Numeric.
+* $atan2: Numeric.
+* $atanh: Numeric.
+* $cos: Numeric.
+* $cosh: Numeric.
+* $exp: Numeric.
+* $expt: Numeric.
+* $log: Numeric.
+* $log10: Numeric.
+* $sin: Numeric.
+* $sinh: Numeric.
+* $sqrt: Numeric.
+* $tan: Numeric.
+* $tanh: Numeric.
+* -: SCM Options.
+* ---: SCM Options.
+* ---c-source-files=: Build Options.
+* ---compiler-options=: Build Options.
+* ---defines=: Build Options.
+* ---features=: Build Options.
+* ---help: SCM Options.
+* ---initialization=: Build Options.
+* ---libraries=: Build Options.
+* ---linker-options=: Build Options.
+* ---no-init-file: SCM Options.
+* ---object-files=: Build Options.
+* ---outname=: Build Options.
+* ---platform=: Build Options.
+* ---scheme-initial=: Build Options.
+* ---type=: Build Options.
+* ---version: SCM Options.
+* --batch-dialect=: Build Options.
+* --script-name=: Build Options.
+* -a: SCM Options.
+* -b: SCM Options.
+* -c <1>: SCM Options.
+* -c: Build Options.
+* -d: SCM Options.
+* -D: Build Options.
+* -e: SCM Options.
+* -f: SCM Options.
+* -F: Build Options.
+* -h <1>: SCM Options.
+* -h: Build Options.
+* -i <1>: SCM Options.
+* -i: Build Options.
+* -j: Build Options.
+* -l <1>: SCM Options.
+* -l: Build Options.
+* -m: SCM Options.
+* -no-init-file: SCM Options.
+* -o <1>: SCM Options.
+* -o: Build Options.
+* -p <1>: SCM Options.
+* -p: Build Options.
+* -q: SCM Options.
+* -r: SCM Options.
+* -s <1>: SCM Options.
+* -s: Build Options.
+* -t: Build Options.
+* -u: SCM Options.
+* -v: SCM Options.
+* -w: Build Options.
+* @apply: Low Level Syntactic Hooks.
+* @copy-tree: Miscellaneous Procedures.
+* @macroexpand1: Syntactic Hooks for Hygienic Macros.
+* _exclusive: Files and Ports.
+* _ionbf: Files and Ports.
+* _tracked: Files and Ports.
+* abort: Internal State.
+* access: I/O-Extensions.
+* acct: Unix Extensions.
+* acons: Miscellaneous Procedures.
+* acosh: Numeric.
+* add-alias: Configure Module Catalog.
+* add-finalizer: Interrupts.
+* add-link: Configure Module Catalog.
+* add-source: Configure Module Catalog.
+* alarm: Interrupts.
+* alarm-interrupt: Interrupts.
+* ALLOW_INTS: Signals.
+* alrm_signal: Signals.
+* ARGC: Cells.
+* arithmetic-error: Interrupts.
+* array->list: Conventional Arrays.
+* array-contents: Conventional Arrays.
+* array-copy!: Conventional Arrays.
+* array-dimensions: Conventional Arrays.
+* array-equal?: Conventional Arrays.
+* array-fill!: Conventional Arrays.
+* array-for-each: Array Mapping.
+* array-in-bounds?: Conventional Arrays.
+* array-index-map!: Array Mapping.
+* array-map!: Array Mapping.
+* array-prototype: Uniform Array.
+* array-rank: Conventional Arrays.
+* array-ref: Conventional Arrays.
+* array-set!: Conventional Arrays.
+* array-shape: Conventional Arrays.
+* array? <1>: Uniform Array.
+* array?: Conventional Arrays.
+* asinh: Numeric.
+* ASRTGO: C Macros.
+* ASSERT: C Macros.
+* atanh: Numeric.
+* bit-count: Bit Vectors.
+* bit-count*: Bit Vectors.
+* bit-invert!: Bit Vectors.
+* bit-position: Bit Vectors.
+* bit-set*!: Bit Vectors.
+* boot-tail <1>: Dump.
+* boot-tail: SCM Session.
+* box: Curses Miscellany.
+* broken-pipe: Posix Extensions.
+* call-with-outputs: Files and Ports.
+* CAR: Cells.
+* cbreak: Terminal Mode Setting.
+* CCLO_LENGTH: Header Cells.
+* CDR: Cells.
+* char: Type Conversions.
+* char-ready: Files and Ports.
+* char-ready? <1>: Socket.
+* char-ready?: Files and Ports.
+* CHARS: Header Cells.
+* chdir: I/O-Extensions.
+* CHEAP_CONTINUATIONS: Continuations.
+* chmod: I/O-Extensions.
+* chown: Posix Extensions.
+* clearok: Output Options Setting.
+* close-port <1>: Window Manipulation.
+* close-port <2>: Posix Extensions.
+* close-port: Files and Ports.
+* closedir: I/O-Extensions.
+* CLOSEDP: Ptob Cells.
+* CLOSUREP: Cells.
+* CODE: Cells.
+* comment: Syntax Extensions.
+* CONSP: Cells.
+* copy-tree: Miscellaneous Procedures.
+* cosh: Numeric.
+* could-not-open: Interrupts.
+* current-error-port: Files and Ports.
+* current-input-port: Files and Ports.
+* current-time: Time.
+* default-input-port: Line Editing.
+* default-output-port: Line Editing.
+* defconst: Syntax Extensions.
+* DEFER_INTS: Signals.
+* defined?: Syntax Extensions.
+* defmacro: Syntax Extensions.
+* defsyntax: Low Level Syntactic Hooks.
+* defvar: Syntax Extensions.
+* dimensions->uniform-array: Uniform Array.
+* directory-for-each: I/O-Extensions.
+* display: Output.
+* dld_find_executable: Executable Pathname.
+* dump: Dump.
+* duplicate-port: I/O-Extensions.
+* dyn:call: Dynamic Linking.
+* dyn:link: Dynamic Linking.
+* dyn:main-call: Dynamic Linking.
+* dyn:unlink: Dynamic Linking.
+* echo: Terminal Mode Setting.
+* ed: Editing Scheme Code.
+* enclose-array: Conventional Arrays.
+* end-of-program: Interrupts.
+* endwin: Curses.
+* ENV: Cells.
+* errno: Errors.
+* error: Errors.
+* eval: Evaluation.
+* EVAL: Evaluation.
+* eval: Miscellaneous Procedures.
+* eval-string: Miscellaneous Procedures.
+* exec-self: Internal State.
+* execl: I/O-Extensions.
+* execlp: I/O-Extensions.
+* execpath: Internal State.
+* execv: I/O-Extensions.
+* execvp: I/O-Extensions.
+* exit: SCM Session.
+* extended-environment: Syntactic Hooks for Hygienic Macros.
+* file-position: I/O-Extensions.
+* file-set-position: I/O-Extensions.
+* fileno: I/O-Extensions.
+* final_scm: Embedding SCM.
+* find_impl_file: File-System Habitat.
+* force-output: Window Manipulation.
+* fork: Posix Extensions.
+* FPORTP: Ptob Cells.
+* free_continuation: Continuations.
+* freshline: Files and Ports.
+* gc: Internal State.
+* gc-hook: Interrupts.
+* gc_mark: Marking Cells.
+* GCCDR: Marking Cells.
+* GCTYP16: Marking Cells.
+* gentemp: Syntax Extensions.
+* get-internal-real-time: Time.
+* get-internal-run-time: Time.
+* getcwd: I/O-Extensions.
+* getegid: Posix Extensions.
+* geteuid: Posix Extensions.
+* getgid: Posix Extensions.
+* getgr: Posix Extensions.
+* getgroups: Posix Extensions.
+* gethost: Host Data.
+* getlogin: Posix Extensions.
+* getnet: Host Data.
+* getpeername: Internet Addresses and Socket Names.
+* getpid: I/O-Extensions.
+* getppid: Posix Extensions.
+* getproto: Host Data.
+* getpw: Posix Extensions.
+* getserv: Host Data.
+* getsockname: Internet Addresses and Socket Names.
+* getuid: Posix Extensions.
+* getyx: Input.
+* hang-up: Interrupts.
+* ICHR: Immediates.
+* ICHRP: Immediates.
+* identifier->symbol: Syntactic Hooks for Hygienic Macros.
+* identifier-equal?: Syntactic Hooks for Hygienic Macros.
+* identifier?: Syntactic Hooks for Hygienic Macros.
+* idlok: Output Options Setting.
+* IFLAGP: Immediates.
+* IMP: Immediates.
+* inet:address->string: Internet Addresses and Socket Names.
+* inet:local-network-address: Internet Addresses and Socket Names.
+* inet:make-address: Internet Addresses and Socket Names.
+* inet:network: Internet Addresses and Socket Names.
+* inet:string->address: Internet Addresses and Socket Names.
+* init_buf0: Embedding SCM.
+* init_sbrk: Embedding SCM.
+* init_signals <1>: Embedding SCM.
+* init_signals: Signals.
+* initscr: Curses.
+* INPORTP: Ptob Cells.
+* int_signal: Signals.
+* integer->line-number: Line Numbers.
+* INUM: Immediates.
+* INUMP: Immediates.
+* isatty?: Files and Ports.
+* ISYMCHARS: Immediates.
+* ISYMNUM: Immediates.
+* ISYMP: Immediates.
+* kill: Posix Extensions.
+* leaveok: Output Options Setting.
+* LENGTH: Header Cells.
+* line-editing: Line Editing.
+* line-number: Miscellaneous Procedures.
+* line-number->integer: Line Numbers.
+* line-number?: Line Numbers.
+* link: Posix Extensions.
+* list->uniform-array: Uniform Array.
+* list-file: Miscellaneous Procedures.
+* load: Dynamic Linking.
+* load-string: Miscellaneous Procedures.
+* logaref: Uniform Array.
+* logaset!: Uniform Array.
+* long: Type Conversions.
+* long2num: Type Conversions.
+* lstat: Unix Extensions.
+* macroexpand: Syntax Extensions.
+* macroexpand-1: Syntax Extensions.
+* main: Embedding SCM.
+* makargvfrmstrs: Type Conversions.
+* makcclo: Header Cells.
+* make-arbiter: Process Synchronization.
+* make-array: Conventional Arrays.
+* make-edited-line-port: Line Editing.
+* make-exchanger: Process Synchronization.
+* make-shared-array: Conventional Arrays.
+* make-soft-port: Soft Ports.
+* make-stream-socket: Socket.
+* make-stream-socketpair: Socket.
+* make_continuation: Continuations.
+* make_gsubr: Defining Subrs.
+* make_root_continuation: Continuations.
+* makfrom0str: Type Conversions.
+* makfromstr: Type Conversions.
+* makfromstrs: Type Conversions.
+* MAKICHR: Immediates.
+* MAKIFLAG: Immediates.
+* MAKINUM: Immediates.
+* MAKISYM: Immediates.
+* MAKSPCSYM: Immediates.
+* mark_locations: Marking Cells.
+* milli-alarm: Interrupts.
+* mkdir: I/O-Extensions.
+* mknod: Unix Extensions.
+* must_free: Allocating memory.
+* must_free_argv: Type Conversions.
+* must_malloc: Allocating memory.
+* must_malloc_cell: Allocating memory.
+* must_realloc: Allocating memory.
+* must_realloc_cell: Allocating memory.
+* mvwin: Window Manipulation.
+* NCONSP: Cells.
+* NEWCELL: Cells.
+* newwin: Window Manipulation.
+* nice: Unix Extensions.
+* NIMP: Immediates.
+* NINUMP: Immediates.
+* nl: Terminal Mode Setting.
+* nocbreak: Terminal Mode Setting.
+* nodelay: Output Options Setting.
+* noecho: Terminal Mode Setting.
+* nonl: Terminal Mode Setting.
+* noraw: Terminal Mode Setting.
+* NSTRINGP: Header Cells.
+* num2long: Type Conversions.
+* NVECTORP: Header Cells.
+* open-file: Files and Ports.
+* open-input-pipe: Posix Extensions.
+* open-output-pipe: Posix Extensions.
+* open-pipe: Posix Extensions.
+* open-ports: Files and Ports.
+* opendir: I/O-Extensions.
+* OPENP: Ptob Cells.
+* OPFPORTP: Ptob Cells.
+* OPINFPORTP: Ptob Cells.
+* OPINPORTP: Ptob Cells.
+* OPOUTFPORTP: Ptob Cells.
+* OPOUTPORTP: Ptob Cells.
+* OPPORTP: Ptob Cells.
+* out-of-storage: Interrupts.
+* OUTPORTP: Ptob Cells.
+* overlay: Window Manipulation.
+* overwrite: Window Manipulation.
+* perror: Errors.
+* pi*: Numeric.
+* pi/: Numeric.
+* pipe: Posix Extensions.
+* port-closed?: Files and Ports.
+* port-column: Miscellaneous Procedures.
+* port-filename: Miscellaneous Procedures.
+* port-line: Miscellaneous Procedures.
+* port-type: Files and Ports.
+* PORTP: Ptob Cells.
+* print <1>: Miscellaneous Procedures.
+* print: Debugging Scheme Code.
+* print-args: Debugging Scheme Code.
+* procedure->identifier-macro: Low Level Syntactic Hooks.
+* procedure->macro: Low Level Syntactic Hooks.
+* procedure->memoizing-macro: Low Level Syntactic Hooks.
+* procedure->syntax: Low Level Syntactic Hooks.
+* procedure-documentation: Syntax Extensions.
+* profile-alarm: Interrupts.
+* profile-alarm-interrupt: Interrupts.
+* program-arguments: SCM Session.
+* putenv: I/O-Extensions.
+* qase: Syntax Extensions.
+* quit: SCM Session.
+* raw: Terminal Mode Setting.
+* read-char <1>: Input.
+* read-char: Files and Ports.
+* read-numbered: Line Numbers.
+* read:sharp: Low Level Syntactic Hooks.
+* read:sharp-char: Low Level Syntactic Hooks.
+* readdir: I/O-Extensions.
+* readlink: Unix Extensions.
+* record-printer-set!: Records.
+* redirect-port!: I/O-Extensions.
+* refresh: Window Manipulation.
+* regcomp: Regular Expression Pattern Matching.
+* regerror: Regular Expression Pattern Matching.
+* regexec: Regular Expression Pattern Matching.
+* regmatch: Regular Expression Pattern Matching.
+* regmatch?: Regular Expression Pattern Matching.
+* regmatchv: Regular Expression Pattern Matching.
+* regsearch: Regular Expression Pattern Matching.
+* regsearchv: Regular Expression Pattern Matching.
+* release-arbiter: Process Synchronization.
+* rename-file: I/O-Extensions.
+* renamed-identifier: Syntactic Hooks for Hygienic Macros.
+* renaming-transformer: Syntactic Hooks for Hygienic Macros.
+* reopen-file: I/O-Extensions.
+* require: Dynamic Linking.
+* resetty: Terminal Mode Setting.
+* restart: Internal State.
+* restore_signals: Embedding SCM.
+* rewinddir: I/O-Extensions.
+* rmdir: I/O-Extensions.
+* room: Internal State.
+* savetty: Terminal Mode Setting.
+* scalar->array: Array Mapping.
+* scm_evstr: Callbacks.
+* scm_find_execpath: Embedding SCM.
+* scm_find_implpath: Embedding SCM.
+* scm_init_from_argv: Embedding SCM.
+* scm_ldfile: Callbacks.
+* scm_ldprog: Callbacks.
+* scm_ldstr: Callbacks.
+* scm_top_level: Embedding SCM.
+* script_count_argv: Script Support.
+* script_find_executable: Script Support.
+* script_process_argv: Script Support.
+* scroll: Output.
+* scrollok: Output Options Setting.
+* serial-array-copy!: Conventional Arrays.
+* serial-array-map!: Array Mapping.
+* set!: Syntax Extensions.
+* setegid: Posix Extensions.
+* seteuid: Posix Extensions.
+* setgid: Posix Extensions.
+* setgrent: Posix Extensions.
+* sethostent: Host Data.
+* setnetent: Host Data.
+* setprotoent: Host Data.
+* setpwent: Posix Extensions.
+* setservent: Host Data.
+* setuid: Posix Extensions.
+* short: Type Conversions.
+* SHORT_ALIGN: Continuations.
+* SIDEVAL: Evaluation.
+* sinh: Numeric.
+* socket-name:address: Internet Addresses and Socket Names.
+* socket-name:family: Internet Addresses and Socket Names.
+* socket-name:port-number: Internet Addresses and Socket Names.
+* socket:accept: Socket.
+* socket:bind: Socket.
+* socket:connect: Socket.
+* socket:listen: Socket.
+* socket:shutdown: Socket.
+* stack-trace: Errors.
+* STACK_GROWS_UP: Continuations.
+* stack_size: Continuations.
+* stat: I/O-Extensions.
+* STREAM: Ptob Cells.
+* string-edit: Regular Expression Pattern Matching.
+* string-split: Regular Expression Pattern Matching.
+* string-splitv: Regular Expression Pattern Matching.
+* STRINGP: Header Cells.
+* subwin: Window Manipulation.
+* SYMBOLP: Header Cells.
+* symlink: Unix Extensions.
+* sync: Unix Extensions.
+* syntax-quote: Syntactic Hooks for Hygienic Macros.
+* syntax-rules: Syntax Extensions.
+* tanh: Numeric.
+* terms: Miscellaneous Procedures.
+* the-macro: Syntactic Hooks for Hygienic Macros.
+* throw_to_continuation: Continuations.
+* ticks: Interrupts.
+* ticks-interrupt: Interrupts.
+* touchline: Window Manipulation.
+* touchwin: Window Manipulation.
+* trace: Debugging Scheme Code.
+* transpose-array: Conventional Arrays.
+* try-arbiter: Process Synchronization.
+* try-create-file: I/O-Extensions.
+* try-load <1>: Line Numbers.
+* try-load: Miscellaneous Procedures.
+* try-open-file: Files and Ports.
+* ttyname: Posix Extensions.
+* TYP16: Cells.
+* TYP3: Cells.
+* TYP7: Cells.
+* UCHARS: Header Cells.
+* ulong2num: Type Conversions.
+* umask: I/O-Extensions.
+* uname: Posix Extensions.
+* unctrl: Curses Miscellany.
+* uniform-array-read!: Uniform Array.
+* uniform-array-write: Uniform Array.
+* uniform-vector-fill!: Uniform Array.
+* untrace: Debugging Scheme Code.
+* user-interrupt: Interrupts.
+* usr:lib: Dynamic Linking.
+* utime: I/O-Extensions.
+* vector-set-length!: Miscellaneous Procedures.
+* VECTORP: Header Cells.
+* VELTS: Header Cells.
+* verbose: Internal State.
+* virtual-alarm: Interrupts.
+* virtual-alarm-interrupt: Interrupts.
+* vms-debug: SCM Session.
+* void: Sweeping the Heap.
+* wadd: Output.
+* wait-for-input: Files and Ports.
+* waitpid: Posix Extensions.
+* warn: Errors.
+* wclear: Output.
+* wclrtobot: Output.
+* wclrtoeol: Output.
+* wdelch: Output.
+* wdeleteln: Output.
+* werase: Output.
+* winch: Input.
+* winsch: Output.
+* winsertln: Output.
+* with-error-to-file: Files and Ports.
+* with-error-to-port: Files and Ports.
+* with-input-from-port: Files and Ports.
+* with-output-to-port: Files and Ports.
+* wmove: Window Manipulation.
+* wstandend: Curses Miscellany.
+* wstandout: Curses Miscellany.
+* x:lib: Dynamic Linking.
+
+Variable Index
+**************
+
+This is an alphabetical list of all the global variables in SCM.
+
+* Menu:
+
+* $pi: Numeric.
+* *argv*: SCM Variables.
+* *execpath: Embedding SCM.
+* *interactive* <1>: Internal State.
+* *interactive*: SCM Variables.
+* *load-pathname*: Miscellaneous Procedures.
+* *load-reader*: Line Numbers.
+* *scm-version*: Internal State.
+* *slib-load-reader*: Line Numbers.
+* *syntax-rules*: SCM Variables.
+* af_inet: Host Data.
+* af_unix: Host Data.
+* BOOL_F: Immediates.
+* BOOL_T: Immediates.
+* EDITOR: SCM Variables.
+* EOF_VAL: Immediates.
+* EOL: Immediates.
+* errobj: Errors.
+* HOME: SCM Variables.
+* internal-time-units-per-second: Time.
+* INUM0: Immediates.
+* isymnames: Immediates.
+* most-negative-fixnum: Numeric.
+* most-positive-fixnum: Numeric.
+* NUM_ISPCSYM: Immediates.
+* NUM_ISYMS: Immediates.
+* open_both: Files and Ports.
+* open_read: Files and Ports.
+* open_write: Files and Ports.
+* pi: Numeric.
+* SCHEME_LIBRARY_PATH: SCM Variables.
+* SCM_INIT_PATH: SCM Variables.
+* symhash: Evaluation.
+* thrown_value: Continuations.
+* UNDEFINED: Immediates.
+* UNSPECIFIED: Immediates.
+
+Type Index
+**********
+
+This is an alphabetical list of data types and feature names in SCM.
+
+* Menu:
+
+* #! <1>: MS-DOS Compatible Scripts.
+* #!: Unix Scheme Scripts.
+* array-for-each: Array Mapping.
+* CELLPTR: Immediates.
+* CONTINUATION: Continuations.
+* curses: Dynamic Linking.
+* dump: Dump.
+* FARLOC: Evaluation.
+* GLOC: Evaluation.
+* gloc: Immediates.
+* i/o-extensions: Socket.
+* ichr: Immediates.
+* iflags: Immediates.
+* ILOC: Evaluation.
+* iloc: Immediates.
+* inum: Immediates.
+* ispcsym: Immediates.
+* isym: Immediates.
+* meta-argument <1>: Script Support.
+* meta-argument: Unix Scheme Scripts.
+* ptob: Ptob Cells.
+* regex: Dynamic Linking.
+* rev2-procedures: Dynamic Linking.
+* rev3-procedures: Dynamic Linking.
+* Scheme Script <1>: MS-DOS Compatible Scripts.
+* Scheme Script: Unix Scheme Scripts.
+* Scheme-Script <1>: MS-DOS Compatible Scripts.
+* Scheme-Script: Unix Scheme Scripts.
+* smob: Smob Cells.
+* socket: Socket.
+* spare: Header Cells.
+* STACKITEM: Continuations.
+* tc16_arbiter: Smob Cells.
+* tc16_array: Smob Cells.
+* tc16_bigneg: Smob Cells.
+* tc16_bigpos: Smob Cells.
+* tc16_flo: Smob Cells.
+* tc16_inpipe: Ptob Cells.
+* tc16_inport: Ptob Cells.
+* tc16_ioport: Ptob Cells.
+* tc16_macro: Smob Cells.
+* tc16_outpipe: Ptob Cells.
+* tc16_outport: Ptob Cells.
+* tc16_promise: Smob Cells.
+* tc16_sfport: Ptob Cells.
+* tc16_strport: Ptob Cells.
+* tc3_closure: Cells.
+* tc3_cons: Cells.
+* tc7_asubr: Subr Cells.
+* tc7_bvect: Header Cells.
+* tc7_contin: Header Cells.
+* tc7_cvect: Header Cells.
+* tc7_cxr: Subr Cells.
+* tc7_dvect: Header Cells.
+* tc7_fvect: Header Cells.
+* tc7_ivect: Header Cells.
+* tc7_lsubr: Subr Cells.
+* tc7_lsubr_2: Subr Cells.
+* tc7_msymbol: Header Cells.
+* tc7_rpsubr: Subr Cells.
+* tc7_specfun: Header Cells.
+* tc7_ssymbol: Header Cells.
+* tc7_string: Header Cells.
+* tc7_subr_0: Subr Cells.
+* tc7_subr_1: Subr Cells.
+* tc7_subr_1o: Subr Cells.
+* tc7_subr_2: Subr Cells.
+* tc7_subr_2o: Subr Cells.
+* tc7_subr_3: Subr Cells.
+* tc7_svect: Header Cells.
+* tc7_uvect: Header Cells.
+* tc7_vector: Header Cells.
+* tc_dblc: Smob Cells.
+* tc_dblr: Smob Cells.
+* tc_free_cell: Smob Cells.
+* turtle-graphics: Dynamic Linking.
+* unexec: Dump.
+
+This is an alphabetical list of concepts introduced in this manual.
+
+Concept Index
+*************
+
+* Menu:
+
+* !#: MS-DOS Compatible Scripts.
+* !#.exe: MS-DOS Compatible Scripts.
+* #!: MS-DOS Compatible Scripts.
+* #!.bat: MS-DOS Compatible Scripts.
+* array <1>: Conventional Arrays.
+* array: Build Options.
+* array-for-each: Build Options.
+* arrays: Build Options.
+* bignums: Build Options.
+* callbacks: Callbacks.
+* careful-interrupt-masking: Build Options.
+* cautious: Build Options.
+* cheap-continuations: Build Options.
+* compiled-closure: Build Options.
+* continuations: Continuations.
+* curses: Build Options.
+* debug: Build Options.
+* documentation string: Syntax Extensions.
+* dump: Build Options.
+* dynamic-linking: Build Options.
+* ecache: Memory Management for Environments.
+* edit-line: Build Options.
+* Embedding SCM: Embedding SCM.
+* engineering-notation: Build Options.
+* environments: Memory Management for Environments.
+* exchanger: Process Synchronization.
+* Exrename: Bibliography.
+* Extending Scm: Compiling and Linking Custom Files.
+* foo.c: Compiling and Linking Custom Files.
+* generalized-c-arguments: Build Options.
+* graphics: Packages.
+* hobbit: Packages.
+* i/o-extensions: Build Options.
+* IEEE: Bibliography.
+* inexact: Build Options.
+* JACAL: Bibliography.
+* lit: Build Options.
+* macro: Build Options.
+* memory management: Memory Management for Environments.
+* mysql: Build Options.
+* no-heap-shrink: Build Options.
+* NO_ENV_CACHE: Memory Management for Environments.
+* none: Build Options.
+* posix: Build Options.
+* R4RS: Bibliography.
+* R5RS: Bibliography.
+* reckless: Build Options.
+* record: Build Options.
+* regex: Build Options.
+* rev2-procedures: Build Options.
+* SchemePrimer: Bibliography.
+* SICP: Build Options.
+* sicp: Build Options.
+* SICP: Bibliography.
+* signals: Signals.
+* Simply: Bibliography.
+* single-precision-only: Build Options.
+* SLIB: Bibliography.
+* socket: Build Options.
+* stack-limit: Build Options.
+* tick-interrupts: Build Options.
+* turtlegr: Build Options.
+* unix: Build Options.
+* windows: Build Options.
+* X: Packages.
+* x <1>: Packages.
+* x: Build Options.
+* xlib: Packages.
+* Xlib: Packages.
+* xlib: Build Options.
+* xlibscm: Packages.
+* Xlibscm: Packages.
+
+
+
+Tag Table:
+Node: Top203
+Node: Overview1426
+Node: SCM Features1737
+Node: SCM Authors3749
+Node: Copying4645
+Node: Bibliography7730
+Node: Installing SCM9598
+Node: Making SCM10113
+Node: SLIB11030
+Node: Building SCM12945
+Node: Invoking Build13519
+Node: Build Options15793
+Node: Compiling and Linking Custom Files27939
+Node: Installing Dynamic Linking29902
+Node: Configure Module Catalog31686
+Node: Saving Images33683
+Node: Automatic C Preprocessor Definitions34358
+Node: Problems Compiling37629
+Node: Problems Linking39282
+Node: Problems Running39547
+Node: Testing41622
+Node: Reporting Problems44659
+Node: Operational Features45504
+Node: Invoking SCM45868
+Node: SCM Options47473
+Node: Invocation Examples51745
+Node: SCM Variables52697
+Node: SCM Session54127
+Node: Editing Scheme Code55465
+Node: Debugging Scheme Code57608
+Node: Errors61231
+Node: Memoized Expressions65459
+Node: Internal State67815
+Node: Scripting70895
+Node: Unix Scheme Scripts71189
+Node: MS-DOS Compatible Scripts74401
+Node: Unix Shell Scripts76213
+Node: The Language78403
+Node: Standards Compliance78995
+Node: Miscellaneous Procedures81409
+Node: Time84509
+Node: Interrupts85503
+Node: Process Synchronization90581
+Node: Files and Ports92118
+Node: Line Numbers97992
+Node: Soft Ports100234
+Node: Syntax Extensions102032
+Node: Low Level Syntactic Hooks111007
+Node: Syntactic Hooks for Hygienic Macros116212
+Node: Packages123186
+Node: Dynamic Linking123988
+Node: Dump128597
+Node: Numeric132606
+Node: Arrays134333
+Node: Conventional Arrays134543
+Node: Array Mapping141171
+Node: Uniform Array143397
+Node: Bit Vectors148645
+Node: Records149910
+Node: I/O-Extensions150773
+Node: Posix Extensions159362
+Node: Unix Extensions169048
+Node: Regular Expression Pattern Matching170950
+Node: Line Editing174904
+Node: Curses176250
+Node: Output Options Setting177173
+Node: Terminal Mode Setting179822
+Node: Window Manipulation182900
+Node: Output186360
+Node: Input189986
+Node: Curses Miscellany191013
+Node: Sockets192437
+Node: Host Data192761
+Node: Internet Addresses and Socket Names195909
+Node: Socket197443
+Node: The Implementation204680
+Node: Data Types204939
+Node: Immediates205760
+Node: Cells210096
+Node: Header Cells212188
+Node: Subr Cells215229
+Node: Ptob Cells217447
+Node: Smob Cells218986
+Node: Data Type Representations222182
+Node: Operations226835
+Node: Garbage Collection227421
+Node: Marking Cells228042
+Node: Sweeping the Heap230144
+Node: Memory Management for Environments231089
+Node: Signals235646
+Node: C Macros237190
+Node: Changing Scm238313
+Node: Defining Subrs242572
+Node: Defining Smobs244449
+Node: Defining Ptobs247495
+Node: Allocating memory248672
+Node: Embedding SCM250985
+Node: Callbacks258587
+Node: Type Conversions260330
+Node: Continuations263886
+Node: Evaluation268100
+Node: Program Self-Knowledge273263
+Node: File-System Habitat273509
+Node: Executable Pathname277109
+Node: Script Support278713
+Node: Improvements To Make280031
+Node: Finishing Dynamic Linking282063
+Node: Index289809
+
+End Tag Table
diff --git a/setjump.h b/setjump.h
index dfacb84..155cd53 100644
--- a/setjump.h
+++ b/setjump.h
@@ -147,3 +147,7 @@ typedef struct safeport {
} safeport;
#define SAFEP_JMPBUF(sfp) (((safeport *)STREAM(sfp))->jmpbuf)
+
+#ifdef __hppa__
+#define STACK_GROWS_UP
+#endif
diff --git a/turtle b/turtle
new file mode 100644
index 0000000..c35625d
--- /dev/null
+++ b/turtle
@@ -0,0 +1,20 @@
+#define turtle_width 40
+#define turtle_height 40
+static char turtle_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0xff, 0x00, 0x00, 0x00, 0xe0, 0x84, 0x07, 0x00, 0x00, 0x10, 0x0c, 0x78,
+ 0x00, 0x00, 0x0c, 0x08, 0xc0, 0x00, 0x00, 0x02, 0x18, 0x40, 0x03, 0x00,
+ 0x01, 0x28, 0x40, 0x02, 0x80, 0x0f, 0xcc, 0x7f, 0x02, 0xc0, 0xf8, 0x07,
+ 0x10, 0x06, 0x40, 0x00, 0x04, 0x30, 0x0c, 0x60, 0x00, 0x04, 0x7c, 0x08,
+ 0xf8, 0x00, 0x04, 0xc2, 0x0f, 0x8c, 0x01, 0x0f, 0x01, 0x0b, 0x26, 0x01,
+ 0xf1, 0x01, 0x11, 0x03, 0x81, 0x01, 0x81, 0x20, 0x07, 0x83, 0x80, 0x80,
+ 0x40, 0x9a, 0x83, 0x00, 0x8f, 0xf8, 0x42, 0xc6, 0xff, 0xe3, 0x0f, 0x7e,
+ 0x63, 0x18, 0x22, 0x00, 0xc0, 0x31, 0xf0, 0x13, 0x00, 0x00, 0x11, 0x00,
+ 0x11, 0x00, 0x00, 0x0f, 0x00, 0x1b, 0x00, 0x00, 0x06, 0x00, 0x0e, 0x0e,
+ 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0xc0, 0x88, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x05, 0x38,
+ 0x08, 0x00, 0x80, 0x08, 0x44, 0x08, 0x00, 0x40, 0x04, 0x44, 0x08, 0x00,
+ 0x20, 0x02, 0x48, 0x04, 0x00, 0x10, 0x01, 0x70, 0x06, 0x00, 0x88, 0x00,
+ 0xc0, 0x01, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, 0x22, 0x0e, 0x40, 0x00,
+ 0x00, 0x11, 0x0a, 0x40, 0x00, 0x00, 0x09, 0x0c, 0x40, 0x00, 0x80, 0x06,
+ 0x3e, 0x20, 0x00, 0x80, 0xf1, 0xc1, 0x1f, 0x00};
diff --git a/turtlegr.c b/turtlegr.c
new file mode 100644
index 0000000..c74663b
--- /dev/null
+++ b/turtlegr.c
@@ -0,0 +1,1298 @@
+
+/* file turtlegr.c *
+ * Copyright (C) 1992 sjm@ee.tut.fi *
+ * jtl@cc.tut.fi *
+ * *
+ * Turtlegraphics primitives for the *
+ * SCM interpreter by Aubrey Jaffer *
+ * *
+ * Last modification: 13.10.1992 *
+ * *
+ * Versions: *
+ * 12.3.1992 The first version. *
+ * 13.3.1992 Added the possibility to pass *
+ * floating point args. *
+ * 15.3.1992 Graphics cards other than EGA *
+ * are now supported. *
+ * 9.4.1992 The internal representation *
+ * of X & Y is now float. *
+ * 13.10.1992 Added X11 support. *
+ * A major rewrite of certain *
+ * parts. *
+ * Put -DX11 -DFLOATS to CFLAGS *
+ * in Makefile to get it. *
+ * *
+ * REMEMBER to define INITS=init_turtlegr() *
+ * in the Makefile. *
+ * */
+
+/* *
+ * This code tries to compromise between two very different *
+ * systems: MSDOS and UNIX with the X11 windowing system. *
+ * The MSDOS version was build first and it really shows. :) *
+ * The X port is a partial rewrite of the old MSDOS stuff *
+ * and plays around with #ifdef's a lot. The result is, *
+ * eventually, a C source which is expected to compile *
+ * under both MSDOS and UNIX (X11). *
+ * The X code handles colors emulating CGA palette. It tries *
+ * to act sensibly even on a monochrome screen and when the *
+ * color palette is full. *
+ * X event handling is implemented with polling whenever *
+ * appropriate. This is not The Right Way to do it in X, but *
+ * it was easiest to adopt in this case. *
+ * Another solution would have been to make the X graphics *
+ * a separate process, but I didn't want to because I wanted *
+ * to keep it simple. I can't tell how good an example of porting *
+ * MSDOS software to X this is, but it works. *
+ * *
+ * This has been tested with SunOs 4.1.2 with X11R5, Linux 0.98.1 *
+ * with Xfree86 1.1 (X11R5 port) and in MSDOS with BC 3.1. *
+ * Because the code uses only the basic Xlib calls, it should *
+ * compile without problems under _any_ UNIX with X11R4 or newer. *
+ * *
+ * Please send bugreports to sjm@ee.tut.fi. *
+ * I'm especially interested in hearing about ports to other *
+ * platforms than those tested by me. *
+ * *
+ * - sjm *
+ * */
+
+
+/****************************************************/
+/***** GENERIC includes & defines *****/
+/****************************************************/
+#include "scm.h" /* includes scmfig.h as well */
+#include "patchlvl.h" /* Guess... */
+#include <math.h> /* sin(), cos(), fmod() */
+#include <stdlib.h> /* atexit() */
+
+/****************************************************/
+/***** X11 specific includes & defines *****/
+/****************************************************/
+#ifdef X11
+
+/* Xlib include files */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <stdio.h>
+
+#include "turtle"
+#define BITMAPDEPTH 1
+
+#define PROGNAME "scm"
+#define CLASSNAME "Scm"
+#define WINDOWNAME "TurtleSCM graphics window"
+#define ICONNAME "TurtleSCM"
+
+#define GR_MAX_XSIZE 1024
+#define GR_MAX_YSIZE 1024
+#define GR_DEF_XSIZE 640
+#define GR_DEF_YSIZE 480
+#define GR_MIN_XSIZE 64
+#define GR_MIN_YSIZE 64
+
+/* Fake CGA colormap with X - yuk! */
+#define GR_COLORS 16 /* CGA/EGA counterpart */
+#define GR_COLOR00 "black" /* black */
+#define GR_COLOR01 "blue2" /* blue */
+#define GR_COLOR02 "green2" /* green */
+#define GR_COLOR03 "cyan2" /* cyan */
+#define GR_COLOR04 "red3" /* red */
+#define GR_COLOR05 "magenta2" /* magenta */
+#define GR_COLOR06 "yellow2" /* brown */
+#define GR_COLOR07 "light gray" /* white */
+#define GR_COLOR08 "gray" /* gray */
+#define GR_COLOR09 "blue1" /* light blue */
+#define GR_COLOR10 "green1" /* light green */
+#define GR_COLOR11 "cyan1" /* light cyan */
+#define GR_COLOR12 "red1" /* light red */
+#define GR_COLOR13 "magenta1" /* light magenta */
+#define GR_COLOR14 "yellow1" /* yellow */
+#define GR_COLOR15 "white" /* bright white */
+
+#ifdef __STDC__
+static void gr_events( int );
+#else
+static void gr_events();
+#endif
+
+#else
+/****************************************************/
+/***** PC specific includes & defines *****/
+/****************************************************/
+#include <graphics.h>
+#include <stdlib.h> /* for getenv() */
+#include <stdio.h> /* for fputs() */
+#define BGIDIR_ENVSTRING "BGIDIR"
+#endif
+
+/********************************************/
+/***** GENERIC code, declarations *****/
+/********************************************/
+#define SIN( x ) \
+ sin( ((x)/180.0) * M_PI )
+#define COS( x ) \
+ cos( ((x)/180.0) * M_PI )
+
+static int gr_graphicsavail = 0;
+static int gr_grmode_on = 0;
+static float gr_dir = 0.0;
+static int gr_max_x=0, gr_max_y=0, gr_max_color=0;
+static float gr_x=0.0, gr_y=0.0;
+static int gr_color = 0;
+
+static char s_gr_draw[] = "draw";
+static char s_gr_move[] = "move";
+static char s_gr_setcolor[] = "set-color!";
+static char s_gr_turnright[] = "turn-right";
+static char s_gr_turnleft[] = "turn-left";
+static char s_gr_turnto[] = "turn-to!";
+
+static char s_gr_getdot[] = "get-dot";
+static char s_gr_drawTo[] = "draw-to!";
+static char s_gr_drawto[] = "draw-to";
+static char s_gr_moveTo[] = "move-to!";
+
+static char s_gr_setdot[] = "set-dot!";
+static char s_gr_validXYC[] = "valid-xyc?";
+
+#ifdef __GNUC__
+inline
+#else
+static
+#endif
+int valid_XYC( x, y, color )
+int x, y, color;
+{
+#ifdef X11
+ /* Check for changed window size */
+ gr_events(0);
+#endif
+ if( (x <= gr_max_x) && (y <= gr_max_y) && (color <= gr_max_color)
+ && (x >= 0) && (y >= 0) && (color >= 0) )
+ return( 1 );
+ else
+ return( 0 );
+} /* valid_XYC() */
+
+
+/********************************************************************/
+/***** X11 specific variable and function declarations *****/
+/********************************************************************/
+#ifdef X11
+static Display *gr_display; /* The X display */
+static int gr_screen; /* The X screen number */
+static Window gr_win; /* The drawable Window */
+static GC gr_gc; /* Graphics Context */
+static unsigned long gr_colortbl[GR_COLORS]; /* Color table */
+static XEvent gr_event; /* Event structure */
+
+/* These are needed for XSetWMProperties */
+static char *gr_windowname = WINDOWNAME;
+static char *gr_iconname = ICONNAME;
+static char gr_progname[] = PROGNAME;
+static char gr_classname[] = CLASSNAME;
+static int gr_argc = 1;
+static char *gr_argv[] = { gr_progname, NULL };
+
+static void gr_eventhandler( event )
+XEvent event;
+{
+ switch( event.type ) {
+
+ case ConfigureNotify:
+#ifdef TESTING
+ fputs( "Received ConfigureNotify event\n", stderr );
+#endif
+ gr_max_x = event.xconfigure.width - 1;
+ gr_max_y = event.xconfigure.height - 1;
+ break;
+
+ case MapNotify:
+#ifdef TESTING
+ fputs( "Received MapNotify event\n", stderr );
+#endif
+ break;
+
+ case DestroyNotify:
+#ifdef TESTING
+ fputs( "Received DestroyNotify event\n", stderr );
+#endif
+ break;
+
+ case UnmapNotify:
+#ifdef TESTING
+ fputs( "Received UnmapNotify event\n", stderr );
+#endif
+ break;
+
+ case Expose:
+#ifdef TESTING
+ fputs( "Received Expose event\n", stderr );
+#endif
+ if( event.xexpose.count != 0 )
+ break;
+ break;
+
+ case ClientMessage:
+#ifdef TESTING
+ fputs( "Received ClientMessage event\n", stderr );
+#endif
+ break;
+
+ default:
+ /* Throw away any unknown events */
+ break;
+
+ } /* switch */
+}
+
+static void gr_events( expected )
+int expected;
+{
+int i;
+
+ /* Get at least 'expected' events */
+ for( i = 0; i < expected; ++i ) {
+ XNextEvent( gr_display, &gr_event );
+ gr_eventhandler( gr_event );
+ }
+ /* Handle all remaining events if there are any */
+ /* XPending will call XFlush() if it doesn't find events at once */
+ while( XPending(gr_display) ) {
+ XNextEvent( gr_display, &gr_event );
+ gr_eventhandler( gr_event );
+ } /* while */
+} /* gr_events() */
+
+static void gr_typedevent( type )
+int type;
+{
+ do {
+ XNextEvent( gr_display, &gr_event );
+ gr_eventhandler( gr_event );
+ } while( gr_event.type != type );
+ /* Handle all remaining events if there are any */
+ /* XPending will call XFlush() if it doesn't find events at once */
+ while( XPending(gr_display) ) {
+ XNextEvent( gr_display, &gr_event );
+ gr_eventhandler( gr_event );
+ } /* while */
+}
+
+
+/********************************************************************/
+/***** PC specific variable and function declarations *****/
+/********************************************************************/
+#else
+
+static int gr_max_display_mode;
+static int gr_drivernum;
+
+#endif
+
+
+/********************************************************************/
+/********************************************************************/
+/*** User callable SCM routines begin here ***
+ *** ***
+ *** ***/
+
+
+SCM gr_helpgr()
+{
+ fputs( "\
+Ret Name nargs args returns\n\
+---------------------------------------------------------\n\
+B graphics-avail? 0 - #t if graphics available\n\
+B graphics-mode! 0 - #f if no graphics\n\
+B text-mode! 0 - #t on success\n\
+B clear-graphics! 0 - #f if not in graphics mode\n\
+i max-x 0 - maximum value of x\n\
+i max-y 0 - maximum value of y\n\
+i max-color 0 - maximum value of color\n\
+B valid-xyc? 3 x y color #t if valid\n\
+B set-dot! 3 x y color #t on success\n\
+i get-dot 2 x y color of the dot in (x,y)\n\
+ or #f if (x,y) not legal\n\
+\n\
+NOTE: Origin (0,0) is in the upper left corner.\n\n\
+", stdout );
+ return BOOL_T;
+} /* gr_helpgr() */
+
+
+SCM gr_helpturtlegr()
+{
+ fputs( "\
+Ret Name nargs args returns\n\
+---------------------------------------------------------\n\
+B goto-home! 0 - #f if not in graphics mode\n\
+B goto-center! 0 - #f if not in graphics mode\n\
+B goto-nw! 0 - #f if not in graphics mode\n\
+B goto-ne! 0 - #f if not in graphics mode\n\
+B goto-sw! 0 - #f if not in graphics mode\n\
+B goto-se! 0 - #f if not in graphics mode\n\
+B draw 1 length #t if target within drawing area\n\
+B draw-to 2 x y #t if (x,y) within drawing area\n\
+B draw-to! 2 x y #t if (x,y) within drawing area\n\
+B move 1 length #t if target within drawing area\n\
+B move-to! 2 x y #t if (x,y) within drawing area\n\
+i where-x 0 - current x-coordinate\n\
+i where-y 0 - current y-coordinate\n\
+i turn-right 1 angle drawing direction in degrees\n\
+i turn-left 1 angle drawing direction in degrees\n\
+i turn-to! 1 angle drawing direction in degrees\n\
+i what-direction 0 - drawing direction in degrees\n\
+B set-color! 1 color #t if color valid\n\
+i what-color 0 - current drawing color\n\n\
+", stdout );
+ return BOOL_T;
+} /* gr_helpturtlegr() */
+
+
+SCM gr_available()
+{
+ if( gr_graphicsavail )
+ return BOOL_T;
+ else
+ return BOOL_F;
+} /* gr_available() */
+
+
+SCM gr_maxx()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+#ifdef X11
+ /* Check for changed window size */
+ gr_events(0);
+#endif
+ return MAKINUM( (long)gr_max_x );
+} /* gr_maxx() */
+
+
+SCM gr_maxy()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+#ifdef X11
+ /* Check for changed window size */
+ gr_events(0);
+#endif
+ return MAKINUM( (long)gr_max_y );
+} /* gr_maxy() */
+
+SCM gr_maxc()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+ return MAKINUM( (long)gr_max_color );
+} /* gr_maxc() */
+
+
+SCM gr_validXYC( x, y, c )
+SCM x, y, c;
+{
+int xi, yi, ci;
+
+ ASSERT( NUMBERP(x),x,ARG1,s_gr_validXYC );
+ ASSERT( NUMBERP(y),y,ARG2,s_gr_validXYC );
+ ASSERT( NUMBERP(c),c,ARG3,s_gr_validXYC );
+ if( !gr_grmode_on )
+ return BOOL_F;
+
+ if( INUMP(x) )
+ xi = (int)(INUM(x));
+ else
+ xi = (int)(REALPART(x));
+
+ if( INUMP(y) )
+ yi = (int)(INUM(y));
+ else
+ yi = (int)(REALPART(y));
+
+ if( INUMP(c) )
+ ci = (int)(INUM(c));
+ else
+ ci = (int)(REALPART(c));
+
+/* valid_XYC() calls gr_events() */
+
+ if( valid_XYC( xi, yi, ci ) )
+ return BOOL_T;
+ else
+ return BOOL_F;
+} /* gr_validXYC() */
+
+
+SCM gr_grmode()
+{
+ if( !gr_graphicsavail )
+ return BOOL_F;
+#ifdef X11
+ /* bwuah... but it works :) */
+ if( !gr_grmode_on ) {
+ XMapWindow( gr_display, gr_win );
+ gr_typedevent( MapNotify );
+ }
+#else /* PC version */
+ setgraphmode( gr_max_display_mode );
+#endif
+ gr_grmode_on = 1;
+ return BOOL_T;
+} /* gr_grmode() */
+
+SCM gr_txtmode()
+{
+ if( !gr_graphicsavail )
+ return BOOL_F;
+#ifdef X11
+ /* bwuah... but it works :) */
+ if( gr_grmode_on ) {
+ XUnmapWindow( gr_display, gr_win );
+ gr_typedevent( UnmapNotify );
+ }
+#else /* PC version */
+ restorecrtmode();
+#endif
+ gr_grmode_on = 0;
+ return BOOL_T;
+} /* gr_txtmode() */
+
+
+SCM gr_cleargraph()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+#ifdef X11
+ XClearWindow( gr_display, gr_win );
+ gr_events(0);
+#else /* PC version */
+ cleardevice();
+#endif
+ return BOOL_T;
+} /* gr_cleargraph() */
+
+
+SCM gr_setdot( x, y, c )
+SCM x, y, c;
+{
+int xi, yi, ci;
+
+ ASSERT( NUMBERP(x),x,ARG1,s_gr_setdot );
+ ASSERT( NUMBERP(y),y,ARG2,s_gr_setdot );
+ ASSERT( NUMBERP(c),c,ARG3,s_gr_setdot );
+ if( !gr_grmode_on )
+ return BOOL_F;
+
+ if( INUMP(x) )
+ xi = (int)(INUM(x));
+ else
+ xi = (int)(REALPART(x));
+
+ if( INUMP(y) )
+ yi = (int)(INUM(y));
+ else
+ yi = (int)(REALPART(y));
+
+ if( INUMP(c) )
+ ci = (int)(INUM(c));
+ else
+ ci = (int)(REALPART(c));
+#ifdef TESTING
+ fprintf( stderr, "set-dot! called (%d,%d,%d)\n", xi, yi, ci );
+#endif
+ if( !valid_XYC( xi, yi, ci ) )
+ return BOOL_F;
+#ifdef X11
+ /* Set the drawing color */
+ XSetForeground( gr_display, gr_gc, gr_colortbl[ ci ] );
+ XDrawPoint( gr_display, gr_win, gr_gc, xi, yi );
+ /* Restore the drawing color */
+ XSetForeground( gr_display, gr_gc, gr_colortbl[ gr_color ] );
+ gr_events(0);
+#else /* PC version */
+ putpixel( xi, yi, ci );
+#endif
+ return BOOL_T;
+} /* gr_setdot() */
+
+
+SCM gr_getdot( x, y )
+SCM x, y;
+{
+int xi, yi;
+#ifdef X11
+XImage *xim;
+XWindowAttributes wattr;
+unsigned long dot;
+int i;
+#endif
+ ASSERT( NUMBERP(x),x,ARG1,s_gr_getdot );
+ ASSERT( NUMBERP(y),y,ARG2,s_gr_getdot );
+ if( !gr_grmode_on )
+ return BOOL_F;
+ if( INUMP(x) )
+ xi = (int)(INUM(x));
+ else
+ xi = (int)(REALPART(x));
+
+ if( INUMP(y) )
+ yi = (int)(INUM(y));
+ else
+ yi = (int)(REALPART(y));
+#ifdef TESTING
+ fprintf( stderr, "get-dot called (%d,%d)\n", xi, yi );
+#endif
+ if( !valid_XYC( xi, yi, 0 ) )
+ return BOOL_F;
+#ifdef X11
+ /* Now, this IS ugly. But it's there if you need it. */
+
+ /* Have to make sure that the window is mapped. Tough... */
+ XGetWindowAttributes( gr_display, gr_win, &wattr );
+ if( wattr.map_state == IsUnmapped ) {
+ XMapWindow( gr_display, gr_win );
+ gr_typedevent( MapNotify );
+ }
+ /* I KNOW this sucks. */
+ xim = XGetImage( gr_display,gr_win, xi,yi, 1,1, AllPlanes, XYPixmap );
+ dot = XGetPixel( xim, 0,0 );
+ for( i = 0; i < GR_COLORS; ++i ) {
+ if( gr_colortbl[i] == dot )
+ return MAKINUM( (long)i );
+ }
+ /* This should never happen. There's garbage in the window! */
+ fprintf( stderr, "%s: %s: Got an illegal pixel value %lu. \
+Is there garbage?\n", gr_progname, s_gr_getdot, dot );
+ return BOOL_F;
+#else /* PC version */
+ return MAKINUM( (long)getpixel( xi, yi ) );
+#endif
+} /* gr_getdot() */
+
+SCM gr_draw( S )
+SCM S;
+{
+float xf, yf;
+float sf;
+int ok;
+
+ ASSERT( NUMBERP(S),S,ARG1,s_gr_draw );
+ if( !gr_grmode_on )
+ return BOOL_F;
+ if( INUMP(S) )
+ sf = (float)(INUM(S));
+ else
+ sf = REALPART(S);
+#ifdef TESTING
+ fprintf( stderr, "draw called (%f)\n", sf );
+#endif
+ ok = 1;
+ xf = gr_x + ( COS( gr_dir ) * sf );
+ yf = gr_y + ( SIN( gr_dir ) * sf );
+ if( (int)xf > gr_max_x ) {
+ xf = (float)gr_max_x;
+ ok = 0;
+ }
+ else if( xf < 0.0 ) {
+ xf = 0.0;
+ ok = 0;
+ }
+ if( (int)yf > gr_max_y ) {
+ yf = (float)gr_max_y;
+ ok = 0;
+ }
+ else if( yf < 0.0 ) {
+ yf = 0.0;
+ ok = 0;
+ }
+#ifdef X11
+ XDrawLine( gr_display, gr_win, gr_gc,
+ (int)gr_x,(int)gr_y,
+ (int)xf,(int)yf );
+ gr_events(0);
+#else /* PC version */
+ line( (int)gr_x,(int)gr_y, (int)xf,(int)yf );
+#endif
+ gr_x = xf;
+ gr_y = yf;
+ if( ok )
+ return BOOL_T;
+ else
+ return BOOL_F;
+} /* gr_draw() */
+
+
+SCM gr_move( S )
+SCM S;
+{
+float xf, yf;
+float sf;
+int ok;
+
+ ASSERT( NUMBERP(S),S,ARG1,s_gr_move );
+ if( !gr_grmode_on )
+ return BOOL_F;
+ if( INUMP(S) )
+ sf = (float)(INUM(S));
+ else
+ sf = REALPART(S);
+#ifdef TESTING
+ fprintf( stderr, "move called (%f)\n", sf );
+#endif
+ ok = 1;
+ xf = gr_x + ( COS( gr_dir ) * sf );
+ yf = gr_y + ( SIN( gr_dir ) * sf );
+
+ if( (int)xf > gr_max_x ) {
+ xf = (float)gr_max_x;
+ ok = 0;
+ }
+ else if( xf < 0.0 ) {
+ xf = 0.0;
+ ok = 0;
+ }
+ if( (int)yf > gr_max_y ) {
+ yf = (float)gr_max_y;
+ ok = 0;
+ }
+ else if( yf < 0.0 ) {
+ yf = 0.0;
+ ok = 0;
+ }
+ gr_x = xf;
+ gr_y = yf;
+ if( ok )
+ return BOOL_T;
+ else
+ return BOOL_F;
+} /* gr_move() */
+
+
+SCM gr_drawto( x, y )
+SCM x, y;
+{
+int xi, yi;
+
+ ASSERT( NUMBERP(x),x,ARG1,s_gr_drawto );
+ ASSERT( NUMBERP(y),y,ARG2,s_gr_drawto );
+ if( !gr_grmode_on )
+ return BOOL_F;
+ if( INUMP(x) )
+ xi = (int)(INUM(x));
+ else
+ xi = (int)(REALPART(x));
+
+ if( INUMP(y) )
+ yi = (int)(INUM(y));
+ else
+ yi = (int)(REALPART(y));
+#ifdef TESTING
+ fprintf( stderr, "draw-to called (%d,%d)\n", xi, yi );
+#endif
+ if( !valid_XYC( xi,yi, 0 ) )
+ return BOOL_F;
+#ifdef X11
+ XDrawLine( gr_display, gr_win, gr_gc,
+ (int)gr_x,(int)gr_y, xi,yi );
+ gr_events(0);
+#else /* PC version */
+ line( (int)gr_x,(int)gr_y, xi,yi );
+#endif
+ return BOOL_T;
+} /* gr_drawto() */
+
+
+SCM gr_drawTo( x, y )
+SCM x, y;
+{
+float xf, yf;
+
+ ASSERT( NUMBERP(x),x,ARG1,s_gr_drawTo );
+ ASSERT( NUMBERP(y),y,ARG2,s_gr_drawTo );
+ if( !gr_grmode_on )
+ return BOOL_F;
+ if( INUMP(x) )
+ xf = (float)(INUM(x));
+ else
+ xf = (REALPART(x));
+
+ if( INUMP(y) )
+ yf = (float)(INUM(y));
+ else
+ yf = (REALPART(y));
+#ifdef TESTING
+ fprintf( stderr, "draw-to! called (%d,%d)\n", (int)xf, (int)yf );
+#endif
+ if( !valid_XYC( (int)xf,(int)yf, 0 ) )
+ return BOOL_F;
+#ifdef X11
+ XDrawLine( gr_display, gr_win, gr_gc,
+ (int)gr_x,(int)gr_y,
+ (int)xf,(int)yf );
+ gr_events(0);
+#else /* PC version */
+ line( (int)gr_x,(int)gr_y, (int)xf,(int)yf );
+#endif
+ gr_x = xf;
+ gr_y = yf;
+ return BOOL_T;
+} /* gr_drawTo() */
+
+
+SCM gr_moveTo( x, y )
+SCM x, y;
+{
+float xf, yf;
+
+ ASSERT( NUMBERP(x),x,ARG1,s_gr_moveTo );
+ ASSERT( NUMBERP(y),y,ARG2,s_gr_moveTo );
+ if( !gr_grmode_on )
+ return BOOL_F;
+ if( INUMP(x) )
+ xf = (float)(INUM(x));
+ else
+ xf = (REALPART(x));
+
+ if( INUMP(y) )
+ yf = (float)(INUM(y));
+ else
+ yf = (REALPART(y));
+#ifdef TESTING
+ fprintf( stderr, "move-to! called (%d,%d)\n", (int)xf, (int)yf );
+#endif
+ if( !valid_XYC( (int)xf,(int)yf, 0 ) )
+ return BOOL_F;
+ gr_x = xf;
+ gr_y = yf;
+ return BOOL_T;
+} /* gr_moveTo() */
+
+
+SCM gr_setcolor( c )
+SCM c;
+{
+int color;
+
+ ASSERT( NUMBERP(c),c,ARG1,s_gr_setcolor );
+ if( !gr_grmode_on )
+ return BOOL_F;
+ if( INUMP(c) )
+ color = (int)(INUM(c));
+ else
+ color = (int)(REALPART(c));
+#ifdef TESTING
+ fprintf( stderr, "set-color! called (%d)\n", color );
+#endif
+ if( !valid_XYC( 0,0, color ) )
+ return BOOL_F;
+ gr_color = color;
+#ifdef X11
+ /* Set the drawing color */
+ XSetForeground( gr_display, gr_gc, gr_colortbl[ gr_color ] );
+ gr_events(0);
+#else /* PC version */
+ setcolor( gr_color );
+#endif
+ return BOOL_T;
+} /* gr_setcolor() */
+
+
+SCM gr_turnright( d )
+SCM d;
+{
+float df;
+
+ ASSERT( NUMBERP(d),d,ARG1,s_gr_turnright );
+ if( !gr_grmode_on )
+ return BOOL_F;
+ if( INUMP(d) )
+ df = (float)(INUM(d));
+ else
+ df = REALPART(d);
+ df = fmod( df, 360.0 );
+ gr_dir -= df;
+ gr_dir = fmod( gr_dir, 360.0 );
+ return MAKINUM( (long)(gr_dir+.5) );
+} /* gr_turnright() */
+
+
+SCM gr_turnleft( d )
+SCM d;
+{
+float df;
+
+ ASSERT( NUMBERP(d),d,ARG1,s_gr_turnleft );
+ if( !gr_grmode_on )
+ return BOOL_F;
+ if( INUMP(d) )
+ df = (float)(INUM(d));
+ else
+ df = REALPART(d);
+ df = fmod( df, 360.0 );
+ gr_dir += df;
+ gr_dir = fmod( gr_dir, 360.0 );
+ return MAKINUM( (long)(gr_dir+.5) );
+} /* gr_turnleft() */
+
+
+SCM gr_turnto( d )
+SCM d;
+{
+float df;
+
+ ASSERT( NUMBERP(d),d,ARG1,s_gr_turnto );
+ if( !gr_grmode_on )
+ return BOOL_F;
+ if( INUMP(d) )
+ df = (float)(INUM(d));
+ else
+ df = REALPART(d);
+ df = fmod( df, 360.0 );
+ gr_dir = df;
+ return MAKINUM( (long)(gr_dir+.5) );
+} /* gr_turnto() */
+
+
+SCM gr_gotohome()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+ gr_x = gr_y = 0.0;
+ return BOOL_T;
+} /* gr_gotohome() */
+
+
+SCM gr_gotocenter()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+#ifdef X11
+ /* Check for changed window size */
+ gr_events(0);
+#endif
+ gr_x = ((float)gr_max_x+1.0) / 2.0;
+ gr_y = ((float)gr_max_y+1.0) / 2.0;
+ return BOOL_T;
+} /* gr_gotocenter() */
+
+
+SCM gr_gotonw()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+#ifdef X11
+ /* Check for changed window size */
+ gr_events(0);
+#endif
+ gr_x = 0.0;
+ gr_y = 0.0;
+ return BOOL_T;
+} /* gr_gotonw() */
+
+
+SCM gr_gotosw()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+#ifdef X11
+ /* Check for changed window size */
+ gr_events(0);
+#endif
+ gr_x = 0.0;
+ gr_y = (float)gr_max_y;
+ return BOOL_T;
+} /* gr_gotosw() */
+
+
+SCM gr_gotone()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+#ifdef X11
+ /* Check for changed window size */
+ gr_events(0);
+#endif
+ gr_x = (float)gr_max_x;
+ gr_y = 0.0;
+ return BOOL_T;
+} /* gr_gotone() */
+
+
+SCM gr_gotose()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+#ifdef X11
+ /* Check for changed window size */
+ gr_events(0);
+#endif
+ gr_x = (float)gr_max_x;
+ gr_y = (float)gr_max_y;
+ return BOOL_T;
+} /* gr_gotose() */
+
+
+SCM gr_whatcolor()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+ return MAKINUM( (long)gr_color );
+} /* gr_whatcolor() */
+
+
+SCM gr_whatdirection()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+ return MAKINUM( (long)(gr_dir+.5) );
+} /* gr_whatdirection() */
+
+
+SCM gr_wherex()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+ return MAKINUM( (long)gr_x );
+} /* gr_wherex() */
+
+
+SCM gr_wherey()
+{
+ if( !gr_grmode_on )
+ return BOOL_F;
+ return MAKINUM( (long)gr_y );
+} /* gr_wherey() */
+
+
+static iproc graph0[] = {
+ { "help-gr", gr_helpgr },
+ { "help-turtlegr", gr_helpturtlegr },
+ { "graphics-mode!", gr_grmode },
+ { "text-mode!", gr_txtmode },
+ { "clear-graphics!", gr_cleargraph },
+ { "graphics-avail?", gr_available },
+ { "max-x", gr_maxx },
+ { "max-y", gr_maxy },
+ { "max-color", gr_maxc },
+ { "what-color", gr_whatcolor },
+ { "what-direction", gr_whatdirection },
+ { "where-x", gr_wherex },
+ { "where-y", gr_wherey },
+ { "goto-home!", gr_gotohome },
+ { "goto-center!", gr_gotocenter },
+ { "goto-nw!", gr_gotonw },
+ { "goto-sw!", gr_gotosw },
+ { "goto-ne!", gr_gotone },
+ { "goto-se!", gr_gotose },
+ {0,0}
+ };
+
+static iproc graph1[] = {
+ { s_gr_draw, gr_draw },
+ { s_gr_move, gr_move },
+ { s_gr_setcolor, gr_setcolor },
+ { s_gr_turnright, gr_turnright },
+ { s_gr_turnleft, gr_turnleft },
+ { s_gr_turnto, gr_turnto },
+ {0,0}
+ };
+
+static iproc graph2[] = {
+ { s_gr_getdot, gr_getdot },
+ { s_gr_drawTo, gr_drawTo },
+ { s_gr_drawto, gr_drawto },
+ { s_gr_moveTo, gr_moveTo },
+ {0,0}
+ };
+
+static iproc graph3[] = {
+ { s_gr_setdot, gr_setdot },
+ { s_gr_validXYC, gr_validXYC },
+ {0,0}
+ };
+
+#if defined __STDC__ || defined __TURBOC__
+void close_turtlegr()
+{
+#ifdef X11
+ gr_events(0);
+ XFreeColors( gr_display, DefaultColormap(gr_display,gr_screen),
+ gr_colortbl, GR_COLORS, AllPlanes );
+ XFreeGC( gr_display, gr_gc );
+ XUnmapWindow( gr_display, gr_win );
+ XDestroyWindow( gr_display, gr_win );
+#else /* PC version */
+ closegraph();
+#endif
+} /* close_turtlegr() */
+#endif
+
+void init_banner(); /* from scm.c */
+
+void init_turtlegr() /* detects if graphics is available; must be
+ called among program initializations */
+{
+#ifdef X11
+ char *display_name = NULL; /* Server to connect to */
+ Pixmap icon_pixmap; /* Icon */
+ XSizeHints size_hints; /* Preferred sizes */
+ XSetWindowAttributes win_attribs; /* Window attributes */
+ XWMHints wm_hints; /* Window manager hints */
+ XClassHint class_hints; /* Class hints */
+ XTextProperty window_name, icon_name; /* Names for Icon & Window */
+ XGCValues gc_values; /* Graphics Context values */
+ static char *colorname[GR_COLORS] = {
+ GR_COLOR00, GR_COLOR01, GR_COLOR02, GR_COLOR03,
+ GR_COLOR04, GR_COLOR05, GR_COLOR06, GR_COLOR07,
+ GR_COLOR08, GR_COLOR09, GR_COLOR10, GR_COLOR11,
+ GR_COLOR12, GR_COLOR13, GR_COLOR14, GR_COLOR15
+ };
+ XColor x_color; /* X11 Color structure */
+ unsigned long mask; /* Mask for selections */
+ int i; /* loop counter variable */
+
+#else /* PC version */
+int errcode;
+#endif
+
+/***************************/
+/* generic initializations */
+/***************************/
+ gr_x = gr_y = gr_dir = 0.0;
+ gr_max_x = gr_max_y = gr_max_color = 0;
+
+ gr_graphicsavail = 0; /* DEFAULT is no graphics - you can do without */
+
+/********************************************/
+/***** Initialize X11 turtlegraphics *****/
+/********************************************/
+#ifdef X11
+ /* connect to X server */
+ if( (gr_display = XOpenDisplay(display_name)) != NULL )
+ {
+
+ /*****************************/
+ /* connection to X server OK */
+ /*****************************/
+
+ gr_screen = DefaultScreen( gr_display ); /* X screen number */
+
+ /* Create a window with Black background and border */
+ gr_win
+ = XCreateSimpleWindow( gr_display,
+ RootWindow( gr_display, gr_screen),
+ 0, 0, /* initial placement */
+ GR_DEF_XSIZE, GR_DEF_YSIZE,
+ 3, /* border width */
+ /* border pixel value */
+ BlackPixel(gr_display,gr_screen),
+ /* background pixel value */
+ BlackPixel(gr_display,gr_screen) );
+
+ /* Select input (events) for the window */
+ XSelectInput( gr_display, gr_win,
+ StructureNotifyMask|ExposureMask );
+
+ /* Check for backing store capability */
+ if( !DoesBackingStore(DefaultScreenOfDisplay(gr_display)) )
+ {
+ fprintf( stderr, "%s: Warning: \
+X server does not offer backing store capability.\n\
+Window cannot be redrawn if obscured. Sorry...\n", gr_progname );
+ }
+ else
+ {
+ /* Enable the backing store feature of X server
+ and set bit gravity */
+ win_attribs.bit_gravity = NorthWestGravity;
+ win_attribs.backing_store = Always;
+ mask = CWBitGravity | CWBackingStore;
+ XChangeWindowAttributes( gr_display, gr_win, mask, &win_attribs );
+ }
+
+ /* Make names of Window and Icon for window manager */
+ if( XStringListToTextProperty(&gr_windowname,1,&window_name) == 0 ) {
+ (void)fprintf( stderr, "%s: Structure allocation for windowName\
+ failed.\n", gr_progname );
+ exit( 42 );
+ }
+ if( XStringListToTextProperty(&gr_iconname,1,&icon_name) == 0 ) {
+ (void)fprintf( stderr, "%s: Structure allocation for iconName\
+ failed.\n", gr_progname );
+ exit( 42 );
+ }
+
+ /* Create the icon */
+ icon_pixmap = XCreateBitmapFromData( gr_display, gr_win, turtle_bits,
+ turtle_width, turtle_height );
+
+ /* Window size, state, icon etc. hints for the window manager */
+ size_hints.flags = PPosition | PMaxSize | PMinSize | USSize;
+ /* position and desired size are given to XCreateSimpleWindow call */
+ size_hints.min_width = GR_MIN_XSIZE;
+ size_hints.min_height = GR_MIN_YSIZE;
+ size_hints.max_width = GR_MAX_XSIZE;
+ size_hints.max_height = GR_MAX_YSIZE;
+ wm_hints.flags = StateHint | IconPixmapHint | InputHint;
+ wm_hints.initial_state = NormalState;
+ wm_hints.input = False;
+ wm_hints.icon_pixmap = icon_pixmap;
+ class_hints.res_name = gr_progname;
+ class_hints.res_class = gr_classname;
+ XSetWMProperties( gr_display, gr_win, &window_name, &icon_name,
+ gr_argv, gr_argc,
+ &size_hints, &wm_hints, &class_hints );
+
+
+ /* Handle colors; this is quite complicated in X11 */
+
+ if( DefaultDepth( gr_display, gr_screen ) == 1 )
+ {
+ /* Only 1 bitplane, BW screen */
+ /* Emulate colors with 0 as Black and 1-15 White */
+ gr_colortbl[0] = BlackPixel( gr_display, gr_screen );
+ for( i = 1; i < GR_COLORS; ++i )
+ gr_colortbl[i] = WhitePixel( gr_display, gr_screen );
+#ifdef TESTING
+ fprintf( stderr, "%s: 1-plane system, substituting White for \
+colors 1-15.\n", gr_progname );
+ fprintf( stderr, "%s: Pixel value is %lu for Black, \
+%lu for White\n", gr_progname, gr_colortbl[0], gr_colortbl[1] );
+#endif
+ }
+ else
+ {
+ /* more than 1 bitplane */
+ for( i = 0; i < GR_COLORS; ++i )
+ {
+ /* Initialize the colortable using named colors */
+ if( XParseColor( gr_display,
+ DefaultColormap(gr_display,gr_screen),
+ colorname[ i ], &x_color ) )
+ {
+ if( !XAllocColor( gr_display,
+ DefaultColormap(gr_display,gr_screen),
+ &x_color ) )
+ {
+ fprintf( stderr, "%s: Can't allocate color \
+\"%s\" (%d). Substituting White.\n",
+ gr_progname,
+ colorname[ i ], i );
+ gr_colortbl[i] = WhitePixel( gr_display, gr_screen );
+ }
+ else
+ {
+ /* succeeded in allocating color */
+ gr_colortbl[ i ] = x_color.pixel;
+#ifdef TESTING
+ fprintf( stderr, "%s: Pixel value is %lu for %s.\n",
+ gr_progname, gr_colortbl[i], colorname[i] );
+#endif
+ }
+ }
+ else
+ {
+ /* could not parse color */
+ fprintf( stderr,
+ "%s: Color name \"%s\" (%d) not in database. \
+Substituting White.\n",
+ gr_progname, colorname[i], i );
+ gr_colortbl[i] = WhitePixel( gr_display, gr_screen );
+ }
+ } /* for */
+ } /* else */
+ gr_max_color = GR_COLORS - 1;
+
+ /* Create and initialize a default GC */
+ gr_gc = XCreateGC( gr_display, gr_win, 0L, &gc_values );
+
+ /* Initialize the drawing color, default's black */
+ XSetForeground( gr_display, gr_gc, gr_colortbl[ 0 ] );
+ XSetBackground( gr_display, gr_gc, gr_colortbl[ 0 ] );
+ gr_color = 0;
+
+ /* OK, we _do_ have graphics available */
+ gr_graphicsavail = 1;
+
+#ifdef __STDC__
+ /* Let's do the Right Thing if possible :) */
+ atexit( close_turtlegr );
+#endif
+ } /* if */
+ else {
+ gr_graphicsavail = 0;
+ }
+/********************************************/
+/***** Initialize PC turtlegraphics *****/
+/********************************************/
+#else /* PC version */
+ gr_drivernum = DETECT;
+
+ detectgraph( &gr_drivernum, &gr_max_display_mode );
+ if( gr_drivernum != grNotDetected ) {
+ if( !getenv( BGIDIR_ENVSTRING ) )
+ fprintf( stderr,
+ "You really should set the %s environment variable.\n",
+ BGIDIR_ENVSTRING );
+ initgraph( &gr_drivernum, &gr_max_display_mode,
+ getenv( BGIDIR_ENVSTRING ) );
+ errcode = graphresult();
+ if( errcode != grOk ) {
+ fputs( "Graphics error: ", stderr );
+ fputs( grapherrormsg( errcode ), stderr );
+ exit( EXIT_FAILURE );
+ }
+ moveto( 0,0 );
+ gr_x = gr_y = 0.0;
+ setcolor( 0 );
+ gr_color = 0;
+ gr_max_x = getmaxx();
+ gr_max_y = getmaxy();
+ gr_max_color = getmaxcolor();
+ gr_max_display_mode = getmaxmode();
+ restorecrtmode();
+ gr_graphicsavail = 1;
+ atexit( close_turtlegr );
+ }
+ else {
+ gr_graphicsavail = 0;
+ }
+#endif
+
+/* generic */
+ init_iprocs( graph0, tc7_subr_0 );
+ init_iprocs( graph1, tc7_subr_1 );
+ init_iprocs( graph2, tc7_subr_2 );
+ init_iprocs( graph3, tc7_subr_3 );
+ gr_grmode_on = 0;
+
+#ifndef X11
+ /* PC version clears screen so this must be repeated */
+ init_banner();
+#endif
+
+ fputs("\nSCM Turtlegraphics Copyright (C) 1992 sjm@cc.tut.fi, jtl@cc.tut.fi\n\
+Type `(help-gr)' or `(help-turtlegr)' for a quick reference of\n\
+the new primitives.\n", stderr);
+
+ if( !gr_graphicsavail ) {
+#ifdef X11
+ fprintf( stderr, "%s: No X server found. \
+Turtlegraphics not available.\n", gr_progname );
+#else
+ fputs( "No graphics adapter detected. \
+Turtlegraphics not available.\n", stderr );
+#endif
+ }
+ else {
+#ifdef X11
+ gr_events(0);
+#else
+ ;
+#endif
+ }
+} /* init_turtlegr() */
diff --git a/version.txi b/version.txi
new file mode 100644
index 0000000..4bfee47
--- /dev/null
+++ b/version.txi
@@ -0,0 +1,2 @@
+@set SCMVERSION 5d6
+@set SCMDATE May 2002
diff --git a/xgen.scm b/xgen.scm
index 6c5bd4b..20d0cfd 100755
--- a/xgen.scm
+++ b/xgen.scm
@@ -1,4 +1,4 @@
-#! /usr/local/bin/scm \ %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
+#! /usr/bin/scm \ %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
- !#
;; Copyright (C) 1991-2000 Free Software Foundation, Inc.
;;