(module repl mzscheme
  (require ""
           (lib "" "planet"))

  (define prim-eval (current-eval))
  (define prim-namespace
    (let ((src (current-namespace)))
      (parameterize ((current-namespace (make-namespace 'empty)))
        (namespace-attach-module src 'mzscheme)
         'mzscheme ;; Eventually this should be more restricted, ie:
         #;'(only mzscheme #%app #%top #%datum
                  quote lambda begin define let if set!
                  null? pair? list? cons car cdr
                  map list apply append
                  and > vector? = >= ;; etc.
         '(planet "" ("dvanhorn" "r6rs-expander-vantonder.plt" 3 2)))

        ; FIXME: Mz372 doesn't have nan?, infinite?
        (eval '(define (nan? x)
                 (and (real? x)
                      (not (= x x)))))
        (eval '(define (infinite? x)
                 (and (real? x)
                      (not (nan? x))
                      (nan? (- x x)))))

  (define library-path
    (let-values (((base name must-be-dir?)
                    '(planet "" ("dvanhorn" "r6rs-expander-vantonder.plt" 3 2))))))
      (build-path base "lib/")))
  (parameterize ((read-curly-brace-as-paren #f) ;; Reserved for future use.
                 (read-accept-box #f)
                 (read-accept-compiled #f)
                 (read-accept-graph #f)
                 (read-accept-dot #t)
                 (read-accept-infix-dot #f)
                 (read-accept-quasiquote #t)
                 (read-accept-reader #f)
                 (current-readtable readtable)  ;; Handles #!r6rs, #vu8, etc.
                  (λ () (printf "R6RS> ") 
                    (let ((x (read)))
                      (if (mzprim? x)
                          (namespace-require (mzprim-quoted-require x))
                  (λ (x)
                    (parameterize ((current-eval prim-eval)
                                   (current-namespace prim-namespace))
                      (eval `(ex:repl '(,(if (and (pair? x)
                                                  (eq? '#%top-interaction (car x)))
                                             (cdr x)
    ;; Load all the auxiliary libraries.
    (parameterize ((current-directory library-path)
                    (λ (path expected-module-name)
                      (let ((p (open-input-file path)))
                        (let loop ((x (read p)))
                            ((eof-object? x) (close-input-port p) (values))
                            (else (eval x) (loop (read p)))))))))
      ;; core = core primitives, rest of core libraries.
      ;; simple rnrs = simple rnrs, control, mutable-pairs, r5rs, io simple, mutable-strings ...
      ;; full rnrs = simple rnrs, rest of standard libraries.
      (for-each load (list
                      ;; CORE PRIMITIVES now available.
                      ;; CORE now available.
                      ;; depend only on core primitives.

                      ;; depend only on core.
                      "rnrs/eval/" ;; non-standard
                      ;; RNRS BASE is now available.
                      "rnrs/"         ;; rnrs base, control
                      "rnrs/"          ;; rnrs eval, base, control

                      "rnrs/arithmetic/"         ;; rnrs base, control, r5rs; bitwise core primitives

                      "rnrs/bytevectors/private/"   ;; mz bytes primitives
                      "rnrs/bytevectors/private/"  ;; rnrs base, control; bytevectors core
                      "rnrs/bytevectors/private/"   ;; rnrs base, control, r5rs; bytevectors core, proto
                      "rnrs/bytevectors/private/" ;; rnrs base, control, r5rs, mutable-strings, arithmetic bitwise; bytevectors core, proto
                      "rnrs/"                ;; rnrs bytevectors private core, proto, ieee, string

                      "rnrs/records/private/"       ;; rnrs base, lists {find, forall}, core vector-types
                      "rnrs/records/"         ;; records core
                      "rnrs/records/"         ;; records core
                      "rnrs/records/private/"   ;; rnrs base, records procedural

                      ""     ;; most of rnrs defn'd so far. 
                                    ;; FIXME: needs to provide sorting, bitwise, etc.
                                    ;; FIXME: bug in records procedural, so it's removed from exports.

                      ;; COMPOSITE RNRS is now available.                                             
                      "ubik/"  ;; simple rnrs    
                      "ubik/"     ;; rnrs base

                      "slib/"        ;; mz primitives (FIXME: move after SRFIs)

                      "srfi/"    ;; rnrs base
                      "srfi/"    ;; primitives for srfi 6 (FIXME!)
                      "srfi/"    ;; rnrs base
                      "srfi/"    ;; rnrs base, rnrs records procedural, rnrs records inspection

		      "ubik/" ;; rnrs base, r5rs, arithmetic bitwise; srfi 9.

                      "srfi/"   ;; rnrs base
                      "srfi/"   ;; rnrs base, rnrs io simple, srfi 6
                      "srfi/streams/" ;; rnrs
                    ;;"srfi/streams/"   ;; rnrs, including unimplemented io ports.
                      "srfi/"   ;; simple rnrs

                    ;;"srfi/"   ;; rnrs base, srfi 1
                      "srfi/"   ;; rnrs base, lists, r5rs, io simple, unicode        

                      "srfi/"   ;; simple rnrs, arithmetic bitwise
                      "srfi/"   ;; rnrs base, r5rs (quotient), control, mutable-strings, slib record
                      "srfi/"   ;; rnrs base, bytevectors
                      "srfi/"   ;; simple rnrs, srfi-9
                      "srfi/"   ;; rnrs base, srfis 26, 60, 66, mz system-big-endian?
                      "srfi/"   ;; simple rnrs, srfi 42
                      "srfi/"   ;; simple rnrs, srfi 63     
                      ;; All depend on srfi 78 and the srfi they test.
                      "srfi/n5/"  ;; rnrs base
                      "srfi/n6/"  ;; rnrs base, rnrs io simple
                      "srfi/n9/"  ;; rnrs base
		      "srfi/n14/" ;; rnrs base, unicode, lists member
                      "srfi/n42/" ;; simple rnrs

                      ;;"rnrs/"   ;; rnrs base, srfi 95
                      "ubik/"  ;; van tonder expander
                      "ubik/"            ;; simple rnrs

                      ;; UBIK is now available.  Spray as directed.
  ) ; end of module