   This file documents the MIT Scheme system.

   Copyright (C) 1988-2002 Massachusetts Institute of Technology

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.  A copy of the license is included in the section entitled "GNU
Free Documentation License".

Format
======

   The procedure `format' is very useful for producing nicely formatted
text, producing good-looking messages, and so on.  MIT Scheme's
implementation of `format' is similar to that of Common Lisp, except
that Common Lisp defines many more directives.(1)

   `format' is a run-time-loadable option.  To use it, execute

     (load-option 'format)

once before calling it.

 - procedure: format destination control-string argument ...
     Writes the characters of CONTROL-STRING to DESTINATION, except
     that a tilde (`~') introduces a "format directive".  The character
     after the tilde, possibly preceded by prefix parameters and
     modifiers, specifies what kind of formatting is desired.  Most
     directives use one or more ARGUMENTs to create their output; the
     typical directive puts the next ARGUMENT into the output,
     formatted in some special way.  It is an error if no argument
     remains for a directive requiring an argument, but it is not an
     error if one or more arguments remain unprocessed by a directive.

     The output is sent to DESTINATION.  If DESTINATION is `#f', a
     string is created that contains the output; this string is
     returned as the value of the call to `format'.  In all other cases
     `format' returns an unspecified value.  If DESTINATION is `#t',
     the output is sent to the current output port.  Otherwise,
     DESTINATION must be an output port, and the output is sent there.

     This procedure performs discretionary output flushing (see
     Output Procedures).

     A `format' directive consists of a tilde (`~'), optional prefix
     parameters separated by commas, optional colon (`:') and at-sign
     (`@') modifiers, and a single character indicating what kind of
     directive this is.  The alphabetic case of the directive character
     is ignored.  The prefix parameters are generally integers, notated
     as optionally signed decimal numbers.  If both the colon and
     at-sign modifiers are given, they may appear in either order.

     In place of a prefix parameter to a directive, you can put the
     letter `V' (or `v'), which takes an ARGUMENT for use as a
     parameter to the directive.  Normally this should be an exact
     integer.  This feature allows variable-width fields and the like.
     You can also use the character `#' in place of a parameter; it
     represents the number of arguments remaining to be processed.

     It is an error to give a format directive more parameters than it
     is described here as accepting.  It is also an error to give colon
     or at-sign modifiers to a directive in a combination not
     specifically described here as being meaningful.

    `~A'
          The next ARGUMENT, which may be any object, is printed as if
          by `display'.  `~MINCOLA' inserts spaces on the right, if
          necessary, to make the width at least MINCOL columns.  The
          `@' modifier causes the spaces to be inserted on the left
          rather than the right.

    `~S'
          The next ARGUMENT, which may be any object, is printed as if
          by `write'.  `~MINCOLS' inserts spaces on the right, if
          necessary, to make the width at least MINCOL columns.  The
          `@' modifier causes the spaces to be inserted on the left
          rather than the right.

    `~%'
          This outputs a `#\newline' character.  `~N%' outputs N
          newlines.  No ARGUMENT is used.  Simply putting a newline in
          CONTROL-STRING would work, but `~%' is often used because it
          makes the control string look nicer in the middle of a
          program.

    `~~'
          This outputs a tilde.  `~N~' outputs N tildes.

    `~NEWLINE'
          Tilde immediately followed by a newline ignores the newline
          and any following non-newline whitespace characters.  With an
          `@', the newline is left in place, but any following
          whitespace is ignored.  This directive is typically used when
          CONTROL-STRING is too long to fit nicely into one line of the
          program:

               (define (type-clash-error procedure arg spec actual)
                 (format
                  #t
                  "~%Procedure ~S~%requires its %A argument ~
                   to be of type ~S,~%but it was called with ~
                   an argument of type ~S.~%"
                  procedure arg spec actual))

               (type-clash-error 'vector-ref
                                 "first"
                                 'integer
                                 'vector)

               prints

               Procedure vector-ref
               requires its first argument to be of type integer,
               but it was called with an argument of type vector.

          Note that in this example newlines appear in the output only
          as specified by the `~%' directives; the actual newline
          characters in the control string are suppressed because each
          is preceded by a tilde.

   ---------- Footnotes ----------

   (1) This description of `format' is adapted from `Common Lisp, The
Language', second edition, section 22.3.3.

Custom Output
=============

   MIT Scheme provides hooks for specifying that certain kinds of
objects have special written representations.  There are no
restrictions on the written representations, but only a few kinds of
objects may have custom representation specified for them,
specifically: records (see Records), vectors that have special tags
in their zero-th elements (see Vectors), and pairs that have
special tags in their car fields (see Lists).  There is a different
procedure for specifying the written representation of each of these
types.

 - procedure: set-record-type-unparser-method! record-type
          unparser-method
     Changes the unparser method of the type represented by RECORD-TYPE
     to be UNPARSER-METHOD, and returns an unspecified value.
     Subsequently, when the unparser encounters a record of this type,
     it will invoke UNPARSER-METHOD to generate the written
     representation.

 - procedure: unparser/set-tagged-vector-method! tag unparser-method
     Changes the unparser method of the vector type represented by TAG
     to be UNPARSER-METHOD, and returns an unspecified value.
     Subsequently, when the unparser encounters a vector with TAG as
     its zero-th element, it will invoke UNPARSER-METHOD to generate
     the written representation.

 - procedure: unparser/set-tagged-pair-method! tag unparser-method
     Changes the unparser method of the pair type represented by TAG to
     be UNPARSER-METHOD, and returns an unspecified value.
     Subsequently, when the unparser encounters a pair with TAG in its
     car field, it will invoke UNPARSER-METHOD to generate the written
     representation.

   An "unparser method" is a procedure that is invoked with two
arguments: an unparser state and an object.  An unparser method
generates a written representation for the object, writing it to the
output port specified by the unparser state.  The value yielded by an
unparser method is ignored.  Note that an unparser state is not an
output port, rather it is an object that contains an output port as one
of its components.  Application programs generally do not construct or
examine unparser state objects, but just pass them along.

   There are two ways to create an unparser method (which is then
registered by one of the above procedures).  The first, and easiest, is
to use `standard-unparser-method'.  The second is to define your own
method using the procedure `with-current-unparser-state'.  We encourage
the use of the first method, as it results in a more uniform appearance
for objects.  Many predefined datatypes, for example procedures and
environments, already have this appearance.

 - procedure: standard-unparser-method name procedure
     Returns a standard unparser method.  NAME may be any object, and
     is used as the name of the type with which the unparser method is
     associated; NAME is usually a symbol.  PROCEDURE must be `#f' or a
     procedure of two arguments.

     If PROCEDURE is `#f', the returned method generates an external
     representation of this form:

          #[NAME HASH]

     Here NAME is the external representation of the argument NAME, as
     generated by `write',(1) and HASH is the external representation
     of an exact non-negative integer unique to the object being
     printed (specifically, it is the result of calling `hash' on the
     object).  Subsequently, the expression

          #@HASH

     is notation for the object.

     If PROCEDURE is supplied, the returned method generates a slightly
     different external representation:

          #[NAME HASH OUTPUT]

     Here NAME and HASH are as above, and OUTPUT is the output
     generated by PROCEDURE.  The representation is constructed in
     three stages:

       1. The first part of the format (up to OUTPUT) is written to the
          output port specified by the unparser state.  This is `"#["',
          NAME, `" "', and HASH.

       2. PROCEDURE is invoked on two arguments: the object and an
          output port.

       3. The closing bracket is written to the output port.

   The following procedure is useful for writing more general kinds of
unparser methods.

 - procedure: with-current-unparser-state unparser-state procedure
     This procedure calls PROCEDURE with one argument, the output port
     from UNPARSER-STATE.  Additionally, it arranges for the remaining
     components of UNPARSER-STATE to be given to the printer when they
     are needed.  The PROCEDURE generates some output by writing to the
     output port using the usual output operations, and the value
     yielded by PROCEDURE is returned from
     `with-current-unparser-state'.

     The port passed to PROCEDURE should only be used within the
     dynamic extent of PROCEDURE.

   ---------- Footnotes ----------

   (1) Except that if the argument NAME is a string, its external
representation is generated by `write-string'.

Prompting
=========

   This section describes procedures that prompt the user for input.
Why should the programmer use these procedures when it is possible to do
prompting using ordinary input and output procedures?  One reason is
that the prompting procedures are more succinct.  However, a second and
better reason is that the prompting procedures can be separately
customized for each user interface, providing more natural interaction.
The interfaces for Edwin and for GNU Emacs have already been customized
in this fashion; because Edwin and Emacs are very similar editors, their
customizations provide very similar behavior.

   Each of these procedure accepts an optional argument called PORT,
which if given must be an I/O port.  If not given, this port defaults
to the value of `(interaction-i/o-port)'; this is initially the console
I/O port.

 - procedure: prompt-for-command-expression prompt [port]
     Prompts the user for an expression that is to be executed as a
     command.  This is the procedure called by the REP loop to read the
     user's expressions.

     If PROMPT is a string, it is used verbatim as the prompt string.
     Otherwise, it must be a pair whose car is `standard' and whose cdr
     is a string; in this case the prompt string is formed by
     prepending to the string the current REP loop "level number" and a
     space.  Also, a space is appended to the string, unless it already
     ends in a space or is an empty string.

     The default behavior of this procedure is to print a fresh line, a
     newline, and the prompt string; flush the output buffer; then read
     an object and return it.

     Under Edwin and Emacs, before the object is read, the interaction
     buffer is put into a mode that allows expressions to be edited and
     submitted for input using specific editor commands.  The first
     expression that is submitted is returned as the value of this
     procedure.

 - procedure: prompt-for-command-char prompt [port]
     Prompts the user for a single character that is to be executed as a
     command; the returned character is guaranteed to satisfy
     `char-graphic?'.  If at all possible, the character is read from
     the user interface using a mode that reads the character as a
     single keystroke; in other words, it should not be necessary for
     the user to follow the character with a carriage return or
     something similar.

     This is the procedure called by `debug' and `where' to read the
     user's commands.

     If PROMPT is a string, it is used verbatim as the prompt string.
     Otherwise, it must be a pair whose car is `standard' and whose cdr
     is a string; in this case the prompt string is formed by
     prepending to the string the current REP loop "level number" and a
     space.  Also, a space is appended to the string, unless it already
     ends in a space or is an empty string.

     The default behavior of this procedure is to print a fresh line, a
     newline, and the prompt string; flush the output buffer; read a
     character in raw mode, echo that character, and return it.

     Under Edwin and Emacs, instead of reading a character, the
     interaction buffer is put into a mode in which graphic characters
     submit themselves as input.  After this mode change, the first
     such character submitted is returned as the value of this
     procedure.

 - procedure: prompt-for-expression prompt [port]
     Prompts the user for an expression.

     The prompt string is formed by appending a colon and a space to
     PROMPT, unless PROMPT already ends in a space or is the null
     string.

     The default behavior of this procedure is to print a fresh line, a
     newline, and the prompt string; flush the output buffer; then read
     an object and return it.

     Under Edwin and Emacs, the expression is read in the minibuffer.

 - procedure: prompt-for-evaluated-expression prompt [environment
          [port]]
     Prompts the user for an evaluated expression.  Calls
     `prompt-for-expression' to read an expression, then evaluates the
     expression using ENVIRONMENT; if ENVIRONMENT is not given, the REP
     loop environment is used.

 - procedure: prompt-for-confirmation prompt [port]
     Prompts the user for confirmation.  The result yielded by this
     procedure is a boolean.

     The prompt string is formed by appending the string `" (y or n)? "'
     to PROMPT, unless PROMPT already ends in a space or is the null
     string.

     The default behavior of this procedure is to print a fresh line, a
     newline, and the prompt string; flush the output buffer; then read
     a character in raw mode.  If the character is `#\y', `#\Y', or
     `#\space', the procedure returns `#t'; If the character is `#\n',
     `#\N', or `#\rubout', the procedure returns `#f'.  Otherwise the
     prompt is repeated.

     Under Edwin or Emacs, the confirmation is read in the minibuffer.

Port Primitives
===============

   This section describes the low-level operations that can be used to
build and manipulate I/O ports.

   The purpose of these operations is twofold: to allow programmers to
construct new kinds of I/O ports, and to provide faster I/O operations
than those supplied by the standard high level procedures.  The latter
is useful because the standard I/O operations provide defaulting and
error checking, and sometimes other features, which are often
unnecessary.  This interface provides the means to bypass such
features, thus improving performance.

   The abstract model of an I/O port, as implemented here, is a
combination of a set of named operations and a state.  The state is an
arbitrary object, the meaning of which is determined by the operations.
The operations are defined by a mapping from names to procedures.

   The set of named operations is represented by an object called a
"port type".  A port type is constructed from a set of named
operations, and is subsequently used to construct a port.  The port type
completely specifies the behavior of the port.  Port types also support
a simple form of inheritance, allowing you to create new ports that are
similar to existing ports.

   The port operations are divided into two classes:

Standard operations
     There is a specific set of standard operations for input ports,
     and a different set for output ports.  Applications can assume
     that the standard input operations are implemented for all input
     ports, and likewise the standard output operations are implemented
     for all output ports.

Custom operations
     Some ports support additional operations.  For example, ports that
     implement output to terminals (or windows) may define an operation
     named `y-size' that returns the height of the terminal in
     characters.  Because only some ports will implement these
     operations, programs that use custom operations must test each
     port for their existence, and be prepared to deal with ports that
     do not implement them.

Port Types
----------

   The procedures in this section provide means for constructing port
types with standard and custom operations, and accessing their
operations.

 - procedure: make-port-type operations port-type
     Creates and returns a new port type.  OPERATIONS must be a list;
     each element is a list of two elements, the name of the operation
     (a symbol) and the procedure that implements it.  PORT-TYPE is
     either `#f' or a port type; if it is a port type, any operations
     implemented by PORT-TYPE but not specified in OPERATIONS will be
     implemented by the resulting port type.

     OPERATIONS need not contain definitions for all of the standard
     operations; the procedure will provide defaults for any standard
     operations that are not defined.  At a minimum, the following
     operations must be defined: for input ports, `read-char' and
     `peek-char'; for output ports, either `write-char' or
     `write-substring'.  I/O ports must supply the minimum operations
     for both input and output.

     If an operation in OPERATIONS is defined to be `#f', then the
     corresponding operation in PORT-TYPE is _not_ inherited.

     If `read-char' is defined in OPERATIONS, then any standard input
     operations defined in PORT-TYPE are ignored.  Likewise, if
     `write-char' or `write-substring' is defined in OPERATIONS, then
     any standard output operations defined in PORT-TYPE are ignored.
     This feature allows overriding the standard operations without
     having to enumerate them.

 - procedure: port-type? object
 - procedure: input-port-type? object
 - procedure: output-port-type? object
 - procedure: i/o-port-type? object
     These predicates return `#t' if OBJECT is a port type, input-port
     type, output-port type, or I/O-port type, respectively.
     Otherwise, they return `#f'.

 - procedure: port-type/operations port-type
     Returns a newly allocated list containing all of the operations
     implemented by PORT-TYPE.  Each element of the list is a list of
     two elements -- the name and its associated operation.

 - procedure: port-type/operation-names port-type
     Returns a newly allocated list whose elements are the names of the
     operations implemented by PORT-TYPE.

 - procedure: port-type/operation port-type symbol
     Returns the operation named SYMBOL in PORT-TYPE.  If PORT-TYPE has
     no such operation, returns `#f'.

Constructors and Accessors for Ports
------------------------------------

   The procedures in this section provide means for constructing ports,
accessing the type of a port, and manipulating the state of a port.

 - procedure: make-port port-type state
     Returns a new port with type PORT-TYPE and the given STATE.  The
     port will be an input, output, or I/O port according to PORT-TYPE.

 - procedure: port/type port
     Returns the port type of PORT.

 - procedure: port/state port
     Returns the state component of PORT.

 - procedure: set-port/state! port object
     Changes the state component of PORT to be OBJECT.  Returns an
     unspecified value.

 - procedure: port/operation port symbol
     Equivalent to

          (port-type/operation (port/type PORT) SYMBOL)

 - procedure: port/operation-names port
     Equivalent to

          (port-type/operation-names (port/type PORT))

 - procedure: make-eof-object input-port
     Returns an object that satisfies the predicate `eof-object?'.  This
     is sometimes useful when building input ports.

Input Port Operations
---------------------

   This section describes the standard operations on input ports.
Following that, some useful custom operations are described.

 - operation on input port: read-char input-port
     Removes the next character available from INPUT-PORT and returns
     it.  If INPUT-PORT has no more characters and will never have any
     (e.g. at the end of an input file), this operation returns an
     end-of-file object.  If INPUT-PORT has no more characters but will
     eventually have some more (e.g. a terminal where nothing has been
     typed recently), and it is in non-blocking mode, `#f' is returned;
     otherwise the operation hangs until input is available.

 - operation on input port: peek-char input-port
     Reads the next character available from INPUT-PORT and returns it.
     The character is _not_ removed from INPUT-PORT, and a subsequent
     attempt to read from the port will get that character again.  In
     other respects this operation behaves like `read-char'.

 - operation on input port: discard-char input-port
     Discards the next character available from INPUT-PORT and returns
     an unspecified value.  In other respects this operation behaves
     like `read-char'.

 - operation on input port: char-ready? input-port k
     `char-ready?' returns `#t' if at least one character is available
     to be read from INPUT-PORT.  If no characters are available, the
     operation waits up to K milliseconds before returning `#f',
     returning immediately if any characters become available while it
     is waiting.

 - operation on input port: read-string input-port char-set
 - operation on input port: discard-chars input-port char-set
     These operations are like `read-char' and `discard-char', except
     that they read or discard multiple characters at once.  This can
     have a marked performance improvement on buffered input ports.  All
     characters up to, but excluding, the first character in CHAR-SET
     (or end of file) are read from INPUT-PORT.  `read-string' returns
     these characters as a newly allocated string, while
     `discard-chars' discards them and returns an unspecified value.
     These operations hang until sufficient input is available, even if
     INPUT-PORT is in non-blocking mode.  If end of file is encountered
     before any input characters, `read-string' returns an end-of-file
     object.

 - operation on input port: read-substring input-port string start end
     Reads characters from INPUT-PORT into the substring defined by
     STRING, START, and END until either the substring has been filled
     or there are no more characters available.  Returns the number of
     characters written to the substring.

     If INPUT-PORT is an interactive port, and at least one character
     is immediately available, the available characters are written to
     the substring and this operation returns immediately.  If no
     characters are available, and INPUT-PORT is in blocking mode, the
     operation blocks until at least one character is available.
     Otherwise, the operation returns `#f' immediately.

     This is an extremely fast way to read characters from a port.

 - procedure: input-port/read-char input-port
 - procedure: input-port/peek-char input-port
 - procedure: input-port/discard-char input-port
 - procedure: input-port/char-ready? input-port k
 - procedure: input-port/read-string input-port char-set
 - procedure: input-port/discard-chars input-port char-set
 - procedure: input-port/read-substring input-port string start end
     Each of these procedures invokes the respective operation on
     INPUT-PORT.  For example, the following are equivalent:

          (input-port/read-char INPUT-PORT)
          ((input-port/operation INPUT-PORT 'read-char) INPUT-PORT)

   The following custom operations are implemented for input ports to
files, and will also work with some other kinds of input ports:

 - operation on input port: eof? input-port
     Returns `#t' if INPUT-PORT is known to be at end of file,
     otherwise it returns `#f'.

 - operation on input port: chars-remaining input-port
     Returns an estimate of the number of characters remaining to be
     read from INPUT-PORT.  This is useful only when INPUT-PORT is a
     file port in binary mode; in other cases, it returns `#f'.

 - operation on input port: buffered-input-chars input-port
     Returns the number of unread characters that are stored in
     INPUT-PORT's buffer.  This will always be less than or equal to
     the buffer's size.

 - operation on input port: input-buffer-size input-port
     Returns the maximum number of characters that INPUT-PORT's buffer
     can hold.

 - operation on input port: set-input-buffer-size input-port size
     Resizes INPUT-PORT's buffer so that it can hold at most SIZE
     characters.  Characters in the buffer are discarded.  SIZE must be
     an exact non-negative integer.

Output Port Operations
----------------------

   This section describes the standard operations on output ports.
Following that, some useful custom operations are described.

 - operation on output port: write-char output-port char
     Writes CHAR to OUTPUT-PORT and returns an unspecified value.

 - operation on output port: write-substring output-port string start
          end
     Writes the substring specified by STRING, START, and END to
     OUTPUT-PORT and returns an unspecified value.  Equivalent to
     writing the characters of the substring, one by one, to
     OUTPUT-PORT, but is implemented very efficiently.

 - operation on output port: fresh-line output-port
     Most output ports are able to tell whether or not they are at the
     beginning of a line of output.  If OUTPUT-PORT is such a port,
     end-of-line is written to the port only if the port is not already
     at the beginning of a line.  If OUTPUT-PORT is not such a port, and
     end-of-line is unconditionally written to the port.  Returns an
     unspecified value.

 - operation on output port: flush-output output-port
     If OUTPUT-PORT is buffered, this causes its buffer to be written
     out.  Otherwise it has no effect.  Returns an unspecified value.

 - operation on output port: discretionary-flush-output output-port
     Normally, this operation does nothing.  However, ports that support
     discretionary output flushing implement this operation identically
     to `flush-output'.

 - procedure: output-port/write-char output-port char
 - procedure: output-port/write-substring output-port string start end
 - procedure: output-port/fresh-line output-port
 - procedure: output-port/flush-output output-port
 - procedure: output-port/discretionary-flush-output output-port
     Each of these procedures invokes the respective operation on
     OUTPUT-PORT.  For example, the following are equivalent:

          (output-port/write-char OUTPUT-PORT CHAR)
          ((output-port/operation OUTPUT-PORT 'write-char)
           OUTPUT-PORT CHAR)

 - procedure: output-port/write-string output-port string
     Writes STRING to OUTPUT-PORT.  Equivalent to

          (output-port/write-substring OUTPUT-PORT
                                       STRING
                                       0
                                       (string-length STRING))

   The following custom operations are generally useful.

 - operation on output port: buffered-output-chars output-port
     Returns the number of unwritten characters that are stored in
     OUTPUT-PORT's buffer.  This will always be less than or equal to
     the buffer's size.

 - operation on output port: output-buffer-size output-port
     Returns the maximum number of characters that OUTPUT-PORT's buffer
     can hold.

 - operation on output port: set-output-buffer-size output-port size
     Resizes OUTPUT-PORT's buffer so that it can hold at most SIZE
     characters.  Characters in the buffer are discarded.  SIZE must be
     an exact non-negative integer.

 - operation on output port: x-size output-port
     Returns an exact positive integer that is the width of OUTPUT-PORT
     in characters.  If OUTPUT-PORT has no natural width, e.g. if it is
     a file port, `#f' is returned.

 - operation on output port: y-size output-port
     Returns an exact positive integer that is the height of
     OUTPUT-PORT in characters.  If OUTPUT-PORT has no natural height,
     e.g. if it is a file port, `#f' is returned.

 - procedure: output-port/x-size output-port
     This procedure invokes the custom operation whose name is the
     symbol `x-size', if it exists.  If the `x-size' operation is both
     defined and returns a value other than `#f', that value is returned
     as the result of this procedure.  Otherwise, `output-port/x-size'
     returns a default value (currently `80').

     `output-port/x-size' is useful for programs that tailor their
     output to the width of the display (a fairly common practice).  If
     the output device is not a display, such programs normally want
     some reasonable default width to work with, and this procedure
     provides exactly that.

 - procedure: output-port/y-size output-port
     This procedure invokes the custom operation whose name is the
     symbol `y-size', if it exists.  If the `y-size' operation is
     defined, the value it returns is returned as the result of this
     procedure; otherwise, `#f' is returned.

Blocking Mode
-------------

   An interactive port is always in one of two modes: "blocking" or
"non-blocking".  This mode is independent of the terminal mode: each
can be changed independent of the other.  Furthermore, if it is an
interactive I/O port, there are separate blocking modes for input and
for output.

   If an input port is in blocking mode, attempting to read from it
when no input is available will cause Scheme to "block", i.e. suspend
itself, until input is available.  If an input port is in non-blocking
mode, attempting to read from it when no input is available will cause
the reading procedure to return immediately, indicating the lack of
input in some way (exactly how this situation is indicated is separately
specified for each procedure or operation).

   An output port in blocking mode will block if the output device is
not ready to accept output.  In non-blocking mode it will return
immediately after performing as much output as the device will allow
(again, each procedure or operation reports this situation in its own
way).

   Interactive ports are initially in blocking mode; this can be
changed at any time with the procedures defined in this section.

   These procedures represent blocking mode by the symbol `blocking',
and non-blocking mode by the symbol `nonblocking'.  An argument called
MODE must be one of these symbols.  A PORT argument to any of these
procedures may be any port, even if that port does not support blocking
mode; in that case, the port is not modified in any way.

 - procedure: port/input-blocking-mode port
     Returns the input blocking mode of PORT.

 - procedure: port/set-input-blocking-mode port mode
     Changes the input blocking mode of PORT to be MODE.  Returns an
     unspecified value.

 - procedure: port/with-input-blocking-mode port mode thunk
     THUNK must be a procedure of no arguments.
     `port/with-input-blocking-mode' binds the input blocking mode of
     PORT to be MODE, executes THUNK, restores the input blocking mode
     of PORT to what it was when `port/with-input-blocking-mode' was
     called, and returns the value that was yielded by THUNK.  This
     binding is performed by `dynamic-wind', which guarantees that the
     input blocking mode is restored if THUNK escapes from its
     continuation.

 - procedure: port/output-blocking-mode port
     Returns the output blocking mode of PORT.

 - procedure: port/set-output-blocking-mode port mode
     Changes the output blocking mode of PORT to be MODE.  Returns an
     unspecified value.

 - procedure: port/with-output-blocking-mode port mode thunk
     THUNK must be a procedure of no arguments.
     `port/with-output-blocking-mode' binds the output blocking mode of
     PORT to be MODE, executes THUNK, restores the output blocking mode
     of PORT to what it was when `port/with-output-blocking-mode' was
     called, and returns the value that was yielded by THUNK.  This
     binding is performed by `dynamic-wind', which guarantees that the
     output blocking mode is restored if THUNK escapes from its
     continuation.

Terminal Mode
-------------

   A port that reads from or writes to a terminal has a "terminal
mode"; this is either "cooked" or "raw".  This mode is independent of
the blocking mode: each can be changed independent of the other.
Furthermore, a terminal I/O port has independent terminal modes both
for input and for output.

   A terminal port in cooked mode provides some standard processing to
make the terminal easy to communicate with.  For example, under unix,
cooked mode on input reads from the terminal a line at a time and
provides rubout processing within the line, while cooked mode on output
might translate linefeeds to carriage-return/linefeed pairs.  In
general, the precise meaning of cooked mode is operating-system
dependent, and furthermore might be customizable by means of operating
system utilities.  The basic idea is that cooked mode does whatever is
necessary to make the terminal handle all of the usual user-interface
conventions for the operating system, while keeping the program's
interaction with the port as normal as possible.

   A terminal port in raw mode disables all of that processing.  In raw
mode, characters are directly read from and written to the device
without any translation or interpretation by the operating system.  On
input, characters are available as soon as they are typed, and are not
echoed on the terminal by the operating system.  In general, programs
that put ports in raw mode have to know the details of interacting with
the terminal.  In particular, raw mode is used for writing programs such
as text editors.

   Terminal ports are initially in cooked mode; this can be changed at
any time with the procedures defined in this section.

   These procedures represent cooked mode by the symbol `cooked', and
raw mode by the symbol `raw'.  Additionally, the value `#f' represents
"no mode"; it is the terminal mode of a port that is not a terminal.
An argument called MODE must be one of these three values.  A PORT
argument to any of these procedures may be any port, even if that port
does not support terminal mode; in that case, the port is not modified
in any way.

 - procedure: port/input-terminal-mode port
     Returns the input terminal mode of PORT.

 - procedure: port/set-input-terminal-mode port mode
     Changes the input terminal mode of PORT to be MODE.  Returns an
     unspecified value.

 - procedure: port/with-input-terminal-mode port mode thunk
     THUNK must be a procedure of no arguments.
     `port/with-input-terminal-mode' binds the input terminal mode of
     PORT to be MODE, executes THUNK, restores the input terminal mode
     of PORT to what it was when `port/with-input-terminal-mode' was
     called, and returns the value that was yielded by THUNK.  This
     binding is performed by `dynamic-wind', which guarantees that the
     input terminal mode is restored if THUNK escapes from its
     continuation.

 - procedure: port/output-terminal-mode port
     Returns the output terminal mode of PORT.

 - procedure: port/set-output-terminal-mode port mode
     Changes the output terminal mode of PORT to be MODE.  Returns an
     unspecified value.

 - procedure: port/with-output-terminal-mode port mode thunk
     THUNK must be a procedure of no arguments.
     `port/with-output-terminal-mode' binds the output terminal mode of
     PORT to be MODE, executes THUNK, restores the output terminal mode
     of PORT to what it was when `port/with-output-terminal-mode' was
     called, and returns the value that was yielded by THUNK.  This
     binding is performed by `dynamic-wind', which guarantees that the
     output terminal mode is restored if THUNK escapes from its
     continuation.

Parser Buffers
==============

   The "parser buffer" mechanism facilitates construction of parsers
for complex grammars.  It does this by providing an input stream with
unbounded buffering and backtracking.  The amount of buffering is under
program control.  The stream can backtrack to any position in the
buffer.

   The mechanism defines two data types: the "parser buffer" and the
"parser-buffer pointer".  A parser buffer is like an input port with
buffering and backtracking.  A parser-buffer pointer is a pointer into
the stream of characters provided by a parser buffer.

   Note that all of the procedures defined here consider a parser buffer
to contain a stream of 8-bit characters in the ISO-8859-1 character
set, except for `match-utf8-char-in-alphabet' which treats it as a
stream of Unicode characters encoded as 8-bit bytes in the UTF-8
encoding.

   There are several constructors for parser buffers:

 - procedure: input-port->parser-buffer port
     Returns a parser buffer that buffers characters read from PORT.

 - procedure: substring->parser-buffer string start end
     Returns a parser buffer that buffers the characters in the argument
     substring.  This is equivalent to creating a string input port and
     calling `input-port->parser-buffer', but it runs faster and uses
     less memory.

 - procedure: string->parser-buffer string
     Like `substring->parser-buffer' but buffers the entire string.

 - procedure: source->parser-buffer source
     Returns a parser buffer that buffers the characters returned by
     calling SOURCE.  SOURCE is a procedure of three arguments: a
     string, a start index, and an end index (in other words, a
     substring specifier).  Each time SOURCE is called, it writes some
     characters in the substring, and returns the number of characters
     written.  When there are no more characters available, it returns
     zero.  It must not return zero in any other circumstance.

   Parser buffers and parser-buffer pointers may be distinguished from
other objects:

 - procedure: parser-buffer? object
     Returns `#t' if OBJECT is a parser buffer, otherwise returns `#f'.

 - procedure: parser-buffer-pointer? object
     Returns `#t' if OBJECT is a parser-buffer pointer, otherwise
     returns `#f'.

   Characters can be read from a parser buffer much as they can be read
from an input port.  The parser buffer maintains an internal pointer
indicating its current position in the input stream.  Additionally, the
buffer remembers all characters that were previously read, and can look
at characters arbitrarily far ahead in the stream.  It is this
buffering capability that facilitates complex matching and backtracking.

 - procedure: read-parser-buffer-char buffer
     Returns the next character in BUFFER, advancing the internal
     pointer past that character.  If there are no more characters
     available, returns `#f' and leaves the internal pointer unchanged.

 - procedure: peek-parser-buffer-char buffer
     Returns the next character in BUFFER, or `#f' if no characters are
     available.  Leaves the internal pointer unchanged.

 - procedure: parser-buffer-ref buffer index
     Returns a character in BUFFER.  INDEX is a non-negative integer
     specifying the character to be returned.  If INDEX is zero,
     returns the next available character; if it is one, returns the
     character after that, and so on.  If INDEX specifies a position
     after the last character in BUFFER, returns `#f'.  Leaves the
     internal pointer unchanged.

   The internal pointer of a parser buffer can be read or written:

 - procedure: get-parser-buffer-pointer buffer
     Returns a parser-buffer pointer object corresponding to the
     internal pointer of BUFFER.

 - procedure: set-parser-buffer-pointer! buffer pointer
     Sets the internal pointer of BUFFER to the position specified by
     POINTER.  POINTER must have been returned from a previous call of
     `get-parser-buffer-pointer' on BUFFER.  Additionally, if some of
     BUFFER's characters have been discarded by
     `discard-parser-buffer-head!', POINTER must be outside the range
     that was discarded.

 - procedure: get-parser-buffer-tail buffer pointer
     Returns a newly-allocated string consisting of all of the
     characters in BUFFER that fall between POINTER and BUFFER's
     internal pointer.  POINTER must have been returned from a previous
     call of `get-parser-buffer-pointer' on BUFFER.  Additionally, if
     some of BUFFER's characters have been discarded by
     `discard-parser-buffer-head!', POINTER must be outside the range
     that was discarded.

 - procedure: discard-parser-buffer-head! buffer
     Discards all characters in BUFFER that have already been read; in
     other words, all characters prior to the internal pointer.  After
     this operation has completed, it is no longer possible to move the
     internal pointer backwards past the current position by calling
     `set-parser-buffer-pointer!'.

   The next rather large set of procedures does conditional matching
against the contents of a parser buffer.  All matching is performed
relative to the buffer's internal pointer, so the first character to be
matched against is the next character that would be returned by
`peek-parser-buffer-char'.  The returned value is always `#t' for a
successful match, and `#f' otherwise.  For procedures whose names do
not end in `-no-advance', a successful match also moves the internal
pointer of the buffer forward to the end of the matched text; otherwise
the internal pointer is unchanged.

 - procedure: match-parser-buffer-char buffer char
 - procedure: match-parser-buffer-char-ci buffer char
 - procedure: match-parser-buffer-not-char buffer char
 - procedure: match-parser-buffer-not-char-ci buffer char
 - procedure: match-parser-buffer-char-no-advance buffer char
 - procedure: match-parser-buffer-char-ci-no-advance buffer char
 - procedure: match-parser-buffer-not-char-no-advance buffer char
 - procedure: match-parser-buffer-not-char-ci-no-advance buffer char
     Each of these procedures compares a single character in BUFFER to
     CHAR.  The basic comparison `match-parser-buffer-char' compares
     the character to CHAR using `char=?'.  The procedures whose names
     contain the `-ci' modifier do case-insensitive comparison (i.e.
     they use `char-ci=?').  The procedures whose names contain the
     `not-' modifier are successful if the character _doesn't_ match
     CHAR.

 - procedure: match-parser-buffer-char-in-set buffer char-set
 - procedure: match-parser-buffer-char-in-set-no-advance buffer char-set
     These procedures compare the next character in BUFFER against
     CHAR-SET using `char-set-member?'.

 - procedure: match-parser-buffer-string buffer string
 - procedure: match-parser-buffer-string-ci buffer string
 - procedure: match-parser-buffer-string-no-advance buffer string
 - procedure: match-parser-buffer-string-ci-no-advance buffer string
     These procedures match STRING against BUFFER's contents.  The
     `-ci' procedures do case-insensitive matching.

 - procedure: match-parser-buffer-substring buffer string start end
 - procedure: match-parser-buffer-substring-ci buffer string start end
 - procedure: match-parser-buffer-substring-no-advance buffer string
          start end
 - procedure: match-parser-buffer-substring-ci-no-advance buffer string
          start end
     These procedures match the specified substring against BUFFER's
     contents.  The `-ci' procedures do case-insensitive matching.

 - procedure: match-utf8-char-in-alphabet buffer alphabet
     This procedure treats BUFFER's contents as UTF-8 encoded Unicode
     characters and matches the next such character against ALPHABET,
     which must be a Unicode alphabet (see Unicode).  UTF-8
     represents characters with 1 to 6 bytes, so a successful match can
     move the internal pointer forward by as many as 6 bytes.

   The remaining procedures provide information that can be used to
identify locations in a parser buffer's stream.

 - procedure: parser-buffer-position-string pointer
     Returns a string describing the location of POINTER in terms of
     its character and line indexes.  This resulting string is meant to
     be presented to an end user in order to direct their attention to a
     feature in the input stream.  In this string, the indexes are
     presented as one-based numbers.

     POINTER may alternatively be a parser buffer, in which case it is
     equivalent to having specified the buffer's internal pointer.

 - procedure: parser-buffer-pointer-index pointer
 - procedure: parser-buffer-pointer-line pointer
     Returns the character or line index, respectively, of POINTER.
     Both indexes are zero-based.

Parser Language
===============

   Although it is possible to write parsers using the parser-buffer
abstraction (see Parser Buffers), it is tedious.  The problem is
that the abstraction isn't closely matched to the way that people think
about syntactic structures.  In this section, we introduce a
higher-level mechanism that greatly simplifies the implementation of a
parser.

   The "parser language" described here allows the programmer to write
BNF-like specifications that are translated into efficient Scheme code
at compile time.  The language is declarative, but it can be freely
mixed with Scheme code; this allows the parsing of grammars that aren't
conveniently described in the language.

   The language also provides backtracking.  For example, this
expression matches any sequence of alphanumeric characters followed by
a single alphabetic character:

     (*matcher
      (seq (* (char-set char-set:alphanumeric))
           (char-set char-set:alphabetic)))

The way that this works is that the matcher matches alphanumeric
characters in the input stream until it finds a non-alphanumeric
character.  It then tries to match an alphabetic character, which of
course fails.  At this point, if it matched at least one alphanumeric
character, it _backtracks_: the last matched alphanumeric is
"unmatched", and it again attempts to match an alphabetic character.
The backtracking can be arbitrarily deep; the matcher will continue to
back up until it finds a way to match the remainder of the expression.

   So far, this sounds a lot like regular-expression matching (see
Regular Expressions).  However, there are some important differences.

   * The parser language uses a Scheme-like syntax that is easier to
     read and write than regular-expression notation.

   * The language provides macros so that common syntactic constructs
     can be abstracted.

   * The language mixes easily with Scheme code, allowing the full
     power of Scheme to be applied to program around limitations in the
     parser language.

   * The language provides expressive facilities for converting syntax
     into parsed structure.  It also makes it easy to convert parsed
     strings into meaningful objects (e.g. numbers).

   * The language is compiled into machine language; regular expressions
     are usually interpreted.

   Here is an example that shows off several of the features of the
parser language.  The example is a parser for XML start tags:

     (*parser
      (with-pointer p
        (seq "<"
             parse-name
             parse-attribute-list
             (alt (match ">")
                  (match "/>")
                  (sexp
                   (lambda (b)
                     (error
                      (string-append
                       "Unterminated start tag at "
                       (parser-buffer-position-string p)))))))))

This shows that the basic description of a start tag is very similar to
its BNF.  Non-terminal symbols `parse-name' and `parse-attribute-list'
do most of the work, and the noise strings `"<"' and `">"' are the
syntactic markers delimiting the form.  There are two alternate endings
for start tags, and if the parser doesn't find either of the endings,
the Scheme code (wrapped in `sexp') is run to signal an error.  The
error procedure `perror' takes a pointer `p', which it uses to indicate
the position in the input stream at which the error occurred.  In this
case, that is the beginning of the start tag, i.e. the position of the
leading `"<"' marker.

   This example still looks pretty complicated, mostly due to the
error-signalling code.  In practice, this is abstracted into a macro,
after which the expression is quite succinct:

     (*parser
      (bracket "start tag"
          (seq (noise (string "<")) parse-name)
          (match (alt (string ">") (string "/>")))
        parse-attribute-list))

The `bracket' macro captures the pattern of a bracketed item, and hides
much of the detail.

   The parser language actually consists of two languages: one for
defining matchers, and one for defining parsers.  The languages are
intentionally very similar, and are meant to be used together.  Each
sub-language is described below in its own section.

   The parser language is a run-time-loadable option; to use it, execute

     (load-option '*parser)

once before compiling any code that uses the language.