4

コンパイラ開発のためのClojureの力を探求したいのですが、最初の例が見つかりません。

私は(Rubyから来た)まったくの初心者ですが、Clojureはこの目的に理想的であると確信しています。

私が探しているものを正確にしましょう:

  • clojureで定義された単純なASTから開始します(たとえば、単純な順次言語:if、while、func、assign、expression)
  • このASTの単純な訪問者(たとえば、きれいなプリンター)
  • 字句解析/構文解析にはあまり興味がありません(DSL構文にはS式で十分だと考えているため)

Clojureでこれに適したイディオムは何ですか?

4

1 に答える 1

4

これは、キーワード演算子を使用して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] `(+ ~@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

うまくいけば、それはあなたにいくつかのアイデアを与える/あなたが始めるのに十分です。考慮すべき明らかな拡張機能は次のとおりです。

  • Clojureソースに直接ではなく、メタデータを使用してASTツリーにコンパイルします。ClojuredefrecordはASTノード表現として適している可能性があります
  • 他の演算子、ループ構造、「goto」などを追加します。
  • コンパイル時の定数式の評価などの単純な最適化
  • 割り当て、動的変数ルックアップなどを可能にする何らかの形式の実行コンテキストがあります。コンパイラの出力は、初期コンテキストを入力として受け取り、最終コンテキストを返す関数である可能性があります。
于 2012-07-26T08:49:32.993 に答える