2009-12-26 3 views
12

J'ai dit "code en direct" parce que je ne parle pas de fichiers source de texte ou de chaînes sources, mais de partialFunctions/lambdas. (Je sais arbre syntaxique et C# de LINQ de ruby1.8 peut le faire)Puis-je obtenir AST à partir du code Scala en direct?

considèrent une fonction partielle f:

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

J'espère que il y a un outil fonctionne comme ceci:

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

Je ne t attention aux choses sémantiques (l'analyse de contexte et les implicits sont trop complexes et inutiles pour moi), j'ai juste besoin de l'arbre de syntaxe du code live, est-ce possible?

Il peut y avoir des problèmes avec l'inspection du code d'autres personnes, mais qu'en est-il de mon propre code? Est-ce que les choses suivantes sont possibles?

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

Il semble avoir besoin d'piratant le compilateur, hmmmm ...

Répondre

17

Le compilateur est lui-même une bibliothèque, que vous pouvez appeler. C'est ainsi que REPL fonctionne, en fait. Mais alors que vous pouvez obtenir l'arbre (à différentes étapes) pour une chaîne de code, vous ne pouvez pas l'obtenir pour le code compilé. Sauf, bien sûr, si vous utilisez des trucs expérimentaux qui peuvent changer à tout moment ou simplement cesser d'exister. Dans ce cas, vous pouvez essayer:

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

et obtenez:

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

Que ce soit qui aide ou non ... Vous pouvez vérifier "The Scala Compiler Corner" de Miguel Garcia.

Questions connexes