scm [-a kbytes] [-ibvqmu] [-p number] [-c expression] [-e expression] [-f filename] [-l filename] [-r feature] [-- | - | -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 `Init5c4.scm') in
platform-dependent directories relative to this directory.
See section 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, `Init5c4.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.
`Init5c4.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. See section Syntax Extensions.
The options are processed in the order specified on the command line.
scm
should allocate an initial heapsize of
kb 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)
.
perl
and sh
respectively. On Amiga systems the entire option and argument need to be
enclosed in quotes. For instance `"-e(newline)"'.
scm
will require the features neccessary to support [R2RS],
[R3RS], [R4RS], or proposed [R5RS], respectively.
Scm
will load the first (unoptioned) file
named on the command line if no -c
, -e
, -f
,
-l
, or -s
option preceeds
it.
scm
command (verobse level).
scm
will print prompts, evaluation
times, notice of loading files, and garbage collection statistics. This
is the same as -p3
.
scm
will print no extra
information. This is the same as -p0
.
-r
macropackage before -m
on the command line.
-m
on the command line or from Scheme
code.
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.
scm
should run non-interactively. That means that
scm
will terminate after processing the command line or if there
are errors.
sh
, that further options are to be
treated as program aguments.
dump
(see section Dump).
If options appear on the command line after `-o filename', then the saved session will continue with processing those options when it is invoked. Otherwise the (new) command line is processed as usual when the saved image is invoked.
% scm foo.scm
% scm -f foo.scm arg1 arg2 arg3
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
("foo.scm" "arg1" "arg2")
and enters interactive
session.
% scm -e `(write (list-ref *argv* *optind*))' bar
% scm -rpretty-print -r format -i
pretty-print
and format
and enters interactive
session.
% scm -r5
dynamic-wind
, values
, and [R4RS] macros and enters
interactive (with macros) session.
% scm -r5 -r4
rev4-optional-procedures
are also loaded.
scm
will look for its initialization
code. The default is the file `Init5c4.scm' in the source directory.
ed
will call. If EDITOR
is not defined, the default is `ed'.
*argv*
can change
during argument processing. This list is suitable for use as an argument
to [SLIB] getopt
.
-m
and -u
options.
-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.
exit
(see section `System' in SLIB). On many
systems, SCM can also tail-call another program. See section I/O-Extensions.
For documentation of the procedures getenv
and system
See section `System Interface' in SLIB.
vms-debug
will invoke the VMS
debugger.
EDITOR
(or just ed
if it isn't defined) is invoked as a command with arguments arg1
....
ed
will invoke the editor with a
single the single argument filename.
(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.
The cautious
and stack-limit
options of build
(see section Build Options) support debugging in Scheme.
error
and
user-interrupt
(invoked by C-c) to print stack traces and
conclude by calling breakpoint
(see section `Breakpoints' in SLIB) 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)
.
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.
The routines I use most frequently for debugging are:
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.
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, section `Quick Print' in SLIB, 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.
swissnet.ai.mit.edu:pub/scm/slib-psd1-3.tar.gz prep.ai.mit.edu:pub/gnu/jacal/slib-psd1-3.tar.gz ftp.maths.tcd.ie:pub/bosullvn/jacal/slib-psd1-3.tar.gz ftp.cs.indiana.edu:/pub/scheme-repository/utl/slib-psd1-3.tar.gz
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 (see section 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.
(out-of-storage)
(end-of-program)
(hang-up)
(user-interrupt)
(arithmetic-error)
(alarm-interrupt)
(virtual-alarm-interrupt)
(profile-alarm-interrupt)
error
does
not set errobj.
errno
and perror
report ANSI C errors encountered during a
call to a system or library function.
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.
errno
and a newline. The value returned is unspecified.
warn
and error
provide a uniform way for Scheme code to
signal warnings and errors.
warn
is defined in
`Init5c4.scm'.
Error
is defined
in `Init5c4.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 section 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
(see section `Breakpoints' in SLIB). This allows the user to interract with SCM as with Lisp
systems.
stack-trace
returns #t
if any lines were
printed and #f
otherwise. See `Init5c4.scm' for an example of
the use of stack-trace
.
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.
For instance, open-input-file
is defined as follows in
`Init5c4.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))>
Note: When running a saved executable (see section Dump),
restart
is redefined to be exec-self
.
exec-self
from restart
.
(room #t)
also gives the hexadecimal heap segment and stack bounds.
In order to dump a saved executable or to dynamically-link using DLD,
SCM must know where its executable file is. Sometimes SCM
(see section 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.
#f
or newpath, respectively. The old path
is returned.
For other configuration constants and procedures See section `Configuration' in SLIB.
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
).
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.
The arg is an optional argument encapsulating the rest of the
first line's contents, if not just whitespace.
When executing a shell-script, the operating system invokes interpreter with (if present) arg, the pathname of the shell script file, and then any arguments which the shell-script was invoked with.
#!
,
the first line of that file will be ignored.
This combination of interpretatons allows SCM source files to be used as POSIX shell-scripts if the first line is:
#!/usr/local/bin/scm
or
#!/usr/local/bin/scm -l
When such a file is invoked, /usr/local/bin/scm is executed with the name of this file as the first argument.
#!/usr/local/bin/scm (print (program-arguments)) (quit) => ("scm" "./script")
#!/usr/local/bin/scm -l (print (program-arguments)) => ("scm" "-l" "./script")
The following shell-script will print factorial of its argument:
#!/usr/local/bin/scm -l (define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n))))) (print (fact (string->number (cadddr (program-arguments)))))
./fact 6 => 720
Shell-scripts suffer from several drawbacks:
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 :;
(type;
in older versions). 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.
#!/bin/sh :;exec scm -l$0 $* (define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n))))) (print (fact (string->number (caddr (program-arguments)))))
./fact 6 => 720
Olin Shivers' Scheme Shell project solves the one-argument limitation by introducing `\' as a meta-argument. This extensions is also supported by SCM.
This is an enhancement to the shell-script format. When the optional arg is `\', the interpreter substitutes the second line of file for `\', then appends any arguments given on the command line invoking this shell-script.
#!
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 shell-script will print its expanded argument list, then factorial of its argument:
#!/usr/local/bin/scm \ -p0 -l !# (print (program-arguments)) (define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n))))) (print (fact (string->number (list-ref (program-arguments) *optind*))))
./fact 5 => ("scm" "-p0" "-l" "./fact" "5") 120
It turns out that we can create shell-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.
The first two characters of the shell-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 shell-script should be literally `\ %0 %1 %2 %3 %4 %5 %6 %7 %8', 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
shell-script up to `!#', the name of the shell-script file, and
then any of at most 8 arguments given on the command line invoking this
shell-script.
The following shell-script will print its expanded argument list, then factorial of its argument. This shell-script in both MS-DOS and unix systems.
#! /usr/local/bin/scm \ %0 %1 %2 %3 %4 %5 %6 %7 %8 -p1 -l !# (print (program-arguments)) (define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n))))) (print (fact (string->number (list-ref (program-arguments) *optind*))))
Go to the first, previous, next, last section, table of contents.