         (and (seq? form) (seq form)) (analyze-seq env form name)
         :else {:op :constant :env env :form form}))))
 
+(defn eval1
+  [^javax.script.ScriptEngine jse env form]
+  (try
+    (let [ast (analyze env form)
+          js (emits ast)]
+      (try
+        (let [ret (.eval jse js)]
+          ret)
+        (catch Throwable ex
+          ;;we eat ns errors because we know goog.provide() will throw when reloaded
+          ;;TODO - file bug with google, this is bs error
+          ;;this is what you get when you try to 'teach new developers' via errors (goog/base.js 104)
+          (when-not (and (seq? form) (= 'ns (first form)))
+            (prn "Error evaluating:" form :as js)
+            (println (str ex))))))
+    (catch Throwable ex
+      (println (str ex)))))
+
+(defn load-file
+  [jse f]
+  (binding [*cljs-ns* 'cljs.user]
+    (let [env {:ns (@namespaces *cljs-ns*) :context :statement :locals {}}
+          res (if (= \/ (first f)) f (io/resource f))]
+      (assert res (str "Can't find " f " in classpath"))
+      (with-open [r (io/reader res)]
+        (let [pbr (clojure.lang.LineNumberingPushbackReader. r)
+              eof (Object.)]
+          (loop [r (read pbr false eof false)]
+            (when-not (identical? eof r)
+              (eval1 jse env r)
+              (recur (read pbr false eof false)))))))))
+
 (defn repl-env
   "Returns a fresh JS environment, suitable for passing to repl.
   Hang on to return for use across repl calls."

;;todo - move to core.cljs, using js
(def ^String bootjs "
//goog.provide should do this for us
cljs = {}
cljs.core = {}
cljs.user = {}
cljs.core.truth_ = function(x){return x != null && x !== false;}
cljs.core.fnOf_ = function(f){return (f instanceof Function?f:f.cljs$core$Fn$invoke);}")


(set! *warn-on-reflection* true)

(ns cljs.compiler
  (:refer-clojure :exclude [munge load-file])
  (:require [clojure.java.io :as io]))

(declare resolve-var)
