   (:import clojure.lang.IFn))
 
 
-(def root-directory 
+(def root-directory
   @#'clojure.core/root-directory)
 
 (def ^:dynamic *load-configuration*

            (fn? emitter)]}
     (let [forms (atom [])
           defs  (atom {})
           config {:debug false
                   :ast {:forms forms
                         :defs defs}}]
       ;; Loads and macroexpands all the code using the built config
       ;; to generate the forms and defs structures.
       (load res config)
       
       ;; The atoms now contain the whole analyzed program, apply
       ;; program passes as updates over the entire AST. Updated ASTs
       ;; are re-evaluated and the symbol to AST mapping rebuilt
       ;; between each pass.
       ;; 
       ;; FIXME:
       ;;   It's worth discussing the correctness of this approach on
       ;;   the maining list.
       (let [settings (:passes settings)]
         (doseq [pass passes]
           (swap! forms pass @defs settings)
           (doseq [form @forms]
             (eval form config))))

       ;; Having taken an O(Nᵏ) compile operation to the face we now
       ;; run the emitter and call it quits.


           (doseq [expr statements]
             (eval expr options))

           (eval ret options))

         ;; bare expression handling
         ;;-----------------------------
         ;; FIXME: Repeated analysis
         ;;   Is there some way that I can merge this so that only one
         ;;   ana.jvm/analyze invocation is required? I think the
         ;;   answer is no, but it'd be nice.

         ;; FIXME: Closed over defs
         ;;  This is gonna be invalid for a whole lot of code. Lambda
         ;;  lifting is gonna come into play here methinks. I have to
         ;;  get this working so that closed over defs are supported,
         ;;  eg:
         ;;
         ;;  (let [x 3]
         ;;    (def foo [y]
         ;;         (+ x y)))
         ;;
         ;; This issue also impacts multimethods which are implemented
         ;; with closed over defs.

         (let [ast   (binding [ana/macroexpand-1 ana.jvm/macroexpand-1
                               ana/create-var    ana.jvm/create-var
                               ana/parse         ana.jvm/parse
                               ana/var?          var?]
                       (ana.jvm/analyze mform
                                        (or env (ana.jvm/empty-env))))]

           ;; the accumulator for the whole read program
           (when (and forms-ast
                      (atom? forms-ast))
             (swap! forms-ast conj ast))

           ;; the accumulator for defs to structure
           (when (and defs-ast
                      (atom? defs-ast)
                      (patern/def? ast))
             (swap! defs-ast assoc
                    (patern/def->symbol ast)
                    ast))

           ;; FIXME: Eval for side effects
           ;;  Running code for side-effects may be something that I
           ;;  need to conditionalize, see "Closed over defs"

           ;; and run the code for side-effects.
           (let [r     (-> `(^:once fn* [] ~mform)
                           (ana.jvm/analyze (or env (ana.jvm/empty-env)))
                           (e/emit {:debug?       debug?
                                    :class-loader (or classloader
                                                      (clojure.lang.RT/makeClassLoader))}))
                 class (-> r meta :class)]
             (.invoke ^IFn (.newInstance ^Class class))))))))


(defn load
