下面是簡單的小例子我能想到的,利用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」等。
- 簡單的優化在編譯時對常量表達式的評估
- 具有某種形式的允許賦值,動態變量查找等的執行上下文。編譯器輸出可以是一個函數,它將初始上下文作爲輸入並返回最終上下文。
您不必將搜索限制在Clojure示例中。其他Lisp有很多例子可以輕鬆移植到Clojure。例如,http://bit.ly/3t1DX或http://bit.ly/I2LFdr – 2012-07-26 07:54:28
我同意。這種說法也可以適用於一般的函數式語言,但我想限制在Clojure中,因爲它對於非lispians來說似乎比舊lisses更容易獲得/吸引人。 「有史以來最好的口齒伶俐的」人說? – JCLL 2012-07-26 08:19:30
不,功能性語言通常是完全不同的話題。 Clojure是一個Lisp,從某種意義上說它是Lisp最重要的部分 - 一個體面的宏觀系統。這實際上使Lisp不同,使得它比其他語言更適合編譯器開發。看看我的第二個鏈接,它使用專門的DSL來定義訪問者。這正是一種習慣Lisp的做事方式。在所有的Lisp中都是一樣的。至於「有史以來最好的口齒伶俐」,我個人不會同意。沒有'cons'的Lisp不是Lisp。 「復發」是可怕的。 – 2012-07-26 08:33:01