


                       LittleScheme Version 0.9

This software is open source, covered by a BSD-style license.
Please read accompanying file license.txt.                                   
-------------------------------------------------------------------------------
    This Scheme interpreter is based on Tinyscheme version 1.31 by
    D. Souflis (dsouflis@acm.org).  He in turn based it on  MiniSCHEME 
    version 0.85k4 (see miniscm.tar.gz in the Scheme Repository)
    Original credits at end of file.

    Charles Hayden (chayden@comcast.net)

-------------------------------------------------------------------------------

     What is LittleScheme?
     -------------------

     LittleScheme is a lightweight Scheme interpreter that implements as large
     a subset of R5RS as was possible without getting very large and
     complicated. It is meant to be used as an embedded scripting interpreter
     for other programs. As such, it does not offer IDEs or extensive toolkits
     although it does sport a small top-level loop, included conditionally.
     Some functionality in LittleScheme is included conditionally, to allow
     developers freedom in balancing features and footprint.

    The main difference between LittleScheme and its predecessor TinyScheme
    is that LittleScheme is implemented in C++ and one or more  scheme 
    interpreters can be instantiated as objects.  Tinyscheme did this also,
    but it was somewhat awkward.

    As an embedded interpreter, it allows multiple interpreter states to
    coexist in the same program, without any interference between them.
    Programmatically, foreign functions in C can be added and values
    can be defined in the Scheme environment. Being a quite small program,
    it is easy to comprehend, get to grips with, and use. 

    In addition to shifting to an object-based interface, the implementation
    has been completely reorganized to take advantage of C++.  Along the way
    a number of additional capabilities have been added and the implementation
    has been improved in many ways. 

    A few things were removed from TinyScheme because they did not work
    in Win32.  Foremost among these was dynamic loading.  LittleScheme
    has been compiled and tested on Visual C++ 6.0 on Windows NT.


     Things that keep missing, or that need fixing
     ---------------------------------------------

     There are no hygienic macros. No rational or
     complex numbers. No unwind-protect and call-with-values.


     Change Log
     ----------
     0.9	January 22, 2003
     First public release of LittleScheme.
	 
     Scheme Reference
     ----------------

     If something seems to be missing, please refer to the code and
     "init.scm", since some are library functions.  Refer to the MiniSCHEME
     readme as a last resort.

     Environments
     (interaction-environment)
     See R5RS. In TinySCHEME, immutable list of association lists.

     (current-environment)
     The environment in effect at the time of the call. An example of its
     use and its utility can be found in the sample code that implements
     packages in "init.scm":

          (macro (package form)
               `(apply (lambda ()
                         ,@(cdr form)
                         (current-environment))))

     The environment containing the (local) definitions inside the closure
     is returned as an immutable value.

     (defined? <symbol>) (defined? <symbol> <environment>)
     Checks whether the given symbol is defined in the current (or given)
     environment.

     Symbols
     (gensym)
     Returns a new interned symbol each time. Will probably move to the
     library when string->symbol is implemented.

          Directives
     (gc)
     Performs garbage collection immediatelly.

     (gcverbose) (gcverbose <bool>)
     The argument (defaulting to #t) controls whether GC produces
     visible outcome.

     (quit) (quit <num>)
     Stops the interpreter and sets the 'retcode' internal field (defaults
     to 0). When standalone, 'retcode' is returned as exit code to the OS.

     (tracing <num>)
     1, turns on tracing. 0 turns it off. (Only when USE_TRACING is 1).

     Mathematical functions
     Since rationals and complexes are absent, the respective functions
     are also missing.
     Supported: exp, log, sin, cos, tan, asin, acos, atan, floor, ceiling,
     trunc, round and also sqrt and expt.
     Number-theoretical quotient, remainder and modulo, gcd, lcm,
     exact?, inexact?, odd?, even?, zero?, positive?, negative?,
     exact->inexact, inexact->exact is a core function.

     Type predicates
     boolean?,eof-object?,symbol?,number?,string?,integer?,real?,list?,null?,
     char?,port?,input-port?,output-port?,procedure?,pair?,environment?',
     vector?. Also closure?, macro?.

     Types
     Types supported:

          Numbers (integers and reals)
          Symbols
          Pairs
          Strings
          Characters
          Ports
          Eof object
          Environments
          Vectors

     Literals
     String literals can contain escaped quotes \" as usual, but also
     \n, \r, \t and \xDD (hex representations). Note also that it is 
     possible to include literal newlines in string literals, e.g.

          (define s "String with newline here
          and here
          that can function like a HERE-string")

     Character literals contain #\space and #\newline and are supplemented
     with #\return and #\tab, with obvious meanings. Hex character
     representations are allowed (e.g. #\x20 is #\space).
     When USE_ASCII_NAMES is defined, various control characters can be
     refered to by their ASCII name.
     0	     #\nul	       17       #\dc1
     1	     #\soh             18       #\dc2
     2	     #\stx             19       #\dc3
     3	     #\etx             20       #\dc4
     4	     #\eot             21       #\nak
     5	     #\enq             22       #\syn
     6	     #\ack             23       #\etv
     7	     #\bel             24       #\can
     8	     #\bs              25       #\em
     9	     #\ht              26       #\sub
     10	     #\lf              27       #\esc
     11	     #\vt              28       #\fs
     12	     #\ff              29       #\gs
     13	     #\cr              30       #\rs
     14	     #\so              31       #\us
     15	     #\si
     16	     #\dle             127      #\del 		
     
     Numeric literals support #x #o #b and #d. Flonums are currently read only
     in decimal notation. Full grammar will be supported soon.

     Quote, quasiquote etc.
     As usual.

     Immutable values
     Immutable pairs cannot be modified by set-car! and set-cdr!.
     Immutable strings cannot be modified via string-set!

     I/O
     As per R5RS, plus String Ports (see below).
     current-input-port, current-output-port,
     close-input-port, close-output-port, input-port?, output-port?,
     open-input-file, open-output-file.
     read, write, display, newline, write-char, read-char, peek-char.
     char-ready? returns #t only for string ports, because there is no
     portable way in stdio to determine if a character is available.
     Also open-input-output-file, set-input-port, set-output-port (not R5RS)
     Library: call-with-input-file, call-with-output-file,
     with-input-from-file, with-output-from-file and
     with-input-output-from-to-files, close-port and input-output-port? 
     (not R5RS).
     String Ports: open-input-string, open-output-string,
     open-input-output-string. Strings can be used with I/O routines.

     Vectors
     make-vector, vector, vector-length, vector-ref, vector-set!, list->vector,
     vector-fill!, vector->list, vector-equal? (auxiliary function, not R5RS)

     Strings
     string, make-string, list->string, string-length, string-ref, string-set!,
     substring, string->list, string-fill!, string-append, string-copy.
     string=?, string<?, string>?, string>?, string<=?, string>=?.
     (No string-ci*? yet). string->number, number->string. Also atom->string,
     string->atom (not R5RS).

     Symbols
     symbol->string, string->symbol

     Characters
     integer->char, char->integer.
     char=?, char<?, char>?, char<=?, char>=?.
     (No char-ci*?)

     Pairs & Lists
     cons, car, cdr, list, length, map, for-each, foldr, list-tail,
     list-ref, last-pair, reverse, append.
     Also member, memq, memv, assoc, assq, assv.

     Streams
     head, tail, cons-stream

     Control features
     Apart from procedure?, also macro? and closure?
     map, for-each, force, delay, call-with-current-continuation (or call/cc),
     eval, apply. 'Forcing' a value that is not a promise produces the value.
     There is no call-with-values, values, nor dynamic-wind. Dynamic-wind in
     the presence of continuations would require support from the abstract
     machine itself.

     Property lists
     LittleScheme inherited from MiniScheme property lists for symbols.
     put, get.
     
     Esoteric procedures
     (oblist)
     Returns the oblist, an immutable list of all the symbols.

     (macro-expand <form>)
     Returns the expanded form of the macro call denoted by the argument

     (define-with-return (<procname> <args>...) <body>)
     Like plain 'define', but makes the continuation available as 'return'
     inside the procedure. Handy for imperative programs.

     (new-segment <num>)
     Allocates more memory segments.

     defined?
     See "Environments"

     (get-closure-code <closure>)
     Gets the code as scheme data.

     (make-closure <code> <environment>)
     Makes a new closure in the given environment.

     Obsolete procedures
     (print-width <object>)          
     
     Programmer's Reference
     ----------------------

     The interpreter state is initialized by creating an instance of 
     a LittleScheme object.  When this object is destroyed, the interpreter
     reclaims all memory that it used.  C++s new and delete are used to
     allocate memory.  If you want a different memory allocation system,
     you can redefine these in the normal way.
     Files and strings can both be loaded using the (overloaded) "load".
     It is a good idea to "load" init.scm before anything else.

     External data for keeping external state (of use to foreign functions)
     can be installed with "set_external_data".
     Foreign functions are installed with "assign_foreign". Additional 
     definitions can be added to the interpreter state, with "define" 
     (this is the way HTTP header data and HTML form data are passed to the 
     Scheme script in the Altera SQL Server). If you wish to define the
     foreign function in a specific environment (to enhance modularity),
     use "assign_foreign_env".

     The procedure "apply0" has been added with persistent scripts in
     mind. Persistent scripts are loaded once, and every time they are needed
     to produce HTTP output, appropriate data are passed through global
     definitions and function "main" is called to do the job. One could
     add easily "apply1" etc.

     
     Foreign Functions
     -----------------

     The user can add foreign functions in C++. For example, a function
     that squares its argument:

          pointer scheme::square(pointer args) {
           if(args != NIL_) {
               if(isnumber(car(args))) {
                    double v = rvalue(car(args));
                    return mk_real(v*v);
               }
           }
           return NIL_;
          }

     You install it with:
     
          assign_foreign(square, "double");

     after initialization.

     Foreign functions can use the external data in the "scheme" struct
     to implement any kind of external state.

     External data are set with the following function:
          void set_external_data(scheme *sc, void *p);

     Standalone
     ----------

     Usage: littlescheme -? 
     or:    littlescheme [<file1> <file2> ...] 
     followed by
	       -1 <file> [<arg1> <arg2> ...]
	       -c <Scheme commands> [<arg1> <arg2> ...]
     assuming that the executable is named littlescheme.

     Use - in the place of a filename to denote stdin.
     The -1 flag is meant for #! usage in shell scripts. If you specify
          #! /somewhere/litlescheme -1
     then littlescheme will be called to process the file. For example, the
     following script echoes the Scheme list of its arguments.

	       #! /somewhere/littlescheme -1
	       (display *args*)

     The -c flag permits execution of arbitrary Scheme code.

     Customizing
     -----------

     The following symbols are defined to default values in scheme.h.
     Use the -D flag of cc to set to either 1 or 0.

     STANDALONE
     Define this to produce a standalone interpreter.

     USE_CHAR_CLASSIFIERS
     Includes character classifier procedures.

     USE_ASCII_NAMES
     Enable extended character notation based on ASCII names.

     USE_STRING_PORTS
     Enables string ports.

     USE_ERROR_HOOK
     To force system errors through user-defined error handling.
     (see "Error handling")

     USE_TRACING
     To enable use of TRACING.

     USE_COLON_HOOK
     Enable use of qualified identifiers. (see "Colon Qualifiers - Packages")
     Defining this as 0 has the rather drastic consequence that any code using
     packages will stop working, and will have to be modified. It should only
     be used if you *absolutely* need to use '::' in identifiers.

     USE_STRCASECMP
     Defines stricmp as strcasecmp, for Unix.

     USE_NO_FEATURES
     Shortcut to disable USE_CHAR_CLASSIFIERS, USE_ASCII_NAMES,
     USE_STRING_PORTS, USE_ERROR_HOOK, USE_TRACING, USE_COLON_HOOK.

     Build instructions
     ------------------

     The VC++ project file builds a scheme library. For 
     demonstration purposes, a standalone interpreter is also included.

     Error Handling
     --------------

     Errors are recovered from without damage. The user can install his
     own handler for system errors, by defining *error-hook*. Defining
     to '() gives the default behavior, which is equivalent to "error".
     USE_ERROR_HOOK must be defined.

     A simple exception handling mechanism can be found in "init.scm".
     A new syntactic form is introduced:

          (catch <expr returned exceptionally>
               <expr1> <expr2> ... <exprN>)

     "Catch" establishes a scope spanning multiple call-frames
     until another "catch" is encountered.

     Exceptions are thrown with:

          (throw "message")

     If used outside a (catch ...), reverts to (error "message").

     Example of use:

          (define (foo x) (write x) (newline) (/ x 0))

          (catch (begin (display "Error!\n") 0)
               (write "Before foo ... ")
               (foo 5)
               (write "After foo"))

     The exception mechanism can be used even by system errors, by

          (define *error-hook* throw)

     which makes use of the error hook described above.

     If necessary, the user can devise his own exception mechanism with
     tagged exceptions etc.


     Reader extensions
     -----------------

     When encountering an unknown character after '#', the user-specified
     procedure *sharp-hook* (if any), is called to read the expression.
     This can be used to extend the reader to handle user-defined constants
     or whatever. It should be a procedure without arguments, reading from
     the current input port (which will be the load-port).


     Colon Qualifiers - Packages
     ---------------------------

     When USE_COLON_HOOK=1:
     The lexer now recognizes the construction <qualifier>::<symbol> and
     transforms it in the following manner (T is the transformation function):

          T(<qualifier>::<symbol>) = (*colon-hook* 'T(<symbol>) <qualifier>)

     where <qualifier> is a symbol not containing any double-colons.

     As the definition is recursive, qualifiers can be nested.
     The user can define his own *colon-hook*, to handle qualified names.
     By default, "init.scm" defines *colon-hook* as EVAL. Consequently,
     the qualifier must denote a Scheme environment, such as one returned
     by (interaction-environment). "Init.scm" defines a new syntantic form,
     PACKAGE, as a simple example. It is used like this:

          (define toto
               (package
                    (define foo 1)
                    (define bar +)))

          foo                                     ==>  Error, "foo" undefined
          (eval 'foo)                             ==>  Error, "foo" undefined
          (eval 'foo toto)                        ==>  1
          toto::foo                               ==>  1
          ((eval 'bar toto) 2 (eval 'foo toto))   ==>  3
          (toto::bar 2 toto::foo)                 ==>  3
          (eval (bar 2 foo) toto)                 ==>  3

     If the user installs another package infrastructure, he must define
     a new 'package' procedure or macro to retain compatibility with supplied
     code.

     Note: Older versions used ':' as a qualifier. Unfortunately, the use
     of ':' as a pseudo-qualifier in existing code (i.e. SLIB) essentially
     precludes its use as a real qualifier.

     O R I G I N A L   C R E D I T S
     -------------------------------
     
     LittleScheme started as TinyScheme, and still retains much from it, even 
     though almost every line of code has changed in some way.  The overall
     architecture of the interpreter and the way it is implemented are taken
     more or less directly from TinyScheme.

     Below are the TinyScheme credits.
     ---------------------------------

     TinyScheme would not exist if it wasn't for MiniScheme. I had just
     written the HTTP server for Ovrimos SQL Server, and I was lamenting the
     lack of a scripting language. Server-side Javascript would have been the
     preferred solution, had there been a Javascript interpreter I could
     lay my hands on. But there weren't. Perl would have been another solution,
     but it was probably ten times bigger that the program it was supposed to
     be embedded in. There would also be thorny licencing issues. 
     
     So, the obvious thing to do was find a trully small interpreter. Forth
     was a language I had once quasi-implemented, but the difficulty of
     handling dynamic data and the weirdness of the language put me off. I then
     looked around for a LISP interpreter, the next thing I knew was easy to
     implement. Alas, the LeLisp I knew from my days in UPMC (Universite Pierre
     et Marie Curie) had given way to Common Lisp, a megalith of a language!
     Then my search lead me to Scheme, a language I knew was very orthogonal
     and clean. When I found Mini-Scheme, a single C file of some 2400 loc, I 
     fell in love with it! What if it lacked floating-point numbers and 
     strings! The rest, as they say, is history.
     
     Below  are the original credits. Don't email Akira KIDA, the address has
     changed.
     
     ---------- Mini-Scheme Interpreter Version 0.85 ----------

                coded by Atsushi Moriwaki (11/5/1989)

            E-MAIL :  moriwaki@kurims.kurims.kyoto-u.ac.jp

               THIS SOFTWARE IS IN THE PUBLIC DOMAIN
               ------------------------------------
 This software is completely free to copy, modify and/or re-distribute.
 But I would appreciate it if you left my name on the code as the author.

  This version has been modified by R.C. Secrist.

  Mini-Scheme is now maintained by Akira KIDA.

  This is a revised and modified version by Akira KIDA.
   current version is 0.85k4 (15 May 1994)

  Please send suggestions, bug reports and/or requests to:
        <SDI00379@niftyserve.or.jp>


     Features compared to TinySCHEME
     -------------------------------

     All code is now C++.  The 'scheme' struct is nos a scheme class.  The
     initialization and deinitialization routines are replaced by constructors
     and destructors.

     An interface class has been introduced, so that the scheme client program does not 
     include the scheme implementation header file, directly or indirectly.  This means
     that the application in which LittleScheme is embedded has not compile-time dependency
     on the classes that implement the scheme interpreter.

     Several primitives that were implemented in init.scm are now implemented directly
     in the interpreter.  Some of these were implemented in C++ to improve speed, but
     most were brought into the interpreter to save cell space.

     The storage for a single cell was reduced from 24 bytes to 10 bytes by (1) separating
     integer and real cell types instead of combining them into one cell type with a flag, 
     and (2) packing to a two byte boundary.

     Various changes were made so that LittleScheme could pass the r4rs test suite.  For instance
     the gcd and lcm primitives were extended to handle 1 argument instead of only two.

     The 'void' type was added.  This is returned from primitives such as define and set! that
     produce undefined results.  The REPL does not display any output for void.  This allows the
     interactive user to make a circular structure without immediately getting into an endless 
     loop trying to display it.

     TinyScheme included two implementations of the capturing of continuations -- one of which
     used lots of cons cells for every application, and another that was much faster but which 
     would not pass the r4rs test suite because it improperly discarded live continuations.  
     LittleScheme combines these two implementations, using the fast one until a continuation
     must be saved, and then switching to the safe one.  When no live continuations remain, it
     reverts to the fast implementation.

     The implementation of vectors has been revised.  In TinyScheme vectors were stored in
     consecutive cells.  In LittleScheme space for vectors is allocated from the heap.  Since
     strings, ports, and the continuation stack are already heap-allocated, it does not hurt
     much to also allocate vectors there.

     A "check" option is provided.  When defined, extra code is included to check for internal
     errors.  For instance, with checking turned on, all access to cells checks the type flags 
     to make sure that it is consistent with the data being accessed.  This has helped to
     identify some subtle trouble spots and to make the code cleaner.

     A number of structural changes are introduced to aid debugging under VC++.  For instance,
     cell flags are separated from the cell types, and the types are now specified using an
     ASCII character, for earier observation through the debugger.

     The interpreter now runs the r4rs test suite completely without any complaints from
     purify, and without leakage.

     Extensive internal documentation was added for use with Doxygen.
     

     TinyScheme Features compared to MiniSCHEME
     -------------------------------

     All code is now reentrant. Interpreter state is held in a 'scheme'
     struct, and many interpreters can coexist in the same program, possibly
     in different threads. The user can specify user-defined memory allocation
     primitives. (see "Programmer's Reference")

     The reader is more consistent.

     Strings, characters and flonums are supported. (see "Types")

     Files being loaded can be nested up to some depth.

     R5RS I/O is there, plus String Ports. (see "Scheme Reference","I/O")

     Vectors exist.

     As a standalone application, it supports command-line arguments.
     (see "Standalone")

     Running out of memory is now handled.

     The user can add foreign functions in C. (see "Foreign Functions")

     The code has been changed slightly, core functions have been moved
     to the library, behavior has been aligned with R5RS etc.

     Support has been added for user-defined error recovery.
     (see "Error Handling")

     Support has been added for modular programming.
     (see "Colon Qualifiers - Packages")

     To enable this, EVAL has changed internally, and can
     now take two arguments, as per R5RS. Environments are supported.
     (see "Colon Qualifiers - Packages")

     Promises are now evaluated once only.

     (macro (foo form) ...) is now equivalent to (macro foo (lambda(form) ...))

     The reader can be extended using new #-expressions
     (see "Reader extensions")







