1995-10-13 23:34:21 -04:00
|
|
|
;;; Scsh top level
|
1999-08-06 09:28:52 -04:00
|
|
|
;;; Copyright (c) 1993 by Olin Shivers. See file COPYING.
|
1995-10-13 23:34:21 -04:00
|
|
|
|
|
|
|
;;; Requires
|
|
|
|
;;; From BUILD: build-image
|
|
|
|
;;; From COMMAND: start-command-processor, user-context,
|
|
|
|
;;; package-for-commands
|
|
|
|
|
|
|
|
(define %internal-full-command-line '())
|
|
|
|
(define %internal-command-line-arguments '())
|
|
|
|
(define (command-line) (append %internal-command-line-arguments '()))
|
|
|
|
|
|
|
|
(define scsh-major-version 0)
|
1997-04-21 16:55:48 -04:00
|
|
|
(define scsh-minor-version 5)
|
2001-02-25 14:51:56 -05:00
|
|
|
(define scsh-version-string "0.5.3")
|
1995-10-13 23:34:21 -04:00
|
|
|
|
|
|
|
;;; A scsh starter takes the command line args, parses them,
|
|
|
|
;;; initialises the scsh system, and either starts up a repl loop
|
|
|
|
;;; or executes the -s script.
|
|
|
|
(define (make-scsh-starter)
|
|
|
|
(let ((env (environment-for-commands))
|
|
|
|
(context (user-context)))
|
|
|
|
(lambda (args)
|
|
|
|
(receive (script args) (parse-scsh-args args)
|
|
|
|
(set! command-line-arguments (append args '()))
|
|
|
|
(cond (script ;Batch
|
|
|
|
(set! %internal-command-line-arguments
|
|
|
|
(cons script args))
|
|
|
|
(load-quietly1 script env)
|
|
|
|
0) ; exit code
|
|
|
|
|
|
|
|
(else ; Interactive
|
|
|
|
(with-interaction-environment env
|
|
|
|
(lambda ()
|
|
|
|
(set-batch-mode?! #t)
|
|
|
|
(set! %internal-command-line-arguments
|
|
|
|
(cons "scsh" args))
|
|
|
|
(start-command-processor ""
|
|
|
|
context
|
|
|
|
(lambda ()
|
|
|
|
(display "Scsh ")
|
|
|
|
(display scsh-version-string)
|
|
|
|
(newline)
|
|
|
|
))))))))))
|
|
|
|
|
|
|
|
;;; Make a different kind of starter. This one initialises the
|
|
|
|
;;; scsh run time, then simply calls the user's program.
|
|
|
|
;;;
|
|
|
|
;;; It should take an arg to determine what kind of a condition
|
|
|
|
;;; system you'd like in place.
|
|
|
|
|
|
|
|
(define (make-top-level main)
|
|
|
|
(lambda (args)
|
|
|
|
(set! %internal-full-command-line args)
|
|
|
|
(set! %internal-command-line-arguments (cons "" args))
|
|
|
|
(init-scsh #f #t)
|
|
|
|
(set! command-line-arguments (append args '()))
|
|
|
|
(main)
|
|
|
|
0))
|
|
|
|
|
|
|
|
(define (repl)
|
|
|
|
(command-loop (lambda () (set-batch-mode?! #f))
|
|
|
|
#f))
|
|
|
|
|
|
|
|
|
|
|
|
(define (bad-args arg-list)
|
|
|
|
(error "Bad argument list to scsh.
|
|
|
|
Useage: scsh [<end-option> <arg1> ... <argn>]
|
|
|
|
<end-option>: -s <script-file>
|
|
|
|
-- (Terminates option parsing)" arg-list))
|
|
|
|
|
|
|
|
(define (parse-scsh-args arg-list)
|
|
|
|
(if (pair? arg-list)
|
|
|
|
(let ((arg1 (car arg-list))
|
|
|
|
(rest (cdr arg-list)))
|
|
|
|
(cond ((string=? arg1 "-s")
|
|
|
|
(if (pair? rest)
|
|
|
|
(values (car rest) (cdr rest))
|
|
|
|
(bad-args arg-list)))
|
|
|
|
((string=? arg1 "--") (values #f rest))
|
|
|
|
(else (bad-args arg-list))))
|
|
|
|
(values #f '())))
|
|
|
|
|
|
|
|
|
|
|
|
;;; BUILD-IMAGE calls the starter after installing a fatal top-level
|
|
|
|
;;; error handler. MAKE-SCSH-STARTER shadows it in the interactive case.
|
|
|
|
|
|
|
|
(define (dump-scsh fname)
|
|
|
|
(build-scsh-image (make-scsh-starter) fname))
|
|
|
|
|
|
|
|
(define (dump-scsh-program main fname)
|
|
|
|
(build-scsh-image main fname))
|
|
|
|
|
|
|
|
;;; Hacked because s48's compiler's scanner insists on echoing the file name.
|
|
|
|
|
|
|
|
(define (load-quietly1 fname package)
|
|
|
|
(call-with-input-file fname
|
|
|
|
(lambda (port)
|
|
|
|
(let loop ()
|
|
|
|
(let ((form (read port)))
|
|
|
|
(if (not (eof-object? form))
|
|
|
|
(begin (eval form package)
|
|
|
|
(loop))))))))
|
|
|
|
|
|
|
|
;;; Had to define these as the ones in s48's build.scm do not properly
|
|
|
|
;;; initialise ERROR-OUTPUT-PORT to stderr -- this is a bug in the vm's
|
|
|
|
;;; handoff to the very first Scheme form (it passes two ports -- not three).
|
|
|
|
;;; Until Kelsey fixes these, we hack it with these replacements, which
|
|
|
|
;;; invoke INIT-SCSH, which re-initialises the I/O system to be what
|
|
|
|
;;; you wanted.
|
|
|
|
|
|
|
|
(define (build-scsh-image start filename)
|
|
|
|
(let ((filename (translate filename)))
|
|
|
|
(display (string-append "Writing " filename) (command-output))
|
|
|
|
(newline (command-output))
|
|
|
|
(flush-the-symbol-table!) ;Gets restored at next use of string->symbol
|
|
|
|
(write-image filename
|
|
|
|
(scsh-stand-alone-resumer start)
|
|
|
|
"")
|
|
|
|
#t))
|
|
|
|
|
|
|
|
(define (scsh-stand-alone-resumer start)
|
|
|
|
(usual-resumer ;sets up exceptions, interrupts, and current input & output
|
|
|
|
(lambda (args)
|
|
|
|
(init-scsh #f #f) ; Whatever. Install scsh's I/O system.
|
|
|
|
(call-with-current-continuation
|
|
|
|
(lambda (halt)
|
|
|
|
(set! command-line-arguments (append args '()))
|
|
|
|
(set! %internal-full-command-line args)
|
|
|
|
(set! %internal-command-line-arguments (cons "" args)) ; WRONG
|
|
|
|
(with-handler (simple-condition-handler halt (error-output-port))
|
|
|
|
(lambda ()
|
|
|
|
(start args))))))))
|