lui*_*ore 12 scala abstract-syntax-tree
我说"实时代码"因为我的意思不是来自文本源文件或源字符串,而是来自partialFunctions/lambdas.(我知道Ruby1.8的parseTree和C#linq可以做到)
考虑一个partialFunction f:
val f = (i: Int, j: Int) => (i + j) * 2
Run Code Online (Sandbox Code Playgroud)
我希望有一些工具像这样:
getBodyAstFrom(f) //=> (Infix('*'), (Infix('+'), Id('i'), Id('j')), Val('2'))
Run Code Online (Sandbox Code Playgroud)
我不关心语义事物(上下文解析和implicits太复杂,对我来说是不必要的),我只需要实时代码的语法树,是否可能?
检查其他人的代码可能存在问题,但我自己的代码呢?以下事情可能吗?
val f = AstFunction(i: Int, j: Int){(i + j) * 2}
f(5, 6) //=> 22
f.ast //=> (Infix('*'), (Infix('+'), Id('i'), Id('j')), Val('2'))
Run Code Online (Sandbox Code Playgroud)
它似乎需要一些黑客入侵编译器,嗯......
Dan*_*ral 17
编译器本身就是一个可以调用的库.事实上,这就是REPL的工作方式.但是,虽然您可以获取树(在不同阶段)获取一串代码,但您无法获得编译代码.
当然,除非你使用的实验性内容可以随时改变或者只是停止存在.在这种情况下,您可以尝试:
scala.reflect.Code.lift(f).tree
Run Code Online (Sandbox Code Playgroud)
得到:
res17: scala.reflect.Tree = Select(Select(Select(Ident(Field(line26$object,PrefixedType(ThisType(RootSymbol),Class(line26$object)))),Field($iw,PrefixedType(ThisType(Class(line26$object)),Class($iw)))),Field($iw,PrefixedType(ThisType(Class($iw)),Class($iw)))),Method(f,PolyType(List(),List(),AppliedType(PrefixedType(ThisType(Class(scala)),Class(scala.Function2)),List(PrefixedType(ThisType(Class(scala)),Class(scala.Int)), PrefixedType(ThisType(Class(scala)),Class(scala.Int)), PrefixedType(ThisType(Class(scala)),Class(scala.Int)))))))
Run Code Online (Sandbox Code Playgroud)
是否有帮助......您可能想查看Miguel Garcia的" The Scala Compiler Corner ".
| 归档时间: |
|
| 查看次数: |
2101 次 |
| 最近记录: |