(defn -elide-meta
[{:keys [op meta expr env] :as ast}]
(let [form (:form meta)
new-meta (apply dissoc form (filter (get-elides ast) (keys form)))]
(case op
:const
(if (or (not meta)
(= new-meta (:form meta)))
ast
(if (not (empty? new-meta))
(assoc-in ast [:meta :val] new-meta)
(-> ast
(update-in [:val] with-meta nil)
(dissoc :children :meta))))
:with-meta
(if (not (empty? new-meta))
(if (= new-meta (:form meta))
ast
(assoc ast :meta (replace-meta meta new-meta)))
(merge (dissoc ast :meta :expr)
{:op :do
:body? true
:ret expr
:statements []
:children [:statements :ret]}))
:def
(if (not (empty? new-meta))
(if (= new-meta (:form meta))
ast
(assoc ast :meta (replace-meta meta new-meta)))
(assoc (dissoc ast :meta) :children [:init]))
ast)))