home *** CD-ROM | disk | FTP | other *** search
- Improvements in V0r2 (over V0r1):
-
- - numerous bugs in numeric code fixed
- - numerous other bugs fixed
- - subdirectory ``slib'' included (for SLIB support)
-
- Improvements in V0r1 (over V0r0):
-
- - bugs fixed
- - new streamlined memory allocator / GC
- - more support for files and file ports
- - VM somewhat faster
- - memory dump format much more compact
- - portability problem in memory dump format eliminated (was
- related to 64 bit machines like the DEC Alpha)
- - error messages (somewhat) improved
-
- Improvements (since vscmIISep29) relevant to public use:
-
- - several bugs fixed
- - support for coroutines added
- - ``ticking'' (to allow for preemptive scheduling)
- - multi-argument continuations
- - interface to some extensions changed
- - I/O interface generalized
- - generic ports added
- - ``string I/O'' added
- - get and put!
-
-
- Command line argument handling:
- ===============================
-
- The following command line switches are recognized by VSCM:
-
- -b bootfile
-
- overrides DEFAULT_BOOTFILE and $VSCMBOOT (a definition of
- the environment variable VSCMBOOT would take precedence
- over DEFAULT_BOOTFILE)
-
- -b -
-
- does not load any bootfile
-
- -a asmfile
-
- reads VSCM assembly code definitions in asmfile after
- loading the bootfile
-
- -a -
-
- reads assembly code in standard input after loading
- the bootfile
-
- -d dumpfile
-
- writes system image into dumpfile immediately after
- reading the bootfile (if any) and processing the asmfile
- (if any).
-
- -p dump_prefix
-
- overrides DEFAULT_DUMP_PREFIX
- this is used for the ``executable'' memory image
- hack (see below)
-
- The processing of these standard options is done left-to-right until
- one of the following events (whichever comes first) occurs:
-
- - there is no further command line argument
- - the next argument does not start with ``-''
- - the next argument is ``-'' by itself
- - the next argument is ``--'' (``--'' will be skipped in this case)
-
- All command line arguments not processed or skipped are passed to the
- Scheme program. In what follows we will refer to those remaining
- arguments as ``the arguments''. Here are the details:
-
- 1. on system startup (default boot image):
-
- - the arguments are stored as a list into the global variable
- command-line-arguments
- - the arguments are interpreted as filenames and LOADed in
- left-to-right order
-
- 2. After returning from ``(dump "filename")''.
-
- - In the program (process) which originally executed
- ``(dump "filename")'' #f will be returned.
- - In a process that was created by running VSCM with
- ``-b filename''
- the call to ``dump'' returns a list of the arguments.
- Note, that ``executing'' a memory image (the file written by
- ``dump'') is equivalent to running VSCM with the appropriate
- ``-b'' switch set.
-
-
- Executable memory images:
- =========================
-
- I incorporated a cute hack suggested by Henry Cejtin (NEC) which
- allows to ``run'' memory images directly. All which needed to be done
- was:
-
- - write a line of the form
- #!/a/path/to/the/vscm/executable/here -b
- into the first line of every memory image
-
- - ignore the first line of every memory image
-
- This works on all Unix systems which have the ``#!'' kernel hack. On
- other systems it will not work (but it will not hurt either). VSCM
- does not set permission bits to make the memory image executable --
- this has to be done manually. (ANSI C does not provide a portable way
- to set permission bits.)
-
-
- Open compilation:
- =================
-
- Calls to the procedures NOT, CONS and any member of the (infinite!)
- CAR/CDR family are ``open compiled'' (aka ``in-lined''). This allows
- for better performance, but strictly speaking it also violates the
- Scheme semantics: A subsequent redefinition of either of these
- functions has no effect any more. Therefore, VSCM (like many other
- Scheme implementations) offers to disable in-lining of these function
- calls by running
-
- (open-compilation #f)
-
- Open compilation can be enabled again using
-
- (open-compilation #t)
-
- The function ``open-compilation'' always returns the old status.
-
- While open compilation is enabled VSCM will refuse to accept any code
- which (possibly) redefines or assigns to an open-compiled primitive.
-
-
- Coroutines:
- ===========
-
- The routines used to work with coroutines in VSCM are described below.
- They can easily be implemented in any R4RS Scheme implementation using
- ``call-with-current-continuation''. Their implementation as
- primitives was done because of efficiency considerations.
-
- The coroutine interface was added to VSCM on demand by Greg Wilson.
-
-
- Continuations with multiple arguments:
- ======================================
-
- VSCM now provides full support for ``call-with-values'' and ``values''.
- Moreover, the new facility was immediately used for other extensions
- like ``divide'' and ``string-read'' (see description below).
-
- Generic ports:
- ==============
-
- VSCM now has a feature called ``generic ports''. Ports are treated as
- an abstract data type supporting a number of operations. (Those are:
- for input ports: read, read-char, peek-char, char-ready?, and close;
- for output ports: write, display, write-char, newline, flush, close.)
-
- VSCM makes no attempt to automatically enforce that ``write'' is
- equivalent to so-many ``write-char''s. The behaviour is completely
- in the hands of the programmer.
-
- A straightforward implementation of ``string ports'' is given in the
- appendix.
-
-
- Reading from and writing to strings:
- ====================================
-
- See description below.
- This feature was added to allow the implementation of string ports (see
- appendix).
-
-
- Rudimentary file system interface:
- ==================================
-
- VSCM now comes with procedures to remove and rename files.
-
-
- File ports are more flexible:
- =============================
-
- The interface to the ``open-*-file'' procedures has been extended in a way
- which resembles fopen's ``mode'' argument. It is possible to select
- binary mode (as opposed to the default text mode), and you can ask for
- permission to ``update'' a file (open for reading and writing at the same
- time). Also, it is possible to specify which kind of buffering
- (full, line, or none) is desired.
-
- A ``seek-and-tell'' procedure was added. which essentially is a
- combination of ``fseek'' and ``ftell''.
-
- In addition to that you can open a ``temporary'' file (which is unnamed
- and which automatically goes away after VSCM quits).
-
-
- The timer:
- ==========
-
- The timer was added to facilitate preemptive scheduling.
-
-
- Get and put!:
- =============
-
- Property lists are now implemented.
-
-
- Character names:
- ================
-
- VSCM provides a somewhat richer syntax to specify character constants.
-
- 1. More symbolic character names:
-
- #\Alarm ~=~ '\a'
- #\Backspace ~=~ '\b'
- #\Tab ~=~ '\t'
- #\Newline ~=~ '\n'
- #\VTab ~=~ '\v'
- #\Return ~=~ '\r'
- #\Escape ~=~ '\033'
- #\Space ~=~ ' '
- #\BackSlash ~=~ '\\'
-
- 2. Decimal, hexadecimal, octal, and binary notation
-
- Decimal:
- #\dn where n is a sequence of [0-9]
- #\Dn
- Hexadecimal:
- #\xn where n is a sequence of [0-9a-fA-F]
- #\Xn
- Octal:
- #\on where n is a sequence of [0-7]
- #\On
- Binary:
- #\bn where n is a sequence of [01]
- #\Bn
-
- The numeric value of n must be within { 0, ..., 255 }, and the 1-1
- mapping from those numeric values to character objects is the same
- as the one used for integer->char and char->integer.
- ______________________________________________________________________________
-
-
- VSCM procedures not present in R4RS -- a brief summary:
- ==============================================================
-
- ;;
- ;; Create a memory image of the running VSCM...
- ;;
-
- (dump "filename")
-
- - writes a memory image into file "filename" (see above)
-
- ;;
- ;; Execute a shell command...
- ;;
-
- (system "shell command")
-
- - return system ("shell command") == 0 ? #t : #f;
-
- ;;
- ;; Continuations with multiple arguments...
- ;;
-
- (call-with-values thunk receiver)
-
- - the R5RS (?) ``call-with-values'' primitive
-
- (values obj ...)
-
- - the R5RS (?) ``values'' primitive
-
- ;;
- ;; Handling errors...
- ;;
-
- (with-error-handler handler thunk)
-
- - equivalent to (thunk) as long as no error occurs
- - calls (handler "error message" ``error-state'') in case of error
- - handler MUST NEVER RETURN
- - ``error-state'' is the continuation of the erroneous computation
- - ``error-state'' CAN NOT BE INVOKED again
- - ``error-state'' is for debugging (error inspection) only
-
- ;;
- ;; Controlling the garbage collector...
- ;;
-
- (with-gc-strategy gc-strategy thunk)
-
- - conceptually equivalent to (thunk) with gc-strategy in effect
- - gc-strategy can be:
- * #t - enables verbose GC messages (statistics)
- * a user-supplied GC strategy (i.e. a Scheme procedure)
-
- ;;
- ;; Handling interrupts...
- ;;
-
- (with-interrupt-handler handler thunk)
-
- - without interrupts equivalent to (thunk)
- - calls (handler) after SIGINT
- - when (handler) returns the the execution of (thunk) resumes
-
- ;;
- ;; Raising an error condition...
- ;;
-
- (error "error message")
-
- - results in error with message "error message"
- - can be caught by with-error-handler
-
- ;;
- ;; Cpu time measurements...
- ;;
-
- (clock)
-
- - returns number of milliseconds spent running VSCM so far
-
- (gc-clock)
-
- - returns number of milliseconds spent in VSCM's garbage
- collector so far
-
- ;;
- ;; Accessing the environment...
- ;;
-
- (getenv "environment variable")
-
- - (getenv "XXX") returns "yyy" if "yyy" is the value of environment
- variable XXX
- - returns #f if XXX is not defined in environment
-
- ;;
- ;; Shutting down the system gracefully...
- ;;
-
- (quit)
-
- - exit (EXIT_SUCCESS);
-
- (quit integer)
-
- - exit (integer);
-
- ;;
- ;; The ubiquitous EVAL...
- ;;
-
- (eval s-expr)
-
- - evaluates s-expr in toplevel environment
-
- ;;
- ;; Controlling open compilation...
- ;;
-
- (open-compilation boolean-flag)
-
- - see above
-
- ;;
- ;; Modified interface to files and file ports...
- ;;
-
- (remove-file "filename")
-
- - does what it says (OS specific)
-
- (rename-file "old-filename" "new-filename")
-
- - does what it says (OS specific)
-
- (with-input-from-port port thunk)
- (with-output-to-port port thunk)
-
- - do the obvious (analogous to ``with-input-from-file'' and
- ``with-output-to-file'')
-
- (open-input-file "filename" [ updt [ binary [ bmode ] ] ])
- (open-output-file "filename" [ updt [ binary [ bmode ] ] ])
-
- - if ``updt'' then "+" is added to fopen's mode (open for update)
- - if ``binary'' then "b" is added to fopen's mode (binary file)
- - bmode == #t -> full buffering
- #f -> no buffering
- else line buffering
- - defaults: updt = #f, binary = #f, bmode = #t
-
- (open-append-file "filename" [ updt [ binary [ bmode ] ] ])
-
- - similar to ``open-output-file''
- - subsequent output operations write to the end of the file (fopen
- is called with mode "a")
-
- (open-temporary-file)
-
- - returns a file port (as if opened with updt = #t, binary = #t,
- bmode = #t)
- - file is anonymous
- - file is automatically removed when port is closed
-
- (close-port port)
-
- - closes any port (``close-input-port'' and ``close-output-port''
- are aliased to this procedure)
-
- (flush [output-port])
-
- - writes any data buffered in the port to the external medium
- - if the argument is missing then the current output port will be
- ``flush''ed
-
- (seek-and-tell port offset whence)
-
- - works for file ports only
- - works only if the restrictions imposed on the undelying
- ``fseek'' are satisfied
- - sets file position to ``w+offset'', where ``w'' is
- - the beginning of the file if ``whence'' is #t
- - the end of the file if ``whence'' is #f
- - the current position otherwise
- - returns the new position (as a number)
-
- (standard-port filedes)
-
- - filedes must be either 0, 1 or 2
- - returns a port object for stdin, stdout or stderr, respectively
-
- ;;
- ;; Generic ports...
- ;;
-
- (open-input-generic read read-char peek-char char-ready? close)
-
- - returns a newly created generic input port object
- - all arguments must be parameterless procedures
- - subsequent calls to the primitives ``read'', ``read-char'',
- ``peek-char'', ``char-ready?'', and ``close-port'' with such a
- port as the (implicit or explicit) argument are transformed
- into calls to the respective procedure associated with the port
-
- (open-output-generic write display write-char newline flush close)
-
- - returns a newly created generic output port object
- - all arguments must be procedures
- - ``write'', ``display'', and ``write-char'' must accept one
- argument
- - ``newline'', ``flush'', and ``close'' are parameterless
- - subsequent calls to the primitives ``write'', ``display'',
- ``write-char'', ``newline'', ``flush'', and ``close-port''
- with such a port as the (implicit or explicit) argument are
- transformed into calls to the respective procedure associated
- with the port
-
- ;;
- ;; ``Writing'' to and ``reading'' from strings...
- ;;
-
- (string-write obj)
-
- - returns a newly allocated string containing the sequence of
- characters that would have been sent to the output port by
- ``(write obj)''
-
- (string-display obj)
-
- - returns a newly allocated string containing the sequence of
- characters that would have been sent to the output port by
- ``(display obj)''
-
- (string-read "string")
-
- - returns TWO values to the caller (similar to ``values'',
- i.e. it requires ``call-with-values'')
- - reads characters from "string" and builds an object just like
- ``read'' does when reading from a file port
- - returns the new object AND a new string which contains the
- remaining characters from the original string
- (white space BEFORE the representation of the object will be
- skipped, but all characters that originally came AFTER the
- object's representation will be returned in the second value)
- - if "string" is empty or contains only white space then
- the first result will be the end-of-file object and the second
- result will be an empty string
-
- Example:
-
- (call-with-values
- (lambda () (string-read "(hello \"world\") @#$% this is Garbage"))
- list)
- =>
- ((hello "world") " @#$% this is Garbage")
-
- ;;
- ;; Another use of multiple values...
- ;;
-
- (divide x y)
-
- - returns TWO values to the caller
- - is defined to behave as if it would be declared by:
-
- (define (divide x y)
- (values (quotient x y)
- (remainder x y)))
-
- - performs only one long division internally
-
- ;;
- ;; Timer...
- ;;
-
- (timer [ticks])
-
- - always returns the number of ticks left in the timer
- - ``(timer 0)'' turns off the timer
- - ``(timer n)'' with ``n'' being an exact integer > 0 sets the
- number of ticks in the timer to ``n''
-
- - the timer turns off itself upon expiration
- - it is an error for the timer to expire with no ``timer expiration
- handler'' defined in the current context
-
- (with-timer-expiration-handler handler thunk)
-
- - both arguments are procedures of 0 arguments
- - ``thunk'' will be called and when the timer expires ``(handler)''
- will run
- - the computation of ``(thunk)'' resumes when ``handler'' returns
-
- ;;
- ;; Coroutines...
- ;;
-
- (cr-create proc)
-
- - returns a new coroutine object
- - ``proc'' is a procedure of one argument, defining the body of the
- new coroutine
- - its argument will be supplied by the first ``cr-transfer''
- to the newly created coroutine
-
- (cr-transfer coroutine obj)
-
- - transfers control to ``coroutine''
- - ``obj'' is supplied to ``coroutine'' as the return value of
- the most recent ``cr-transfer'' which was executed in the body
- of ``coroutine'' or as the argument to ``proc'' (see ``cr-create'')
- - the active coroutine is implicitly suspended
-
- (cr-self)
-
- - returns the coroutine object associated with the active coroutine
-
- ;;
- ;; Property lists:
- ;;
-
- (get <symbol> <property>)
-
- - <symbol> and <property> are Scheme symbols
- - returns the property denoted by <property> of <symbol> or #f
- if <property> was not defined for <symbol>
-
- (put! <symbol> <property> <obj>)
-
- - <symbol> and <property> are Scheme symbols
- - <obj> can be any Scheme object
- - (re-)defines the property <property> for <symbol> to be <obj>
-
- (get-properties <symbol>)
-
- - returns an A-list of <property> - <obj> pairs or #f if no
- properties are defined
-
- (set-properies! <symbol> <a-list>)
-
- - replaces the properties of <symbol> by those defined in the
- A-list <a-list>.
-
- ;;
- ;; Stuff you're not supposed to mess around with... :-)
- ;;
-
- (execute-asm ...)
- (define-asm ...)
- (inspect ...)
-
- - compiler/debugger/VM interface
-
-
- ______________________________________________________________________________
-
- ;;; Appendix: Implementation of string ports using generic ports
-
- (define (open-input-string s)
-
- (let ((l (string-length s))
- (eof (call-with-values (lambda () (string-read "")) (lambda (x y) x))))
-
- (define (read)
- (call-with-values
- (lambda ()
- (string-read s))
- (lambda (obj res)
- (set! s res)
- (set! l (string-length res))
- obj)))
-
- (define (read-char)
- (if (zero? l)
- eof
- (let ((c (string-ref s 0)))
- (set! s (substring s 1 l))
- (set! l (- l 1))
- c)))
-
- (define (peek-char)
- (if (zero? l) eof (string-ref s 0)))
-
- (define (char-ready?) #t)
-
- (define (close) s)
-
- (open-input-generic read read-char peek-char char-ready? close)))
-
- (define (open-output-string)
-
- (let ((s ""))
-
- (define (write x)
- (set! s (string-append s (string-write x)))
- x)
-
- (define (display x)
- (set! s (string-append s (string-display x)))
- x)
-
- (define (write-char x)
- (set! s (string-append s (string x)))
- x)
-
- (define (newline)
- (set! s (string-append s "\n"))
- #f)
-
- (define (flush) #f)
-
- (define (close) s)
-
- (open-output-generic write display write-char newline flush close)))
-