home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-27 | 12.4 KB | 280 lines | [TEXT/CCL2] |
-
- ;;;=========================================================================
- ;;; Top-level command loop
- ;;;=========================================================================
-
-
- (define *init-complete* '#f)
-
- ;;; The savesys code arranges for this function to be called at
- ;;; startup time.
-
- (define (heval)
- (initialize-haskell-system)
- (format '#t "~&Yale Haskell ~A~A ~A~%Type :? for help.~%"
- *haskell-compiler-version*
- *haskell-compiler-update*
- (identify-system))
- (funcall *haskell-initialize-hook*)
- (do () ('#f)
- (let/cc croak
- (dynamic-let ((*abort-compilation*
- (lambda ()
- (when *haskell-compilation-error-hook*
- (funcall *haskell-compilation-error-hook*))
- (funcall croak '#f)))
- (*abort-phase* '#f)
- (*phase* 'toplevel)
- (*in-error-handler* '#f))
- (funcall *haskell-command-hook*)))))
-
-
- ;;; This is an alternative entry point for emulating a standalone
- ;;; executable.
-
- (define (hrun file args)
- (initialize-haskell-system)
- (funcall *haskell-initialize-hook*)
- (let/cc croak
- (dynamic-let ((*abort-compilation*
- (lambda ()
- (when *haskell-compilation-error-hook*
- (funcall *haskell-compilation-error-hook*))
- (funcall croak '#f)))
- (*abort-phase* '#f)
- (*phase* 'toplevel)
- (*in-error-handler* '#f))
- (compile/run file args)
- (force-output)
- (exit))))
-
-
-
- ;;;=========================================================================
- ;;; Eval and run in extension
- ;;;=========================================================================
-
- (define (haskell-eval exp extension-name extension module-name maybe-file)
- (declare (ignore extension-name))
- (when (memq 'interactive (dynamic *printers*))
- (format '#t "~%Evaluating ~a...~%" exp))
- (when maybe-file
- (compile/load maybe-file))
- (let* ((module (find-executable-module module-name))
- (module+pad (add-pad-definitions module extension)))
- (haskell-exec-aux
- exp
- (format '#f "~A = putText (~a)~%" *magic-temp-name* exp)
- module+pad
- )))
-
- (define (haskell-run exp extension-name extension module-name maybe-file)
- (declare (ignore extension-name))
- (when (memq 'interactive (dynamic *printers*))
- (format '#t "~%Running ~a...~%" exp))
- (when maybe-file
- (compile/load maybe-file))
- (let* ((module (find-executable-module module-name))
- (module+pad (add-pad-definitions module extension)))
- (haskell-exec-aux
- exp
- (format '#f "~a = ~a~%~a :: IO ()~%"
- *magic-temp-name* exp *magic-temp-name*)
- module+pad)))
-
- (define (haskell-run-print exp extension-name extension module-name maybe-file)
- (declare (ignore extension-name))
- (when (memq 'interactive (dynamic *printers*))
- (format '#t "~%Running ~a...~%" exp))
- (when maybe-file
- (compile/load maybe-file))
- (let* ((module (find-executable-module module-name))
- (module+pad (add-pad-definitions module extension)))
- (haskell-exec-aux
- exp
- (format '#f "~a = (~a) >>= putText~%~a :: IO ()~%"
- *magic-temp-name* exp *magic-temp-name*)
- module+pad)))
-
-
- (define (haskell-report-type exp extension-name extension
- module-name maybe-file)
- (declare (ignore extension-name))
- (when (memq 'interactive (dynamic *printers*))
- (format '#t "~%Type checking ~a...~%" exp))
- (when maybe-file
- (compile/load maybe-file))
- (let* ((module (find-executable-module module-name))
- (module+pad (add-pad-definitions module extension)))
- (haskell-report-type-aux
- exp
- (format '#f "~A = ~A~%" *magic-temp-name* exp)
- module+pad)))
-
- (define (add-pad-definitions module pad)
- (if (string=? pad "")
- module
- (dynamic-let ((*printers*
- (if (memq 'pad (dynamic *printers*))
- (dynamic *printers*)
- (if (memq 'time *printers*)
- '(time)
- '()))))
- (let ((new-module
- (parse-fragment
- (module-name module)
- "-pad"
- pad
- (format '#f "~A pad" (module-name module))
- '#t)))
- (fragment-initialize new-module module)
- (eval (modules->lisp-code (list new-module)))
- new-module))))
-
- (define (haskell-exec-aux extension-name fragment module)
- (dynamic-let ((*printers* '()))
- (prepare-execution)
- (let ((new-module (parse-fragment
- (module-name module)
- "-exp"
- fragment
- extension-name
- '#f)))
- (fragment-initialize new-module module)
- (eval (modules->lisp-code (list new-module)))
- (run-dialogue *magic-temp-name* new-module)
- new-module)))
-
- (define (haskell-report-type-aux extension-name fragment module)
- (dynamic-let ((*printers* '()))
- (let ((new-module (parse-fragment
- (module-name module)
- "-exp"
- fragment
- extension-name
- '#f)))
- (fragment-initialize new-module module)
- (modules->lisp-code (list new-module))
- (report-type fragment *magic-temp-name* new-module)
- new-module)))
-
-
- ;;; Helper functions for above
-
- (define (parse-fragment mod-name mod-type fragment filename has-lines?)
- (let* ((new-mod-name (string-append (symbol->string mod-name) mod-type))
- (module (parse-module-body-from-string
- (string->symbol new-mod-name)
- fragment
- filename
- has-lines?)))
- (when (not (null? (module-imports module)))
- (signal-import-decl-in-extension))
- module))
-
- (define (signal-import-decl-in-extension)
- (fatal-error 'import-decl-in-extension
- "Import declarations are not allowed in scratch pads."))
-
-
- (define (fragment-initialize new old)
- (setf (module-type new) 'extension)
- (setf (module-unit new) (module-unit old))
- (setf (module-uses-standard-prelude? new)
- (module-uses-standard-prelude? old))
- (setf (module-inherited-env new) old)
- (setf (module-fixity-table new)
- (copy-table (module-fixity-table old)))
- (setf (module-default new) (module-default old)))
-
-
- (define (report-type exp name module)
- (let ((var (table-entry (module-symbol-table module) name)))
- (if (var? var)
- (format '#t "~&~A :: ~A~%" exp (var-type var))
- (signal-no-definition-of-var name module))))
-
-
-
- ;;;=========================================================================
- ;;; Support for operations on files
- ;;;=========================================================================
-
- ;;; This keeps track of modules which are currently available.
-
- (define *modules-available* '())
-
-
- ;;; These both load the code associated with the file
- ;;; Do NOT mess with the return values from these functions.
- ;;; The stuff in vanilla.scm depends on getting the unit back.
-
- (define (compile/compile file)
- (compile/common file *compile/compile-cflags*))
-
- (define (compile/load file)
- (compile/common file *compile/load-cflags*))
-
- (define (compile/common file flags)
- (let ((unit (haskell-compile file flags)))
- (setf *modules-available* (ucache-modules unit))
- unit))
-
-
-
- ;;; This loads the compilation unit, then runs the dialogue called
- ;;; "main". If there's more than one module, it looks for the one
- ;;; called "Main".
-
- (define *haskell-command-line-args* '())
- (define *haskell-program-name* "haskell")
-
- (define (compile/run file args)
- (let ((unit (compile/load file)))
- (when unit
- (when (memq 'interactive (dynamic *printers*))
- (format '#t "~%Running main...~%"))
- (let ((mod (find-executable-module/inner '|Main|)))
- (unless mod
- (if (eqv? (length (ucache-modules-defined unit)) 1)
- (setf mod (car (ucache-modules unit)))
- (fatal-error 'ambiguous-module "No Main module found.")))
- (dynamic-let ((*haskell-command-line-args* args)
- (*haskell-program-name* file))
- (run-dialogue '|main| mod))))
- unit))
-
-
- (define (find-executable-module mod-name)
- (or (find-executable-module/inner mod-name)
- (signal-module-not-found mod-name)))
-
- (define (find-executable-module/inner mod-name)
- (find-executable-module-1 mod-name *modules-available*))
-
- (define (find-executable-module-1 name mods)
- (if (null? mods)
- '#f
- (if (and (eq? name (module-name (car mods)))
- (not (interface-module? (car mods))))
- (car mods)
- (find-executable-module-1 name (cdr mods)))))
-
- (define (signal-module-not-found mod-name)
- (fatal-error 'module-not-found
- "Module ~a is not currently compiled and loaded."
- mod-name))
-
-
-
-
- ;;;=========================================================================
- ;;; Support for running dialogues
- ;;;=========================================================================
-
- (define (run-dialogue name module)
- (let ((var (table-entry (module-symbol-table module) name)))
- (cond ((not var)
- (signal-no-definition-of-var name module))
- ((not (is-dialogue? var))
- (signal-var-not-dialogue var modul