【发布时间】:2016-01-29 11:32:43
【问题描述】:
假设我有一个 lambda,我使用 reify 将它转换为一个包裹在树周围的 Expr。例如
val expr = reify{x: Int => 3*(4+x)}
我可以对特定的 x 进行如下评估
val toolbox = currentMirror.mkToolBox()
val fun = toolbox.eval(expr.tree).asInstanceOf[Int => Int]
println(fun(10))
我的目标是打印出整个树,并用每个子表达式的值进行注释。如何确定所有子表达式及其值?例如,确定当 x 为 10 时存在子表达式
(4+x)
计算结果为 14。Traverser 类允许我访问树中的每个节点,但我不知道如何评估每个节点的子树。
例如,用下面的
class TestTraverser extends Traverser {
override def traverse(tree: Tree): Unit = {
val toolbox = currentMirror.mkToolBox()
tree match {
case app @ Apply(fun, args) =>
val f = toolbox.eval(app.fun)
case _ =>
}
super.traverse(tree)
}
}
打电话
new TestTraverser().traverse(expr.tree)
导致此异常
scala.tools.reflect.ToolBoxError: reflective compilation has failed:
ambiguous reference to overloaded definition,
both method * in class Int of type (x: Char)Int
and method * in class Int of type (x: Byte)Int
match expected type Any
【问题讨论】:
-
为子树调用 eval?
-
你会认为有一些方法可以在子树上调用 eval,但我还没有找到方法。我添加了一个 Traverser 来尝试这个并且 not 工作。
标签: scala abstract-syntax-tree