私は Scala マクロの初心者で、非常に基本的な DSL を書こうとしています。
次の Scala クラスがあります。
abstract class SpecialFunction {
def apply(): Unit
}
および次の Scala マクロ:
def mImpl(c: Context)(bodyBlock: c.Expr[Unit]): c.Expr[X] =
c.universe.reify {
new X(new SpecialFunction {
override def apply() {
bodyBlock.splice
}
})
}
def m(bodyBlock: Unit): X = macro mImpl
ここまでは順調ですね。たとえば、次のように書くことができます。
def example = m {
println("Hello, world")
}
そして、これは次のようにコンパイルされます。
def example = new X(new SpecialFunction {
override def apply() {
println("Hello, world")
}
})
しかし、この定式化では、そのような「m ブロック」にローカル変数を含めることはできません。たとえば、次のように書くことはできません。
def example = m {
val x = 7
println(x.toString)
}
コンパイル時にエラーが発生します:
symbol value x does not exist in example
しかし、私が達成したいのはこれです:
def example = new X(new SpecialFunction {
override def apply() {
val x = 7
println(x.toString)
}
})
(これが事実である理由を理解していると思います。部分式はマクロに渡される前に評価されるため、x への参照は無効です)。
だから私の質問はこれです:どうすれば上記を機能させることができますか? (マクロで定義された余分なコードを、C++ マクロのように、「m ブロック」内のコードの周りに「コピー アンド ペースト」したいだけです。)
どんな助けでも大歓迎です:-)