【问题标题】:Generate a new value in Scala AST在 Scala AST 中生成新值
【发布时间】:2015-08-30 00:45:37
【问题描述】:

我在编译期间使用 API 来重建 scala AST。

我想更改一个“应用”AST,例如

a(1)

进入“分配并返回”块

{

val newvalue = a(1)

newvalue

}

这是我在 AST 中生成新值的代码:

val newVal : Tree = gen.mkPatDef(Typed(Ident(newTermName("newvalue")), returnType), a)(new FreshNameCreator("newvalue"))(0)
val newSymbol = newVal.symbol.newValue(newTermName("newvalue"), a.pos, 0)
newVal.setSymbol(newSymbol)
newVal.setType(a.tpe)
newVal.symbol.setName(newTermName("newvalue"))
newVal.symbol.setInfo(a.tpe)

在代码中,“a”是 Apply AST

我在scala编译器阶段“packageobjects”之后进行了这个更改,AST树的转换可以完成,但之后总是卡住。我想问题在于“newvalue”的符号,因为如果我使用现有值的现有符号而不是自己创建一个新符号,它就可以工作。

谢谢。

【问题讨论】:

  • 请重新编辑您的问题。
  • @luoluo 感谢您查看我的问题。你能检查一下我现在说清楚了吗?基本上,在一个scala程序的AST树中,当我发现一个函数A调用另一个函数B作为它的返回值时,我想先把B的调用赋值给一个新值,然后用这个新值作为返回值A. 你能告诉我怎么做吗?

标签: scala abstract-syntax-tree


【解决方案1】:

想办法!当函数调用“a”返回“Unit”时会出现另一个问题,在这种情况下,当我使用“newvalue”作为返回时,它会报告类型不匹配错误:

错误:java.lang.AssertionError:断言失败:无法在源单元 hello.scala 中从 UNIT 转换为 REF(类 BoxedUnit)-/Users/shiyu/Scala/FinalDataFlow/src/print/hello.scala ,line-347,offset=13999

但我下面的代码适用于其他情况。代码中“d”为函数定义的DefDef AST节点,“a”为“d”末尾尾部函数调用的Apply AST节点,“b”为“d”的右侧Block .

val newVal = ValDef(Modifiers(0), newTermName("newvalue"), d.tpt, treeCopy.Apply(a, a.fun, a.args))
val newSymbol = a.symbol.newValue(newTermName("newvalue"), a.pos, 0) 
newSymbol.owner = d.symbol
newVal.setSymbol(newSymbol)
newVal.symbol.setName(newTermName("newvalue"))
newVal.symbol.setInfo(a.tpe)
newVal.setType(a.tpe)
val newIdent = Ident(newVal.symbol)
newIdent.setType(a.tpe)
treeCopy.DefDef(d, mods, name, tparams, vparamss, tpt, treeCopy.Block(rhs, b.stats ::: List(newVal), newIdent))

【讨论】:

  • 谁能告诉我 Scala 中 UNIT 和 boxedUnit 的区别?
猜你喜欢
  • 1970-01-01
  • 2015-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-07
  • 2014-08-12
相关资源
最近更新 更多