More Related Content Similar to MoteMote Compiler Plugin Similar to MoteMote Compiler Plugin (20) MoteMote Compiler Plugin2. 自己紹介
●
@kiris
●
アリエルの中の人
●
アリエルだと少数派なScalaユーザー
●
最近はCommon Lisperに押され気味
4. 発表の前に
●
簡単な質問させてください
●
ありえるえりあ勉強会の参加は何回目ですか?
5. 発表の前に
●
簡単な質問させてください
●
ありえるえりあ勉強会の参加は何回目ですか?
●
Scalaプログラムどれくらい書いてますか?
6. 発表の前に
●
簡単な質問させてください
●
ありえるえりあ勉強会の参加は何回目ですか?
●
Scalaプログラムどれくらい書いてますか?
●
コンパイラプラグインを書いたことはありますか?
7. 発表の前に
●
簡単な質問させてください
●
ありえるえりあ勉強会の参加は何回目ですか?
●
Scalaプログラムどれくらい書いてますか?
●
コンパイラプラグインを書いたことはありますか?
●
コンパイラプラグインが書けると
モテそうだと思いませんか?
8. 今日の内容
●
コンパイラプラグインを書けるようになって
モテモテになる
●
ゴール「この勉強会中で 告白される」
●
インスパイア モテモテPHP(WEB+DB PRESS)
●
「PHP連載を通して モテ を目指す」
という大変アグレッシブな企画
●
http://goo.gl/83fcw
9. 対象環境
●
Scala 2.9.0.fnal 以上
●
SBT 0.10.0 以上
●
女子 18歳 以上
●
「スカラちゃん」という処理系があるので代用
11. コンパイラプラグイン
●
コンパイル時に独自の処理(フェーズ)を追加で
きる
●
例えば
●
型や文法以外のチェックを追加する
●
構文木を変更する
●
.class以外のものを生成する
●
etc
●
IDEやビルドツールへの依存が無いのも嬉しい
13. 実用的そうなの
●
Alacs
●
コンパイル時にバグになりそうな箇所を探す
●
ScalaCL
●
コンパイル時にfor文の最適化
●
OpenCLによるGPUの利用
●
Scala enhanced Strings
●
文字列中に直接 Scala の式を書けるようにする
●
“Length: #{aString.length}.stuf”
14. 使い方
●
scalac -Xplugin:myplugin.jar Hello.scala
●
$SCALA_HOME/misc/scala-devel/plugins に
pluginのjarを追加するだけでも可
●
scalac -Xplugin:myplugin.jar -Xplugin-list
●
プラグイン一覧の表示
17. 構文木作成
1. parser
●
parse source into ASTs, perform simple
desugaring
●
余談だけどreaderの差し替えも可能らしい
– scalac -Xsource-reader MyReader hoge.scala
18. 名前解決とか
2. namer
●
resolve names, attach symbols to named trees
3. packageobjects
4. typer
●
the meat and potatoes: type the trees
5. superaccessors
6. picker
7. refchecks
19. 構文木操作
8. selectiveanf
●
限定継続用コンパイラプラグイン
9. liftcode
10. selectivecps
●
限定継続用コンパイラプラグイン
11. uncurry
12. tailcalls
…
20. mixin
20. 中間コード生成
21. cleanup
●
platform-specifc cleanups, generate refective
calls
22. icode
●
generate portable intermediate code
21. 最適化
23. inliner
●
optimization: do inlining
24. closelim
●
optimization: eliminate uncalled closures
25. dce
●
optimization: eliminate dead code
22. JVMコード生成・後処理
26. jvm
●
generate JVM bytecode
27. terminal
●
The last phase in the compiler chain
25. プロジェクト構成(SBT)
●
project_root/
●
build.sbt
●
src/main
• scala
●
MyPlugin.scala
●
MyCompornent.scala
– resource
●
scalac-plugin.xml
●
src/test
...
26. build.sbt
name := "My Plugin"
version := "1.0"
organization := "localhost"
scalaVersion := "2.9.0"
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.9.0"
30. Component(2/2)
class MyComponent(val global: Global) extends PluginComponent {
… // Component(1/2)
def newPhase(prev: Phase) = new StdPhase(prev) {
def name = phaseName
override def apply(unit: CompilationUnit): Unit = {
printf("Hello, motemote world.")
}
}
}
31. どのフェーズを使うべきか?
●
わりとケースバイケースですが
● 構文木を操作するならparserやnamerの後
● 値をチェックするならrefchecksの後
●
などがよさそう
32. 参考:各プラグインのフェーズ
●
コンパイル時にチェックを追加するタイプ
●
DivByZero(チュートリアル) / runAfter = refchecks
●
Var Hunter / runAfter = refchecks
●
WarnBoxingPlugin / runAfter = refchecks
●
コンパイル時にコードを追加するタイプ
●
atuoproxy-plugin / runAfter = parser
●
Notnull-check generator / runAfter = parser
●
Scala enhanced Strings / runAfter = parser
●
コンパイル時に別なコードを生成するタイプ
●
ScalaCL / runAfter = namer
●
s2js / runAfter = refchecks
33. 構文木を探索する
class MyComponent(val global: Global) extends PluginComponent {
…
def newPhase(prev: Phase): Phase = new StdPhase(prev) {
override def apply(unit: CompilationUnit): Unit = {
new ForeachTreeTraverser(onTraverse).traverse(unit.body)
}
}
def onTraverse(tree: Tree): Unit = tree match {
case Apply(fun, args) => println("traversing application of "+ fun)
case _ => ()
}
}
34. 別な構文木に変換する
class MyComponent(val global: Global) extends PluginComponent
with Transform {
def newTransformer(unit: CompilationUnit) = new MyTransformer
class MyTransformer extends Transformer {
override def transform(tree: Tree): Tree = {
postTransform(super.transform(preTransform(tree)))
}
def preTransform(tree: Tree): Tree = tree match {
case _ => tree
}
def postTransform(tree: Tree): Tree = ....
}
35. 構文木を調べる
●
プログラムの変換結果を表示
●
scalac -Xprint:refchecks Hello.scala
●
シンタックスツリーの表示
●
scalac -Xprint:refchecks -Yshow-trees Hello.scala
●
シンタックスツリーをGUIで表示
●
scalac -Ybrowse:refchecks Hello.scala
36. 構文木の作成
●
case Apply(Select(Select(Select(Ident …
●
やってらんない
●
MkTreeを使おう
●
http://goo.gl/O3oeh
$ scala MkTree "if (b) 3 else 5"
If(
Ident("b") // sym=<none>, sym.tpe=<notype>, tpe=null
Literal(Constant(3))
Literal(Constant(5))
)
37. 完成したら
●
sbt package
●
target/scala-2.x.x/myplugin_2.x.x-1.0.jar
●
これで君もモテモテだ!m9(°д°)
39. おまけ
●
「モテモテになるコンパイラプラグイン」
が欲しいと言われて考えてみた
●
loveletter plugin
●
コンパイルの待ち時間を使って愛の告白
●
コンパイルの各フェーズでメッセージを出力
●
特定の相手にだけに出力されようにする
– java.net.InetAddress.getLocalHost()
41. 君に届け
scalatan $ scalac -Xplugin:loveletter-plugin.jar src/test/scala/Hello.scala
スカラ!スカラ!スカラ!スカラぁぁあああわぁあああああああああああああ
あああああああああん!!!あぁああああ…ああ…あっあっー!あぁああああ
ああ!!!スカラスカラスカラぁああぁわぁああああ!!!あぁクンカクン
カ!クンカクンカ!スーハースーハー!スーハースーハー!いい匂いだなぁ…く
んくんんはぁっ!スカラ・オーダスキーたんの黒色の髪をクンカクンカしたい
お!クンカクンカ!あぁあ!!間違えた!モフモフしたいお!モフモフ!モフ
モフ!髪髪モフモフ!カリカリモフモフ…きゅんきゅんきゅい!!型推論が大
幅強化されたスカラたんかわいかったよぅ!!あぁぁああ…あああ…あっあぁ
ああああ!!ふぁぁあああんんっ!!拡張可能リテラルScala3.0で決まって良
かったねスカラたん!あぁあああああ!かわいい!スカラたん!かわいい!
あっああぁああ!爆速コンパイルも新しいジェネリクスも発表されて嬉し…い
やぁああああああ!!!にゃああああああああん!!ぎゃあああああああ
あ!!ぐあああああああああああ!!!爆速コンパイルなんて現実じゃな
い!!!!あ…型推論の大幅強化も拡張可能リテラルもよく考えたら…ス カ ラ
ち ゃ ん は 現実 じ ゃ な い?にゃあああああああああああああん!!うぁああ
ああああああああ!!そんなぁああああああ!!いやぁぁぁああああああああ
あ!!はぁああああああん!!ローザンヌぅうううう!!この!ちきしょー!
やめてやる!!現実なんかやめ…て…え!?見…てる?表紙絵のスカラちゃん
が僕を見てる?表紙絵のスカラちゃんが僕を見てるぞ!スカラちゃんが僕を見
てるぞ!挿絵のスカラちゃんが僕を見てるぞ!!拡張可能リテラルのスカラ
ちゃんが僕に話しかけてるぞ!!!よかった…世の中まだまだ捨てたモンじゃ