 (defmacro js [form]
   `(emit (analyze {:ns (@namespaces 'cljs.user) :context :statement :locals {}} '~form)))
 
+(defn jscapture [form]
+  "just grabs the js, doesn't print it"
+  (with-out-str
+    (emit (analyze {:ns (@namespaces 'cljs.user) :context :expr :locals {}} form))))
+
 (defn jseval [form]
-  (let [js (emits (analyze {:ns (@namespaces 'cljs.user) :context :expr :locals {}}
-                           form))]
+  (let [js (jscapture form)]
     ;;(prn js)
     (.eval jse (str "print(" js ")"))))
-
-(defn jscapture [form]
-  "just grabs the js, doesn't print it"
-  (emits (analyze {:ns (@namespaces 'cljs.user) :context :expr :locals {}} form)))
 
 ;; from closure.clj
 (optimize (jscapture '(defn foo [x y] (if true 46 (recur 1 x)))))

    (with-open [out ^java.io.Writer (io/make-writer dest {})]
      (binding [*out* out
                *cljs-ns* 'cljs.user
                *cljs-file* (.getPath ^java.io.File src)]
        (loop [forms (forms-seq src)
               ns-name nil
               deps nil]

        subcontext (if (= :expr context) :return context)]
    (if (or name finally)
      (do
        (when (= :expr context) (emits "(function (){"))
        (emits "try{")
        (let [{:keys [statements ret]} try]
          (emit-block subcontext statements ret))
        (emits "}")
        (when name
          (emits "catch (" name "){")
          (when catch
            (let [{:keys [statements ret]} catch]
              (emit-block subcontext statements ret)))
          (emits "}"))
        (when finally
          (let [{:keys [statements ret]} finally]
            (assert (not= :constant (:op ret)) "finally block cannot contain constant")
            (emits "finally {")
            (emit-block subcontext statements ret)
            (emits "}")))
        (when (= :expr context) (emits "})()")))
      (let [{:keys [statements ret]} try]
        (when (and statements (= :expr context)) (emits "(function (){"))
        (emit-block subcontext statements ret)
        (when (and statements (= :expr context)) (emits "})()"))))))

(defmethod emit :let
  [{:keys [bindings statements ret env loop]}]
  (let [context (:context env)]
    (when (= :expr context) (emits "(function (){"))
    (doseq [{:keys [name init]} bindings]
      (emitln "var " name " = " init ";"))
    (when loop (emitln "while(true){"))
    (emit-block (if (= :expr context) :return context) statements ret)
    (when loop
      (emitln "break;")
      (emitln "}"))
    ;(emits "}")
    (when (= :expr context) (emits "})()"))))

(defmethod emit :recur
  [{:keys [frame exprs env]}]
  (let [temps (vec (take (count exprs) (repeatedly gensym)))
        names (:names frame)]
    (emitln "{")
    (dotimes [i (count exprs)]
      (emitln "var " (temps i) " = " (exprs i) ";"))
    (dotimes [i (count exprs)]
      (emitln (names i) " = " (temps i) ";"))
    (emitln "continue;")
    (emitln "}")))

(defmethod emit :invoke
  [{:keys [f args env]}]
