我对 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 的引用是无效的)。
所以我的问题是:我怎样才能使上述工作?(我只想将宏中定义的额外代码“复制粘贴”在“m 块”中的代码周围,就像在 C++ 宏中一样。)
任何帮助将不胜感激 :-)