(defmacro with-compiler-env
"Evaluates [body] with [env] bound as the value of the `*compiler*` var in
this namespace."
[env & body]
`(let [env# ~env
env# (cond
(map? env#) (atom env#)
(and (instance? clojure.lang.Atom env#)
(map? @env#)) env#
:default (throw (IllegalArgumentException.
(str "Compiler environment must be a map or atom containing a map, not "
(class env#)))))]
(binding [*compiler* env#] ~@body)))