 
 (def ^:dynamic *passes* nil)
 
+(defn analyze-form [env form name opts]
+  #?(:clj (load-core))
+  (cond
+    (symbol? form) (analyze-symbol env form)
+    (and (seq? form) (seq form)) (analyze-seq env form name opts)
+    (map? form) (analyze-map env form)
+    (vector? form) (analyze-vector env form)
+    (set? form) (analyze-set env form)
+    (keyword? form) (analyze-keyword env form)
+    #?@(:clj [(instance? JSValue form) (analyze-js-value env form)])
+    (= () form) (analyze-list env form)
+    :else
+    (let [tag (cond
+                (nil? form) 'clj-nil
+                (number? form) 'number
+                (string? form) 'string
+                (true? form) 'boolean
+                (false? form) 'boolean)]
+      (cond-> {:op :constant :env env :form form}
+        tag (assoc :tag tag)))))
+
+(defn analyze* [env form name opts]
+  (let [passes *passes*
+        passes (when (nil? passes) [infer-type])
+        form   (if (instance? LazySeq form)
+                 (if (seq form) form ())
+                 form)
+        ast    (analyze-form env form name opts)]
+    (reduce (fn [ast pass] (pass env ast)) ast passes)))
+
 (defn analyze
   "Given an environment, a map containing {:locals (mapping of names to bindings), :context
   (one of :statement, :expr, :return), :ns (a symbol naming the

            (assoc (source-info env) :tag :cljs/analysis-error)
            cause)))

(defn analysis-error? [ex]
  (= :cljs/analysis-error (:tag (ex-data ex))))

#?(:clj

(defn macro-autoload-ns?
  "Given a spec form check whether the spec namespace requires a macro file
   of the same name. If so return true."
  #?(:cljs {:tag boolean})
  [form]
  (when *macro-infer*
    (let [ns (if (sequential? form) (first form) form)
