diff options
-rwxr-xr-x | build | 2 | ||||
-rw-r--r-- | build.scm | 40 | ||||
-rw-r--r-- | continue.h | 2 | ||||
-rw-r--r-- | debian/changelog | 238 | ||||
-rw-r--r-- | debian/control | 16 | ||||
-rw-r--r-- | debian/copyright | 16 | ||||
-rw-r--r-- | debian/doc-base | 12 | ||||
-rw-r--r-- | debian/postinst | 20 | ||||
-rw-r--r-- | debian/prerm | 16 | ||||
-rw-r--r-- | debian/require.scm.debian | 2 | ||||
-rwxr-xr-x | debian/rules | 161 | ||||
-rw-r--r-- | grtest.scm | 82 | ||||
-rw-r--r-- | scm5d6.info | 8382 | ||||
-rw-r--r-- | setjump.h | 4 | ||||
-rw-r--r-- | turtle | 20 | ||||
-rw-r--r-- | turtlegr.c | 1298 | ||||
-rw-r--r-- | version.txi | 2 | ||||
-rwxr-xr-x | xgen.scm | 2 |
18 files changed, 10293 insertions, 22 deletions
@@ -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) @@ -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) @@ -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 @@ -147,3 +147,7 @@ typedef struct safeport { } safeport; #define SAFEP_JMPBUF(sfp) (((safeport *)STREAM(sfp))->jmpbuf) + +#ifdef __hppa__ +#define STACK_GROWS_UP +#endif @@ -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 @@ -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. ;; |