             [clojure.tools.analyzer.utils :refer [resolve-var]]
             [clojure.ruby.runtime         :refer [var->constant lookup-var-in-module]]
             [clojure.ruby.util            :refer :all]))
+
+(defn- endl-separate [exprs]
+  (clojure.string/join "\n" exprs))
+
+(defn- indent [s]
+  (endl-separate
+    (map
+      #(str "  " %)
+      (clojure.string/split s #"\n"))))
 
 (defn- comma-separate [exprs]
   (clojure.string/join ", " exprs))

(defmethod -emit :in-ns [{:keys [name]}]
  (emit-module-declaration (clojure.core/name name)))

(defn- wrap-emit-in-module-eval [emitter]
  (fn [{:keys [op env] :as ast}]
    (let [body (emitter ast)]
      (if (= op :create-ns)
        body
        (module-eval (:ns env) body)))))

(defn- wrap-emit-source-comment [emitter]
  (fn [{:keys [form] :as ast}]
    (format "# %s\n%s" form (emitter ast))))

(def emitter (-> -emit
               wrap-emit-source-comment))

(defn emit [ast]
  (emitter ast))

          (comma-separate (map -emit args))))

(defmethod -emit :if [{:keys [test then else] :as ast}]
  (let [else-expr (-emit else)]
    (if (= "" else-expr)
      (format "if %s\n%s\nend"
              (-emit test)
              (indent (-emit then)))
      (format "if %s\n%s\nelse\n%s\nend"
              (-emit test)
              (indent (-emit then))
              (indent else-expr)))))

(defmethod -emit :do [{:keys [statements ret env] :as ast}]
  (endl-separate (map -emit (conj (vec statements) ret))))
