           (parse-invoke env form))
         (analyze env mform name)))))
 
+(declare analyze-wrap-map)
+
+(defn analyze-map
+  [env form name]
+  (let [expr-env (assoc env :context :expr)
+        items (disallowing-recur
+                (map #(analyze expr-env % name) (apply concat form)))]
+    (analyze-wrap-meta {:op :map :env env :form form :children items} name)))
+
+(defn analyze-vector
+  [env form name]
+  (let [expr-env (assoc env :context :expr)
+        items (disallowing-recur (map #(analyze expr-env % name) form))]
+    (analyze-wrap-meta {:op :vector :env env :form form :children items} name)))
+
+(defn analyze-wrap-meta [expr name]
+  (let [form (:form expr)]
+    (if (meta form)
+      (let [env (:env expr) ; take on expr's context ourselves
+            expr (assoc-in expr [:env :context] :expr) ; change expr to :expr
+            meta-expr (analyze-map (:env expr) (meta form) name)]
+        {:op :meta :env env :form form :children [meta-expr expr]
+         :meta meta-expr :expr expr})
+      expr)))
+
 (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

       (cond
        (symbol? form) (analyze-symbol env form)
        (and (seq? form) (seq form)) (analyze-seq env form name)
        :else {:op :constant :env env :form form}))))

(defn eval1

(defmethod emit-constant Boolean [x] (print (if x "true" "false")))
(defmethod emit-constant Character [x] (pr (str x)))

(defn- emit-meta-constant [x string]
  (if (meta x)
    (do
      (print (str "cljs.core.with_meta(" string ","))
      (emit-constant (meta x))
      (print ")"))
    (print string)))

(defmethod emit-constant clojure.lang.PersistentList$EmptyList [x]
  (emit-meta-constant x "cljs.core.List.EMPTY"))

(defmethod emit-constant clojure.lang.PersistentList [x]
  (emit-meta-constant x
    (str "cljs.core.list("
         (comma-sep (map #(with-out-str (emit-constant %)) x))
         ")")))

(defmethod emit-constant clojure.lang.IPersistentVector [x]
  (emit-meta-constant x
    (str "(new cljs.core.Vector(null, ["
         (comma-sep (map #(with-out-str (emit-constant %)) x))
         "]))")))

(defmethod emit-constant clojure.lang.IPersistentMap [x]
  (emit-meta-constant x
    (str "cljs.core.hash_map("
         (comma-sep (map #(with-out-str (emit-constant %))
                         (apply concat x)))
         ")")))

(defmulti emit :op)

