3

私は 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 ブロック」内のコードの周りに「コピー アンド ペースト」したいだけです。)

どんな助けでも大歓迎です:-)

4

1 に答える 1