Idioms for compiler development in Clojure

I would like to explore the possibilities of Clojure for compiler development, but I can not find an example to start with.

I am a complete newbie (from Ruby), but I am convinced that Clojure should be perfect for this purpose.

Let exactly what I'm looking for:

  • start with a simple AST defined in clojure (e.g. simple sequential language: if, while, func, assign, expression)
  • a simple visitor for this AST (e.g. a beautiful printer)
  • I am not interested in lexing / parsing (since I find the s-expression sufficient for my DSL syntax)

What are the correct idioms for this in Clojure?

+4
source share
1 answer

Here is the simplest trivial example that I can think of using the AST tree built from s-expressions with keyword operators:

;; functions map, can be easily extended with new functions ;; map is of keyword -> code generating function (def funcs {:if (fn [cond exp1 exp2] `(if ~cond ~exp1 ~exp2)) :neg (fn [exp1] `(- 0 ~exp1)) :plus (fn [& exps] `(+ ~@exps ))}) ;; compile directly to Clojure source code (defn my-compile [code] (cond (sequential? code) ;; if we have a list, look up the function in funcs (cons (funcs (first code)) (map compile (rest code))) :else ;; treat anything else as a constant literal code)) ;; example compilation to a Clojure expression (my-compile `(:if true (:neg 10) (:plus 10 20 30))) => (if true (clojure.core/- 0 10) (clojure.core/+ 10 20 30)) ;; evaluate compiled code (eval (my-compile `(:if true (:neg 10) (:plus 10 20 30)))) => -10 

Hope this is enough to give you some ideas / get started. The obvious extensions to consider would be:

  • Compile the AST tree with metadata, not directly to a Clojure source. A Clojure defrecord may be appropriate as an AST node representation
  • Add other statements, loop builders, "goto", etc.
  • Simple optimizations, for example. evaluating constant expressions at compile time
  • It has some kind of execution context that allows you to assign dynamic search for variables, etc. The compiler output may be a function that takes the source context as input and returns the final context.
+3
source

All Articles