2010-02-12 2 views
7

В Интернете есть fewresources, которые поучительны в написании плагинов-компиляторов Scala, которые соответствуют шаблону, но не помогают генерировать код (построение деревьев символов) , Где я должен начать выяснять, как это сделать? (Если есть более простой способ, чем вручную создавать деревья символов, мне тоже было бы интересно.)Создание деревьев кода Scala из плагина-компилятора Scala

Например, я бы хотел написать плагин, который заменяет некоторый код простым АСТ для этого выражения, где переменные (извлеченные из исходного кода программы) может быть любого типа:

"" + hello + ", " + world + "!" 

Я понимаю, что это может быть сложно из-за бокса и toString, например, если hello были объектом и world были ИНТ, это должно быть действительно что-то вроде:

"".+(hello.toString().+(", ".+(new Integer(world).toString().+("!")))) 
+0

Я не знаю ответа на ваш вопрос, но Мигель Гарсия собрал [Угол компилятора Scala] (http://www.sts.tu-harburg.de/people/mi.garcia/ScalaCompilerCorner /), который, вероятно, является наилучшей доступной компиляцией ресурсов о компиляторе Scala. –

ответ

3

Если вы создаете дерево до фазы erasure компилятора, вы можете ввести hello и world с Any и вызвать toString на них.

~: cat test.scala 
object test { 
    def f(hello: Any, world: Any) = "" + hello + ", " + world + "!" 
    f("1", "2") 
    f(1, 1) 
} 
~: scalac -Xprint:typer test.scala 
[[syntax trees at end of typer]]// Scala source: test.scala 
package <empty> { 
    final object test extends java.lang.Object with ScalaObject { 
    def this(): object test = { 
     test.super.this(); 
    () 
    }; 
    def f(hello: Any, world: Any): java.lang.String = "".+(hello).+(", ").+(world).+("!"); 
    test.this.f("1", "2"); 
    test.this.f(1, 1) 
    } 
} 

~: scalac -Xprint:erasure test.scala 
[[syntax trees at end of erasure]]// Scala source: test.scala 
package <empty> { 
    final class test extends java.lang.Object with ScalaObject { 
    def this(): object test = { 
     test.super.this(); 
    () 
    }; 
    def f(hello: java.lang.Object, world: java.lang.Object): java.lang.String = "".+(hello).+(", ").+(world).+("!"); 
    test.this.f("1", "2"); 
    test.this.f(scala.Int.box(1), scala.Int.box(1)) 
    } 
} 
+0

Спасибо за ответ, но это не говорит мне, как создать АСТ. – Yang

1

Эта нить выглядит уместным: Convert Scala AST to source code

В частности, вы можете построить Scala AST с TreeDSL упоминается. http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/compiler/scala/tools/nsc/ast/TreeDSL.html

+0

Обновление: есть проект, который расширяется на TreeDSL и выглядит вполне применимым: https://github.com/eed3si9n/treehugger – pdxleif

Смежные вопросы