Daysこの広告は、90日以上更新していないブログに表示しています。ついて分かったことclojure最近,暇を見つけてClojureのコンパイラを読んでいる。いう中間形式についてまとめておく。何?Clojureの内部では,以下のような処理が行われている。Exprは,次のように定義されるインタフェースで,抽象構文木の各ノードを表す。大まかにいえば,REPL(インタプリタ)から呼ばれるのがevalで,コンパイラから呼ばれるのがemitだ。Clojureの構文それぞれについてExprの実装クラスが用意されていて,全部でだいたい50個くらいある。解析するツールClojureプログラムからExprへのパースは,clojure.lang.Compilerクラスのanalyzeメソッドを呼び出すことで実行される。interopの機能を利用してClojureから呼び出すことができる。そこで,analyzeによるパースを適当にClojureのオブジェクトに変換してくれるツールを作った。ソースコードはanalyze.clj。簡単な実行例はこんな感じ。0}]}}]}}niluser=>analyzeの内部では,clojure.lang.Compilerクラスのanalyzeメソッドを呼び出し,結果として返ってきたExprオブジェクトを適当にClojureのMapに変換している。analyzeを2引数で呼び出すと,第1引数で解析するコンテキストを指定することができる。コンテキストの違いについてはいまいちよく分かっていないけど,EVALがREPLから入力されたトップレベルのフォーム,EXPRESSIONが通常の式,RETURNが末尾位置,STATEMENTが値を捨てていいコンテキストを表しているらしい,という理解。指定するコンテキストが異なると解析できない構文もある。ObjExprさっき「evalはインタプリタから呼ばれ,emitはコンパイラから呼ばれる」とざっくり説明したが,この2つは完全に分業しているわけじゃない。いうのも,Clojureの関数はJavaのオブジェクトとして実現されていて,そのためにClojureのインタプリタでは,オンザフライでクラスを生成する必要があるためだ。実現にも動的なクラス生成が使われている。いった動的なクラス生成を担っているのがObjExprで,compileメソッドを呼ぶことでバイトコードを生成できる。deftypeをanalyzeするときに呼ばれる。先程のanalyze関数で解析すると,その時点ですでにクラスが生成されている。ObjExprのサブクラスを作って,適当なメソッド(emitMethodsあたり)をオーバーライドすれば,reifyやdeftypeのような機能を好きなように作れるはず。このあたりをさらに掘り下げるもっとおもしろいことができそう。emit)をもち,(基本的には)evalはインタプリタから,emitはコンパイラから呼ばれるclojure.lang.Compiler/analyzeを呼ぶことでClojureからでもExprオブジェクトへの変換ができるオンザフライのクラス生成にはObjExprが関係しているといったようなことが分かった,というまとめ。4はてなブログをはじめよう!athosさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。