scm [-a kbytes] [-ibvqmu] [-p number] [-c expression] [-e expression] [-f filename] [-l filename] [-r feature] [-- | - | -s] [filename] [arguments ...]
scm loads the file specified by by the environment
If SCM_INIT_PATH is not defined or if the file it names is not
scm tries to find the directory containing the
executable file. If it is able to locate the executable,
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
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.
scmshould 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_SIZEin source file `setjump.h' which the distribution sets at
shrespectively. On Amiga systems the entire option and argument need to be enclosed in quotes. For instance `"-e(newline)"'.
scmwill require the features neccessary to support [R2RS], [R3RS], [R4RS], or proposed [R5RS], respectively.
Scmwill load the first (unoptioned) file named on the command line if no
-soption preceeds it.
scmcommand (verobse level).
scmwill print prompts, evaluation times, notice of loading files, and garbage collection statistics. This is the same as
scmwill print no extra information. This is the same as
-mon the command line.
-mon the command line or from Scheme code.
scmshould run interactively. That means that
scmwill not terminate until the
(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
scmis started from a tty, it will assume that it should be interactive unless given a subsequent
scmshould run non-interactively. That means that
scmwill 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
arg3are 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
formatand enters interactive session.
% scm -r5
values, and [R4RS] macros and enters interactive (with macros) session.
% scm -r5 -r4
rev4-optional-proceduresare also loaded.
scmwill look for its initialization code. The default is the file `Init5c4.scm' in the source directory.
edwill 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]
-boptions. Define this in `ScmInit.scm' or files specified on the command line. This can be overridden by subsequent
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
See section `System Interface' in SLIB.
vms-debugwill invoke the VMS debugger.
edif it isn't defined) is invoked as a command with arguments arg1 ....
edwill 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.
stack-limit options of
(see section Build Options) support debugging in Scheme.
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
HEAP_SEG_SIZE/2), SCM generates a
segment violationinterrupt. 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:
newlineat 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.
(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.
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.
errordoes not set errobj.
perror report ANSI C errors encountered during a
call to a system or library function.
errno. When given an argument,
errnosets the system variable
errnoto n and returns the previous value of
(errno 0)will clear outstanding errors. This is recommended after
#fsince this occurs when the file could not be opened.
errnoand a newline. The value returned is unspecified.
error provide a uniform way for Scheme code to
signal warnings and errors.
warnis defined in `Init5c4.scm'.
Erroris 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
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
#tif any lines were printed and
#fotherwise. See `Init5c4.scm' for an example of the use of
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.
open-input-file is defined as follows in
(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)))
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
(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
execpath with the pathname.
#for 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
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
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:
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
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
This combination of interpretatons allows SCM source files to be used as POSIX shell-scripts if the first line is:
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:
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,
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
#! tries all directories named by environment
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
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.