vendredi 8 juillet 2016

Scala - How to get type info from Abstract Syntax Tree in Scala reflection

I'd like to get type information from Abstract Syntax Tree in Scala reflection.

Eventually, I'd like to convert Scala code into other programming language.

For example,

Scala code

{
    val s = "hello, world"
    val d = 10
}

Converted other language code

begin
   string s :=  "hello, world";
   int d :=  10;
   return ();
end

For creating this converter, I have to get type information inferred by Scala.

I created uncompleted a converter. The following code is the uncompleted converter.

import scala.reflect.runtime.universe._

val exp = reify(
  {
    val s = "hello, world"
    val d = 10
  }
)

// convert exp.tree
println(convert(exp.tree))


// Definition of the Converter
def convert(tree: Tree): String = tree match {
  // convert "val d = 10" to "int d := 10"
  case ValDef(modifiers, variableName, typeTree, rightSide) =>
    s"[variable type] ${variableName} :=  ${convert(rightSide)};"

  /*
      {
       statementA
       statementB
      }

      into

      begin
        statementA;
        return statementB;
      end
   */
  case Block(codeList, returnValue) =>
    s"""begin
      |${codeList
        .map(convert)    // convert
        .map("    " + _) // indent
        .mkString("\n")}
      |    return ${returnValue};
      |end
      |
    """.stripMargin

  // for example,
  // Literal(Constant("hello, world") into "hello, world"
  case Literal(Constant(any)) =>
    any match {
      case _: String => "\"" + any + "\""
      case _         => any.toString
    }

  // unimplemented, unexpected or unknown tree format
  case tree =>
      "Unknown tree " + showRaw(tree)
 }

The output is the following

begin
    [variable type] s :=  hello, world;
    [variable type] d :=  10;
    return ();
end

I couldn't get type information. I want to fill [variable type] with string or int.

Could you tell me how to get type information from Abstract Syntax Tree?





Aucun commentaire:

Enregistrer un commentaire