合成语法树和变量树以避免跨阶段求值
Synthesizing syntax tree and variable tree to avoid cross stage evaluation
在创建语法树时,我想将语法树中的变量综合为一棵树。
但是,跨阶段评估错误。
是否可以通过组合不同阶段的树来创建一棵树?
这是查看错误的示例。
object Sample {
case class Input(a: String, b: Int)
trait Scriber[T] {
def scribe(i: Input): T
}
trait Hoge[T] {
def exec(t: Input): Either[Throwable, T]
}
}
object Macro {
def exec[T](scribers: Seq[Scriber[_]]): Hoge[T] = macro SampleMacro.test[T]
}
class SampleMacro(val c: blackbox.Context) {
import c.universe._
def test[T: c.WeakTypeTag](scribers: c.Expr[Seq[Scriber[_]]]): c.Expr[Hoge[T]] = {
reify {
new Hoge[T] {
override def exec(t: Input): Either[Throwable, T] = {
val x = reify {
scribers.splice.map(_.scribe(t)) // <- cross stage evaluation.
}
Right(
c.Expr[T](
q"${weakTypeOf[T].typeSymbol.companion}.apply(..$x)"
).splice
)
}
}
}
}
}
在这种情况下,t是跨阶段的。
这是一个示例,其中会发生跨阶段评估错误,但即使已解决也不会起作用。
用准引号试试
def test[T: c.WeakTypeTag](scribers: c.Expr[Seq[Scriber[_]]]): c.Expr[Hoge[T]] = {
c.Expr[Hoge[T]](q"""
new Hoge[T] {
override def exec(t: Input): Either[Throwable, T] = {
val x = $scribers.map(_.scribe(t))
Right(
${weakTypeOf[T].typeSymbol.companion}.apply(x)
)
}
}""")
用reify
/splice
试试
def test[T: c.WeakTypeTag](scribers: c.Expr[Seq[Scriber[_]]]): c.Expr[Hoge[T]] =
reify {
new Hoge[T] {
override def exec(t: Input): Either[Throwable, T] = {
val x = scribers.splice.map(_.scribe(t))
Right(
c.Expr[Seq[_] => T](
q"${weakTypeOf[T].typeSymbol.companion}"
).splice.apply(x)
)
}
}
}
在创建语法树时,我想将语法树中的变量综合为一棵树。 但是,跨阶段评估错误。
是否可以通过组合不同阶段的树来创建一棵树?
这是查看错误的示例。
object Sample {
case class Input(a: String, b: Int)
trait Scriber[T] {
def scribe(i: Input): T
}
trait Hoge[T] {
def exec(t: Input): Either[Throwable, T]
}
}
object Macro {
def exec[T](scribers: Seq[Scriber[_]]): Hoge[T] = macro SampleMacro.test[T]
}
class SampleMacro(val c: blackbox.Context) {
import c.universe._
def test[T: c.WeakTypeTag](scribers: c.Expr[Seq[Scriber[_]]]): c.Expr[Hoge[T]] = {
reify {
new Hoge[T] {
override def exec(t: Input): Either[Throwable, T] = {
val x = reify {
scribers.splice.map(_.scribe(t)) // <- cross stage evaluation.
}
Right(
c.Expr[T](
q"${weakTypeOf[T].typeSymbol.companion}.apply(..$x)"
).splice
)
}
}
}
}
}
在这种情况下,t是跨阶段的。 这是一个示例,其中会发生跨阶段评估错误,但即使已解决也不会起作用。
用准引号试试
def test[T: c.WeakTypeTag](scribers: c.Expr[Seq[Scriber[_]]]): c.Expr[Hoge[T]] = {
c.Expr[Hoge[T]](q"""
new Hoge[T] {
override def exec(t: Input): Either[Throwable, T] = {
val x = $scribers.map(_.scribe(t))
Right(
${weakTypeOf[T].typeSymbol.companion}.apply(x)
)
}
}""")
用reify
/splice
试试
def test[T: c.WeakTypeTag](scribers: c.Expr[Seq[Scriber[_]]]): c.Expr[Hoge[T]] =
reify {
new Hoge[T] {
override def exec(t: Input): Either[Throwable, T] = {
val x = scribers.splice.map(_.scribe(t))
Right(
c.Expr[Seq[_] => T](
q"${weakTypeOf[T].typeSymbol.companion}"
).splice.apply(x)
)
}
}
}