SlideShare a Scribd company logo
1 of 43
Download to read offline
モテモテコンパイラプラグイン
自己紹介
●
    @kiris
●
    アリエルの中の人
●
    アリエルだと少数派なScalaユーザー
    ●
        最近はCommon Lisperに押され気味
発表の前に
●
    簡単な質問させてください
発表の前に
●
    簡単な質問させてください
    ●
        ありえるえりあ勉強会の参加は何回目ですか?
発表の前に
●
    簡単な質問させてください
    ●
        ありえるえりあ勉強会の参加は何回目ですか?
    ●
        Scalaプログラムどれくらい書いてますか?
発表の前に
●
    簡単な質問させてください
    ●
        ありえるえりあ勉強会の参加は何回目ですか?
    ●
        Scalaプログラムどれくらい書いてますか?
    ●
        コンパイラプラグインを書いたことはありますか?
発表の前に
●
    簡単な質問させてください
    ●
        ありえるえりあ勉強会の参加は何回目ですか?
    ●
        Scalaプログラムどれくらい書いてますか?
    ●
        コンパイラプラグインを書いたことはありますか?

    ●
        コンパイラプラグインが書けると
        モテそうだと思いませんか?
今日の内容
●
    コンパイラプラグインを書けるようになって
    モテモテになる
    ●
        ゴール「この勉強会中で    告白される」
●
    インスパイア モテモテPHP(WEB+DB PRESS)
    ●
        「PHP連載を通して  モテ      を目指す」
        という大変アグレッシブな企画
    ●
        http://goo.gl/83fcw
対象環境
●
    Scala 2.9.0.fnal 以上
●
    SBT 0.10.0 以上
●
    女子 18歳 以上
    ●
        「スカラちゃん」という処理系があるので代用
本題
コンパイラプラグイン
●
    コンパイル時に独自の処理(フェーズ)を追加で
    きる

●
    例えば
    ●
        型や文法以外のチェックを追加する
    ●
        構文木を変更する
    ●
        .class以外のものを生成する
    ●
        etc

●
    IDEやビルドツールへの依存が無いのも嬉しい
簡単なデモ
実用的そうなの
●
    Alacs
    ●
        コンパイル時にバグになりそうな箇所を探す
●
    ScalaCL
    ●
        コンパイル時にfor文の最適化
    ●
        OpenCLによるGPUの利用
●
    Scala enhanced Strings
    ●
        文字列中に直接 Scala の式を書けるようにする
    ●
        “Length: #{aString.length}.stuf”
使い方
●
    scalac -Xplugin:myplugin.jar Hello.scala
    ●
        $SCALA_HOME/misc/scala-devel/plugins に
        pluginのjarを追加するだけでも可

●
    scalac -Xplugin:myplugin.jar -Xplugin-list
    ●
        プラグイン一覧の表示
コンパイラの流れ
Scalaのコンパイルの流れ
●
    全部で25+2フェーズ
    ●
        scalac -Xshow-phases
構文木作成
1. parser
  ●
      parse source into ASTs, perform simple
      desugaring
  ●
      余談だけどreaderの差し替えも可能らしい
      –   scalac -Xsource-reader MyReader hoge.scala
名前解決とか
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
構文木操作
 8. selectiveanf
   ●
       限定継続用コンパイラプラグイン
 9. liftcode
10. selectivecps
   ●
       限定継続用コンパイラプラグイン
11. uncurry
12. tailcalls
…
20. mixin
中間コード生成
21. cleanup
  ●
      platform-specifc cleanups, generate refective
      calls
22. icode
  ●
      generate portable intermediate code
最適化
23. inliner
   ●
       optimization: do inlining
24. closelim
   ●
       optimization: eliminate uncalled closures
25. dce
   ●
       optimization: eliminate dead code
JVMコード生成・後処理
26. jvm
  ●
      generate JVM bytecode
27. terminal
  ●
      The last phase in the compiler chain
コンパイラプラグインを使うと
$ scalac -Xplugin:myplugin.jar -Xplugin-phases

1. parser
2. myplugin-phase <- 独自のフェーズを追加
3. namer
4. packageobjects
5. typer
...
書いてみよう
プロジェクト構成(SBT)
●
    project_root/
     ●
          build.sbt
     ●
          src/main
           • scala
               ●
                 MyPlugin.scala
               ●
                 MyCompornent.scala
           – resource
               ●
                 scalac-plugin.xml
     ●
          src/test
    ...
build.sbt
name := "My Plugin"
version := "1.0"
organization := "localhost"
scalaVersion := "2.9.0"
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.9.0"
scalac-plugin.xml
<plugin>
 <name>myplugin</name>
 <classname>localhost.MyPlugin</classname>
</plugin>
Plugin
import scala.tools.nsc.Global
import scala.tools.nsc.plugins.Plugin


class MyPlugin(val global: Global) extends Plugin {
    override val name = "myplugin"
    override val description = "myplugin description"
    override val components = List(new MyComponent(global))
}
Component(1/2)
import scala.tools.nsc._
import scala.tools.nsc.plugins.PluginComponent


class MyComponent(val global: Global) extends PluginComponent {
    import global._
    import global.defnitions._


    val runsAfter = List("refchecks")
    val phaseName = "myplugin-phase"


    … // Component(2/2)
}
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.")
        }
    }
}
どのフェーズを使うべきか?
●
    わりとケースバイケースですが
●   構文木を操作するならparserやnamerの後
●   値をチェックするならrefchecksの後

●
    などがよさそう
参考:各プラグインのフェーズ
●
    コンパイル時にチェックを追加するタイプ
    ●
      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
構文木を探索する
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 _ => ()
    }
}
別な構文木に変換する
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 = ....
}
構文木を調べる
●
    プログラムの変換結果を表示
    ●
        scalac -Xprint:refchecks Hello.scala
●
    シンタックスツリーの表示
    ●
        scalac -Xprint:refchecks -Yshow-trees Hello.scala
●
    シンタックスツリーをGUIで表示
    ●
        scalac -Ybrowse:refchecks Hello.scala
構文木の作成
●
      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))
)
完成したら
●
    sbt package
    ●
        target/scala-2.x.x/myplugin_2.x.x-1.0.jar


●
    これで君もモテモテだ!m9(°д°)
おまけ
おまけ
●
    「モテモテになるコンパイラプラグイン」
    が欲しいと言われて考えてみた

●
    loveletter plugin
    ●
        コンパイルの待ち時間を使って愛の告白
    ●
        コンパイルの各フェーズでメッセージを出力
    ●
        特定の相手にだけに出力されようにする
        –   java.net.InetAddress.getLocalHost()
君に届け
scalatan $ scalac -Xplugin:loveletter-plugin.jar src/test/scala/Hello.scala
君に届け
scalatan $ scalac -Xplugin:loveletter-plugin.jar src/test/scala/Hello.scala
スカラ!スカラ!スカラ!スカラぁぁあああわぁあああああああああああああ
あああああああああん!!!あぁああああ…ああ…あっあっー!あぁああああ
ああ!!!スカラスカラスカラぁああぁわぁああああ!!!あぁクンカクン
カ!クンカクンカ!スーハースーハー!スーハースーハー!いい匂いだなぁ…く
んくんんはぁっ!スカラ・オーダスキーたんの黒色の髪をクンカクンカしたい
お!クンカクンカ!あぁあ!!間違えた!モフモフしたいお!モフモフ!モフ
モフ!髪髪モフモフ!カリカリモフモフ…きゅんきゅんきゅい!!型推論が大
幅強化されたスカラたんかわいかったよぅ!!あぁぁああ…あああ…あっあぁ
ああああ!!ふぁぁあああんんっ!!拡張可能リテラルScala3.0で決まって良
かったねスカラたん!あぁあああああ!かわいい!スカラたん!かわいい!
あっああぁああ!爆速コンパイルも新しいジェネリクスも発表されて嬉し…い
やぁああああああ!!!にゃああああああああん!!ぎゃあああああああ
あ!!ぐあああああああああああ!!!爆速コンパイルなんて現実じゃな
い!!!!あ…型推論の大幅強化も拡張可能リテラルもよく考えたら…ス カ ラ
ち ゃ ん は 現実 じ ゃ な い?にゃあああああああああああああん!!うぁああ
ああああああああ!!そんなぁああああああ!!いやぁぁぁああああああああ
あ!!はぁああああああん!!ローザンヌぅうううう!!この!ちきしょー!
やめてやる!!現実なんかやめ…て…え!?見…てる?表紙絵のスカラちゃん
が僕を見てる?表紙絵のスカラちゃんが僕を見てるぞ!スカラちゃんが僕を見
てるぞ!挿絵のスカラちゃんが僕を見てるぞ!!拡張可能リテラルのスカラ
ちゃんが僕に話しかけてるぞ!!!よかった…世の中まだまだ捨てたモンじゃ
ご静聴ありがとうございました
告白タイム




        質問も一応受けつけます

More Related Content

What's hot

MessagePack RPC によるドキドキ非同期通信 @関ジャバ 2012年度8月
MessagePack RPC によるドキドキ非同期通信 @関ジャバ 2012年度8月MessagePack RPC によるドキドキ非同期通信 @関ジャバ 2012年度8月
MessagePack RPC によるドキドキ非同期通信 @関ジャバ 2012年度8月
Takashi Someda
 
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugSpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
Y Watanabe
 
Shibuya Pm Tt08 Advanced Mogilefs
Shibuya Pm Tt08 Advanced MogilefsShibuya Pm Tt08 Advanced Mogilefs
Shibuya Pm Tt08 Advanced Mogilefs
guest172cfb
 

What's hot (20)

Heap statsfx analyzer
Heap statsfx analyzerHeap statsfx analyzer
Heap statsfx analyzer
 
TypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめ
 
SmalltalkBoltでUFFI入門
SmalltalkBoltでUFFI入門SmalltalkBoltでUFFI入門
SmalltalkBoltでUFFI入門
 
MessagePack RPC によるドキドキ非同期通信 @関ジャバ 2012年度8月
MessagePack RPC によるドキドキ非同期通信 @関ジャバ 2012年度8月MessagePack RPC によるドキドキ非同期通信 @関ジャバ 2012年度8月
MessagePack RPC によるドキドキ非同期通信 @関ジャバ 2012年度8月
 
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミング
 
CakePHP 1 to 2 Migration tips 100
CakePHP 1 to 2 Migration tips 100CakePHP 1 to 2 Migration tips 100
CakePHP 1 to 2 Migration tips 100
 
HttpClientModule
HttpClientModuleHttpClientModule
HttpClientModule
 
scala-kaigi1-sbt
scala-kaigi1-sbtscala-kaigi1-sbt
scala-kaigi1-sbt
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
 
Introduction to JShell #JavaDayTokyo #jdt_jshell
Introduction to JShell #JavaDayTokyo #jdt_jshellIntroduction to JShell #JavaDayTokyo #jdt_jshell
Introduction to JShell #JavaDayTokyo #jdt_jshell
 
Reactive Extensions v2.0
Reactive Extensions v2.0Reactive Extensions v2.0
Reactive Extensions v2.0
 
コンピューティングとJava~なにわTECH道
コンピューティングとJava~なにわTECH道コンピューティングとJava~なにわTECH道
コンピューティングとJava~なにわTECH道
 
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugSpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
 
Javaの進化にともなう運用性の向上はシステム設計にどういう変化をもたらすのか
Javaの進化にともなう運用性の向上はシステム設計にどういう変化をもたらすのかJavaの進化にともなう運用性の向上はシステム設計にどういう変化をもたらすのか
Javaの進化にともなう運用性の向上はシステム設計にどういう変化をもたらすのか
 
Shibuya Pm Tt08 Advanced Mogilefs
Shibuya Pm Tt08 Advanced MogilefsShibuya Pm Tt08 Advanced Mogilefs
Shibuya Pm Tt08 Advanced Mogilefs
 
Javaクラスファイルの読み方
Javaクラスファイルの読み方Javaクラスファイルの読み方
Javaクラスファイルの読み方
 
なぜリアクティブは重要か #ScalaMatsuri
なぜリアクティブは重要か #ScalaMatsuriなぜリアクティブは重要か #ScalaMatsuri
なぜリアクティブは重要か #ScalaMatsuri
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive Extensions
 
JavaOne2015報告またはこれからのJava
JavaOne2015報告またはこれからのJavaJavaOne2015報告またはこれからのJava
JavaOne2015報告またはこれからのJava
 

Similar to MoteMote Compiler Plugin

これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallこれからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
なおき きしだ
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
papamitra
 
tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1
Ryosuke IWANAGA
 

Similar to MoteMote Compiler Plugin (20)

Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
 
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallこれからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
 
Play framework 2.0のちょっとした紹介
Play framework 2.0のちょっとした紹介Play framework 2.0のちょっとした紹介
Play framework 2.0のちょっとした紹介
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行
 
XPages 開発 Tips 百連発
XPages 開発 Tips 百連発XPages 開発 Tips 百連発
XPages 開発 Tips 百連発
 
tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1
 
はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入
 
Trait in scala
Trait in scalaTrait in scala
Trait in scala
 
言語アップデート -Scala編-
言語アップデート -Scala編-言語アップデート -Scala編-
言語アップデート -Scala編-
 
Scala EE 7 Essentials
Scala EE 7 EssentialsScala EE 7 Essentials
Scala EE 7 Essentials
 
Web技術勉強会 第31回
Web技術勉強会 第31回Web技術勉強会 第31回
Web技術勉強会 第31回
 
Phantom Type in Scala
Phantom Type in ScalaPhantom Type in Scala
Phantom Type in Scala
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDE
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
qmake入門
qmake入門qmake入門
qmake入門
 
Openresty
OpenrestyOpenresty
Openresty
 
企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624
 
20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)
 

Recently uploaded

Recently uploaded (10)

Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 

MoteMote Compiler Plugin

  • 2. 自己紹介 ● @kiris ● アリエルの中の人 ● アリエルだと少数派なScalaユーザー ● 最近はCommon Lisperに押され気味
  • 3. 発表の前に ● 簡単な質問させてください
  • 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 ● プラグイン一覧の表示
  • 16. Scalaのコンパイルの流れ ● 全部で25+2フェーズ ● scalac -Xshow-phases
  • 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
  • 23. コンパイラプラグインを使うと $ scalac -Xplugin:myplugin.jar -Xplugin-phases 1. parser 2. myplugin-phase <- 独自のフェーズを追加 3. namer 4. packageobjects 5. typer ...
  • 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"
  • 28. Plugin import scala.tools.nsc.Global import scala.tools.nsc.plugins.Plugin class MyPlugin(val global: Global) extends Plugin { override val name = "myplugin" override val description = "myplugin description" override val components = List(new MyComponent(global)) }
  • 29. Component(1/2) import scala.tools.nsc._ import scala.tools.nsc.plugins.PluginComponent class MyComponent(val global: Global) extends PluginComponent { import global._ import global.defnitions._ val runsAfter = List("refchecks") val phaseName = "myplugin-phase" … // Component(2/2) }
  • 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()
  • 40. 君に届け scalatan $ scalac -Xplugin:loveletter-plugin.jar src/test/scala/Hello.scala
  • 41. 君に届け scalatan $ scalac -Xplugin:loveletter-plugin.jar src/test/scala/Hello.scala スカラ!スカラ!スカラ!スカラぁぁあああわぁあああああああああああああ あああああああああん!!!あぁああああ…ああ…あっあっー!あぁああああ ああ!!!スカラスカラスカラぁああぁわぁああああ!!!あぁクンカクン カ!クンカクンカ!スーハースーハー!スーハースーハー!いい匂いだなぁ…く んくんんはぁっ!スカラ・オーダスキーたんの黒色の髪をクンカクンカしたい お!クンカクンカ!あぁあ!!間違えた!モフモフしたいお!モフモフ!モフ モフ!髪髪モフモフ!カリカリモフモフ…きゅんきゅんきゅい!!型推論が大 幅強化されたスカラたんかわいかったよぅ!!あぁぁああ…あああ…あっあぁ ああああ!!ふぁぁあああんんっ!!拡張可能リテラルScala3.0で決まって良 かったねスカラたん!あぁあああああ!かわいい!スカラたん!かわいい! あっああぁああ!爆速コンパイルも新しいジェネリクスも発表されて嬉し…い やぁああああああ!!!にゃああああああああん!!ぎゃあああああああ あ!!ぐあああああああああああ!!!爆速コンパイルなんて現実じゃな い!!!!あ…型推論の大幅強化も拡張可能リテラルもよく考えたら…ス カ ラ ち ゃ ん は 現実 じ ゃ な い?にゃあああああああああああああん!!うぁああ ああああああああ!!そんなぁああああああ!!いやぁぁぁああああああああ あ!!はぁああああああん!!ローザンヌぅうううう!!この!ちきしょー! やめてやる!!現実なんかやめ…て…え!?見…てる?表紙絵のスカラちゃん が僕を見てる?表紙絵のスカラちゃんが僕を見てるぞ!スカラちゃんが僕を見 てるぞ!挿絵のスカラちゃんが僕を見てるぞ!!拡張可能リテラルのスカラ ちゃんが僕に話しかけてるぞ!!!よかった…世の中まだまだ捨てたモンじゃ
  • 43. 告白タイム 質問も一応受けつけます