Skip to content

Instantly share code, notes, and snippets.

@cgrand
Forked from remleduff/gist:1876575
Created February 21, 2012 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cgrand/1877266 to your computer and use it in GitHub Desktop.
Save cgrand/1877266 to your computer and use it in GitHub Desktop.
Simplified AST processing code from CinC
(use '[clojure.walk :only [walk]])
(def ^:dynamic ^:private *frame*)
(defn- new-frame [] (atom {}))
(defn- collect-frame [ast]
(case (:op ast)
:constant
{:constants [{:value (:form ast)}]}
nil))
(defn- new-frame? [form]
(#{:fn } (:op form)))
(defn- unboxed-parent? [ast] (#{:let} (:op ast)))
(def ^:dynamic *unbox* false)
(defn- process-frames-helper [f ast]
(let [pre-fn
(fn [form]
(process-frames-helper f (if (:op form) (assoc form :unbox *unbox*) form)))
post-fn
(fn [form]
(swap! *frame* (partial merge-with (comp vec distinct concat)) (f form))
form)
main
(fn [f ast]
(if (new-frame? ast)
(binding [*frame* (new-frame)]
(let [res (walk pre-fn post-fn ast)]
(merge res @*frame*)))
(walk pre-fn post-fn ast)))]
(if (unboxed-parent? ast)
(binding [*unbox* true] (main f ast))
(main f ast))
))
(defn process-frames [ast]
(binding [*frame* (new-frame)]
(merge (process-frames-helper collect-frame ast) @*frame*)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment