Scala 2.8 compiler process sources trough 27 phases.
Compiler phases
# I'll illustrate `what's going on' in `bash code
scalac -Xshow-phases
The naming of those phases defined in man page. To get to the meaning we have to detour and become compiler hacker or rediscover stuff hands on style. I'm not that much into compiler internals yet and have to choose `discovery mode.
Collecting information
man scalac
Compilation Phases
initial - initializing compiler
parse - parse source files
namer - create symbols
analyze - name and type analysis
refcheck - reference checking
uncurry - uncurry function types and applications
transmatch - translate match expressions
lambdalift - lambda lifter
typesasvalues - represent types as values
addaccessors - add accessors for constructor arguments
explicitouterclasses - make links from inner classes to enclosing one explicit
addconstructors - add explicit constructor for each class
tailcall - add tail-calls
wholeprog - perform whole program analysis
addinterfaces - add one interface per class
expandmixins - expand mixins by code copying
boxing - makes boxing explicit
erasure - type eraser
icode - generate icode
codegen - enable code generation
terminal - compilation terminated
Lets prepare stage.
We use simple code with `case class and `for expression.
// Scala source: Frameworks.scala
object cph {
case class Person(name: String, mail: Boolean, children: Person*)
//
val bob = Person("Bob", true)
val aida = Person("Aida", false)
val cipi = Person("Cipi", true, bob, aida)
val alina = Person("Alina", false, bob, aida)
val all = List(bob, aida, cipi, alina)
// println(all)
//
val mochi = all filter (_.mail == false)
flatMap (p => p.children map (c => (p, c)))
//
mochi foreach {
pair =>
val (p: Person, c: Person) = pair
println(p.name + " > " + c.name)
}
//
val motherOf = for (m <- all;
c <- m.children
if m.mail == false)
yield (m, c)
//
for ((m, c) <- motherOf)
println (m.name + " - " + c.name)
}
(1) - Code formatting made ugly on purpose. I'm working with `emacs scala-mode with `sbt replacing `scala shell. Coding paralleled with 'sbt> ~compile', which means `compile whenever source files change. Going to REPL with 'sbt> console-project' I can use select paragraph M-h then sent it to interpreter with C-c-e. That's why scala blocks formatted as emacs paragraphs.
Generate reports for all phases.
$ scalac -Xshow-phases 2>&1 |while read f; do echo ">> $f";
> scalac -Xprint:$f Frameworks.scala 2>&1 > Frameworks.$f.scala;
> done
Analyze
We need diff's from consecutive phase. Could be done nicely with change-set manager HG designed just for this.
scalac -Xshow-phases > scala.phases
for f in `cat scala.phases `; do echo ">> $f";
cp Frameworks.$f.scala Frameworks.scala;
hg ci -m"$f" Frameworks.scala;
done
hg log Frameworks.scala
changeset: 34:c03403f4f0c4
summary: namer
changeset: 33:37ed3eeb753e
summary: parser
changeset: 32:917dc0255899
summary: add Framework.scala
hg diff -r33:34
diff -r 37ed3eeb753e -r c03403f4f0c4 ScalaLanguage/src/main/scala/Frameworks.scala
--- a/ScalaLanguage/src/main/scala/Frameworks.scala Sun Aug 15 13:03:51 2010 +0300
+++ b/ScalaLanguage/src/main/scala/Frameworks.scala Sun Aug 15 13:03:51 2010 +0300
@@ -1,6 +1,6 @@
-[[syntax trees at end of parser]]// Scala source: Frameworks.scala
+[[syntax trees at end of namer]]// Scala source: Frameworks.scala
package {
- object cph extends scala.ScalaObject {
+ final object cph extends scala.ScalaObject {
def () = {
super.();
()
Visualizing
It shouldn't be that much console stuff, but there is nice 'unix tradition to get you trough process even if don't have installed `kdiff3 or `hgview.
|
hgview on scalac phases |
I was looking for translation of `for expression. Surprisingly, it done at the very beginning in `parse phase.
I followed remaining phases too. It is quite entertaining to see code morphing from Sources to JVM. It's also much more educative that simple `scalap -verbose or even `jd. However good showing off need special code snippets for which I'm going to look because it worse effort.
Naming phase.
Typer phase.
Specialize to ExplicitOuter.