Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
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)
{:constants [{:value (:form ast)}]}
(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)))
(fn [form]
(swap! *frame* (partial merge-with (comp vec distinct concat)) (f form))
(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*)))

This comment has been minimized.

Copy link
Owner Author

remleduff commented Feb 21, 2012

A vastly simplified example:

(process-frames {:op :fn :children [{:op :let :children [{:op :constant :form 1}]}]})

{:op :fn,
:constants [{:value 1}],
:children [
{:op :let,
:unbox false,
:children [
{:unbox true, :form 1, :op :constant}]}]}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.