Skip to content

Instantly share code, notes, and snippets.

@athos
Created June 4, 2011 08:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save athos/1007715 to your computer and use it in GitHub Desktop.
Save athos/1007715 to your computer and use it in GitHub Desktop.
(ns analyze)
(defmulti expr->clj-obj class)
(defmethod expr->clj-obj :default [x] x)
(defn exprs->clj-obj [xs]
(vec (map expr->clj-obj xs)))
(def EVAL clojure.lang.Compiler$C/EVAL)
(def EXPRESSSION clojure.lang.Compiler$C/EXPRESSION)
(def RETURN clojure.lang.Compiler$C/RETURN)
(def STATEMENT clojure.lang.Compiler$C/STATEMENT)
(defn analyze
([x] (analyze EVAL x))
([ctx x]
(expr->clj-obj (clojure.lang.Compiler/analyze ctx x))))
;; utility function to access a private field
(defn private-field-value [^Object obj field-name]
(let [^Class c (.getClass obj)
^java.lang.reflect.Field field (.getDeclaredField c (name field-name))]
(.setAccessible field true)
(.get field obj)))
;; method implementations
(defmethod expr->clj-obj clojure.lang.Compiler$DefExpr [x]
{:$ 'DefExpr, :var (.var x), :init (expr->clj-obj (.init x))})
(defmethod expr->clj-obj clojure.lang.Compiler$AssignExpr [x]
{:$ 'AssignExpr, :target (expr->clj-obj (.target x)), :val (expr->clj-obj (.val x))})
(defmethod expr->clj-obj clojure.lang.Compiler$VarExpr [x]
{:$ 'VarExpr, :var (.var x)})
(defmethod expr->clj-obj clojure.lang.Compiler$TheVarExpr [x]
{:$ 'TheVarExpr, :var (.var x)})
(defmethod expr->clj-obj clojure.lang.Compiler$KeywordExpr [x]
{:$ 'KeywordExpr, :k (.k x)})
(defmethod expr->clj-obj clojure.lang.Compiler$ImportExpr [x]
{:$ 'ImportExpr, :c (.c x)})
(defmethod expr->clj-obj clojure.lang.Compiler$InstanceFieldExpr [x]
{:$ 'InstanceFieldExpr, :target (expr->clj-obj (.target x)), :field-name (.fieldName x)})
(defmethod expr->clj-obj clojure.lang.Compiler$StaticFieldExpr [x]
{:$ 'StaticFieldExpr, :c (.c x), :field-name (.fieldName x)})
(defmethod expr->clj-obj clojure.lang.Compiler$InstanceMethodExpr [x]
{:$ 'InstanceMethodExpr, :target (expr->clj-obj (.target x)),
:method-name (.methodName x), :args (exprs->clj-obj (.args x))})
(defmethod expr->clj-obj clojure.lang.Compiler$StaticMethodExpr [x]
{:$ 'StaticMethodExpr, :c (.c x), :method-name (.methodName x), :args (exprs->clj-obj (.args x))})
(defmethod expr->clj-obj clojure.lang.Compiler$UnresolvedVarExpr [x]
{:$ 'UnresolvedVarExpr, :symbol (.symbol x)})
;; NumberExpr is supported only since v1.3
;;(defmethod expr->clj-obj clojure.lang.Compiler$NumberExpr [x]
;; nil)
(defmethod expr->clj-obj clojure.lang.Compiler$ConstantExpr [x]
{:$ 'ConstantExpr, :v (.v x)})
(defmethod expr->clj-obj clojure.lang.Compiler$NilExpr [x]
{:$ 'NilExpr})
(defmethod expr->clj-obj clojure.lang.Compiler$BooleanExpr [x]
{:$ 'BooleanExpr, :val (.val x)})
(defmethod expr->clj-obj clojure.lang.Compiler$StringExpr [x]
{:$ 'StringExpr, :str (.str x)})
(defmethod expr->clj-obj clojure.lang.Compiler$MonitorEnterExpr [x]
{:$ 'MonitorEnterExpr, :target (expr->clj-obj (private-field-value x :target))})
(defmethod expr->clj-obj clojure.lang.Compiler$MonitorExitExpr [x]
{:$ 'MonitorExitExpr, :target (expr->clj-obj (private-field-value x :target))})
(defmethod expr->clj-obj clojure.lang.Compiler$TryExpr [x]
{:$ 'TryExpr, :try-expr (.tryExpr x), :catch-exprs (exprs->clj-obj (.catchExprs x)), :finaly-expr (.finallyExpr x)})
(defmethod expr->clj-obj clojure.lang.Compiler$TryExpr$CatchClause [x]
{:$ 'CatchCaluse, :c (.c x), :lb (expr->clj-obj (.lb x)), :handler (expr->clj-obj (.handler x))})
(defmethod expr->clj-obj clojure.lang.Compiler$ThrowExpr [x]
{:$ 'ThrowExpr, :exc-expr (expr->clj-obj (.excExpr x))})
(defmethod expr->clj-obj clojure.lang.Compiler$NewExpr [x]
{:$ 'NewExpr, :c (.c x), :ctor (.ctor x), :args (exprs->clj-obj (.args x))})
(defmethod expr->clj-obj clojure.lang.Compiler$MetaExpr [x]
{:$ 'MetaExpr, :meta (expr->clj-obj (.meta x)), :expr (expr->clj-obj (.expr x))})
(defmethod expr->clj-obj clojure.lang.Compiler$IfExpr [x]
{:$ 'IfExpr, :test-expr (expr->clj-obj (.testExpr x)),
:then-expr (expr->clj-obj (.thenExpr x)), :else-expr (expr->clj-obj (.elseExpr x))})
(defmethod expr->clj-obj clojure.lang.Compiler$EmptyExpr [x]
{:$ 'EmptyExpr, :coll (.coll x)})
(defmethod expr->clj-obj clojure.lang.Compiler$ListExpr [x]
nil)
(defmethod expr->clj-obj clojure.lang.Compiler$MapExpr [x]
{:$ 'MapExpr, :keyvals (exprs->clj-obj (.keyvals x))})
(defmethod expr->clj-obj clojure.lang.Compiler$SetExpr [x]
{:$ 'SetExpr, :keys (exprs->clj-obj (.keys x))})
(defmethod expr->clj-obj clojure.lang.Compiler$VectorExpr [x]
{:$ 'VectorExpr, :args (exprs->clj-obj (.args x))})
(defmethod expr->clj-obj clojure.lang.Compiler$KeywordInvokeExpr [x]
{:$ 'KeywordInvokeExpr, :kw (expr->clj-obj (.kw x)), :target (expr->clj-obj (.target x))})
(defmethod expr->clj-obj clojure.lang.Compiler$InstanceOfExpr [x]
{:$ 'InstanceOfExpr, :c (private-field-value x :c), :expr (expr->clj-obj (private-field-value x :expr))})
;; StaticInvoke is supported only since v1.3
;;(defmethod expr->clj-obj clojure.lang.Compiler$StaticInvokeExpr [x]
;; nil)
(defmethod expr->clj-obj clojure.lang.Compiler$InvokeExpr [x]
{:$ 'InvokeExpr, :fexpr (expr->clj-obj (.fexpr x)), :args (exprs->clj-obj (.args x))})
(defmethod expr->clj-obj clojure.lang.Compiler$FnExpr [x]
{:$ 'FnExpr, :methods (exprs->clj-obj (.methods x)), :compiled-class (.compiledClass x)})
(defmethod expr->clj-obj clojure.lang.Compiler$FnMethod [x]
{:$ 'FnMethod, :req-parms (exprs->clj-obj (.reqParms x)), :rest-parms (expr->clj-obj (.restParm x)), :body (expr->clj-obj (.body x))})
(defmethod expr->clj-obj clojure.lang.Compiler$ObjExpr [x]
{:$ 'ObjExpr})
(defmethod expr->clj-obj clojure.lang.Compiler$LocalBindingExpr [x]
{:$ 'LocalBindingExpr, :b (expr->clj-obj (.b x))})
(defmethod expr->clj-obj clojure.lang.Compiler$LocalBinding [x]
{:$ 'LocalBinding, :sym (.sym x), :init (expr->clj-obj (.init x))})
(defmethod expr->clj-obj clojure.lang.Compiler$BodyExpr [x]
{:$ 'BodyExpr, :exprs (exprs->clj-obj (.exprs x))})
(defmethod expr->clj-obj clojure.lang.Compiler$LetFnExpr [x]
{:$ 'LetFnExpr, :binding-inits (exprs->clj-obj (.bindingInits x)), :body (expr->clj-obj (.body x))})
(defmethod expr->clj-obj clojure.lang.Compiler$BindingInit [x]
{:$ 'BindingInit, :binding (expr->clj-obj (.binding x))})
(defmethod expr->clj-obj clojure.lang.Compiler$LetExpr [x]
{:$ 'LetExpr, :binding-inits (exprs->clj-obj (.bindingInits x)), :body (expr->clj-obj (.body x))})
(defmethod expr->clj-obj clojure.lang.Compiler$RecurExpr [x]
{:$ 'RecurExpr, :args (exprs->clj-obj (.args x))})
(defmethod expr->clj-obj clojure.lang.Compiler$NewInstanceExpr [x]
{:$ 'NewInstanceExpr, :methods (exprs->clj-obj (private-field-value x :methods))})
(defmethod expr->clj-obj clojure.lang.Compiler$NewInstanceMethod [x]
{:$ 'NewInstanceMethod, :body (expr->clj-obj (.body x))})
(defmethod expr->clj-obj clojure.lang.Compiler$MethodParamExpr [x]
{:$ 'MethodParamExpr})
(defmethod expr->clj-obj clojure.lang.Compiler$CaseExpr [x]
{:$ 'CaseExpr})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment