summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
blob: 68ead723d73f76125295e46d52a36f6a04831e6a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* NSC -- new scala compiler
 * Copyright 2005 LAMP/EPFL
 * @author  Martin Odersky
 */

// $Id$

package scala.tools.nsc.backend.icode;

import java.io.PrintWriter;

import scala.tools.nsc.util.Position;
import scala.tools.nsc.symtab.Flags;

abstract class Printers {
  val global: Global;
  import global._;
  import global.icodes.opcodes._;
  import global.icodes._;

  class TextPrinter(writer: PrintWriter) {
    var margin = 0;
    var out = writer;

    final val TAB = 2;

    def setWriter(w: PrintWriter) = (out = w);

    def indent = margin = margin + TAB;
    def undent = margin = margin - TAB;

    def print(s: String) = out.print(s);
    def print(o: Any): Unit = print(o.toString());

    def println(s: String): Unit = {
      print(s);
      println
    }

    def println = {
      out.println();
      var i = 0;
      while (i < margin) {
        print(" ");
        i = i + 1;
      }
    }

    def printList[a](l: List[a], sep: String): Unit = l match {
      case Nil => ();
      case x :: Nil => print(x);
      case x :: xs  => print(x); print(sep); printList(xs, sep);
    }

    def printList[a](pr: a => Unit)(l: List[a], sep: String): Unit = l match {
      case Nil => ();
      case x :: Nil => pr(x);
      case x :: xs  => pr(x); print(sep); printList(pr)(xs, sep);
    }


    private var clazz : IClass = _;
    def printClass(cls: IClass): Unit = {
      this.clazz = cls;
      print(cls.symbol.toString()); print(" extends ");
      printList(cls.symbol.info.parents, ", ");
      indent; println(" {");
      println("// fields:");
      cls.fields.foreach(printField); println;
      println("// methods");
      cls.methods.foreach(printMethod);
      undent; println;
      println("}");
    }

    def printField(f: IField): Unit = {
      print(f.symbol.keyString); print(" ");
      print(f.symbol.nameString); print(": ");
      println(f.symbol.info.toString());
    }

    def printMethod(m: IMethod): Unit = {
      print("def "); print(m.symbol.name);
      print("("); printList(printParam)(m.params.reverse, ", "); print(")");
      print(": "); print(m.symbol.info.resultType);

      if (!m.isDeferred) {
        println(" {");
        println("locals: " + m.locals.mkString("", ", ", ""));
        println;
        linearizer.linearize(m) foreach printBlock;
        println("}");

        indent;println("Exception handlers: ");
        m.exh foreach printExceptionHandler;

        undent;println;
      } else
        println;
    }

    def printParam(p: Local): Unit = {
      print(p.sym.name); print(": "); print(p.sym.info);
      print(" ("); print(p.kind); print(")");
    }

    def printExceptionHandler(e: ExceptionHandler) = {
      indent;
      println("catch (" + e.cls.simpleName + ") in " + e.covered + " starting at: " + e.startBlock);
      undent;
      println("with finalizer: " + e.finalizer);
//      linearizer.linearize(e.startBlock) foreach printBlock;
    }

    def printBlock(bb: BasicBlock): Unit = {
      print(bb.label); print(": "); indent; println;
      bb traverse printInstruction;
      undent; println;
    }

    def printInstruction(i: Instruction): Unit = {
      if (settings.debug.value)
        print("/* " + Position.line(clazz.cunit.source, i.pos) + " */ ");
      println(i.toString());
    }
  }
}