2009-12-26 4 views
12

Ich sagte "Live-Code", weil ich meine nicht von Text Quelldateien oder Quellstrings, sondern von PartialFunctions/Lambdas. (Ich weiß ruby1.8 der Syntaxbaum und C# Linq es tun kann)Kann ich AST von Live Scala Code bekommen?

eine Partielle Funktion f betrachten:

val f = (i: Int, j: Int) => (i + j) * 2 

Ich hoffe, dass es einige Tool funktioniert wie folgt:

getBodyAstFrom(f) //=> (Infix('*'), (Infix('+'), Id('i'), Id('j')), Val('2')) 

I don‘ Ich kümmere mich um die semantischen Dinge (Kontextanalyse und implicits sind zu komplex und unnötig für mich), ich brauche nur den Syntaxbaum aus Live-Code, ist das möglich?

Möglicherweise gibt es Probleme bei der Überprüfung des Codes anderer Personen, aber was ist mit meinem eigenen Code? Sind folgende Dinge möglich?

val f = AstFunction(i: Int, j: Int){(i + j) * 2} 
f(5, 6) //=> 22 
f.ast //=> (Infix('*'), (Infix('+'), Id('i'), Id('j')), Val('2')) 

Es scheint, nennen einige Hacker in den Compiler, hmmmm ...

Antwort

17

Der Compiler selbst ist eine Bibliothek, die Sie benötigen. So funktioniert REPL. Aber während Sie die Struktur (in verschiedenen Phasen) für eine Codezeile abrufen können, können Sie sie nicht für kompilierten Code abrufen.

Außer, natürlich, wenn Sie experimentelle Dinge verwenden, die sich jederzeit ändern oder einfach aufhören können zu existieren. In diesem Fall können Sie versuchen:

scala.reflect.Code.lift(f).tree 

Und erhalten:

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))))))) 

Ob das hilft oder nicht ... Vielleicht möchten Sie Miguel Garcia "The Scala Compiler Corner" überprüfen.