 ;; -----------------------------------------------------------------------------
 ;; Eval
 
-(defn eval* [env bound-vars form opts cb]
-  (binding [env/*compiler*   env
+(defn eval* [bound-vars form opts cb]
+  (binding [env/*compiler*   (:*compiler* bound-vars)
             *eval-fn*        (:*eval-fn* bound-vars)
             ana/*cljs-ns*    (:*cljs-ns* bound-vars)
             *ns*             (:*ns* bound-vars)

(defn eval
  ([env form cb] (eval env form nil cb))
  ([env form opts cb]
   (eval* env
     {:*cljs-ns*      'cljs.user
      :*ns*           (create-ns 'cljs.user)
      :*data-readers* tags/*cljs-data-readers*
      :*eval-fn*      (or (:js-eval opts) js/eval)}
     form opts cb)))
   (when-not (contains? @*loaded* name)
     (*load-fn* name
       (fn [source]
         (compile* bound-vars source opts (fn [ret] (cb true))))))))

(declare ns-side-effects)

(defn analyze* [bound-vars source opts cb]
  (let [rdr  (rt/string-push-back-reader source)
        eof  (js-obj)
        aenv (ana/empty-env)]
    (binding [env/*compiler*   (:*compiler* bound-vars)
              ana/*cljs-ns*    (:*cljs-ns* bound-vars)
              *ns*             (:*ns* bound-vars)
              r/*data-readers* (:*data-readers* bound-vars)]
      (loop []
        (let [form (r/read {:eof eof} rdr)]
          (if-not (identical? eof form)
            (let [aenv (assoc aenv :ns (ana/get-namespace ana/*cljs-ns*))
                  ast  (ana/analyze aenv form)]
              (if (= (:op ast) :ns)
                (ns-side-effects bound-vars aenv ast opts (fn [_] (cb)))
                (recur)))
            (cb)))))))

