2012-07-26 39 views
4

我想探索Clojure的編譯器開發的力量,但我找不到示例。在Clojure編譯器開發的習語

我是一個新手(來自Ruby),但我確信Clojure應該是理想的這個目的。

讓我們確切什麼我在尋找:

  • 開始從Clojure中定義的簡單AST(爲讓說一個簡單的順序語言:如果,同時,FUNC,分配,表達)
  • 簡單遊客對這個AST(例如漂亮的打印)
  • 我不是真的詞法/感興趣的解析(因爲我認爲S-表達足以成爲我的DSL語法)

在Clojure中,這是什麼合適的成語?

+0

您不必將搜索限制在Clojure示例中。其他Lisp有很多例子可以輕鬆移植到Clojure。例如,http://bit.ly/3t1DX或http://bit.ly/I2LFdr – 2012-07-26 07:54:28

+0

我同意。這種說法也可以適用於一般的函數式語言,但我想限制在Clojure中,因爲它對於非lispians來說似乎比舊lisses更容易獲得/吸引人。 「有史以來最好的口齒伶俐的」人說? – JCLL 2012-07-26 08:19:30

+0

不,功能性語言通常是完全不同的話題。 Clojure是一個Lisp,從某種意義上說它是Lisp最重要的部分 - 一個體面的宏觀系統。這實際上使Lisp不同,使得它比其他語言更適合編譯器開發。看看我的第二個鏈接,它使用專門的DSL來定義訪問者。這正是一種習慣Lisp的做事方式。在所有的Lisp中都是一樣的。至於「有史以來最好的口齒伶俐」,我個人不會同意。沒有'cons'的Lisp不是Lisp。 「復發」是可怕的。 – 2012-07-26 08:33:01

回答

3

下面是簡單的小例子我能想到的,利用S-表達式建有關鍵字運營商的AST樹:

;; 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] `(+ [email protected]))}) 

;; 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 

希望這足夠給你一些想法/讓你開始。需要考慮的明顯擴展是:

  • 使用元數據編譯爲AST樹,而不是直接編譯爲Clojure源。 Clojure defrecord可能適合作爲AST節點表示
  • 添加其他運算符,循環構造,「goto」等。
  • 簡單的優化在編譯時對常量表達式的評估
  • 具有某種形式的允許賦值,動態變量查找等的執行上下文。編譯器輸出可以是一個函數,它將初始上下文作爲輸入並返回最終上下文。