8

There are a few resources on the web that are instructive in writing Scala compiler plugins that pattern-match against the code, but these don't help in generating code (constructing symbol trees). Where should I start to figure out how to do this? (If there's an easier way than to manually build symbol trees, I'd be interested as well.)

For instance, I'd like write a plugin that replaces some code with a simple AST for this expression, where the variables (extracted from the original program code) could be of any type:

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

I realize this may be tricky because of boxing and toString, e.g. if hello were an object and world were an int, this should really be something like:

"".+(hello.toString().+(", ".+(new Integer(world).toString().+("!"))))
1
  • I don't know the answer to your question, but Miguel Garcia has put together the Scala Compiler Corner which is probably the best available compilation of resources about the Scala compiler. Commented Feb 12, 2010 at 4:55

3 Answers 3

3

If you generate the tree before the erasure compiler phase, you can type hello and world with Any, and call toString on them.

 ~: 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))
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the reply, but this doesn't really tell me how to generate an AST.
2

you might find something in this project: http://github.com/scala-incubator/autoproxy-plugin

1 Comment

Unfortunately, this plugin wasn't really instructive in how to construct ASTs.
1

This thread looks relevant: Convert Scala AST to source code

Specifically, you can construct Scala AST with the TreeDSL mentioned. http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/compiler/scala/tools/nsc/ast/TreeDSL.html

1 Comment

Update: There's a project that expands on the TreeDSL and looks quite usable: github.com/eed3si9n/treehugger

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.