logo

class

compiler::FPrinter

sys::Obj
  compiler::FPrinter : compiler::FConst
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   26 Dec 05  Brian Frank  Creation
   7  //   19 Aug 06  Brian Frank  Ported from Java to Fan
   8  //
   9  
  10  **
  11  ** FPrinter is used to pretty print fcode
  12  **
  13  class FPrinter : FConst
  14  {
  15  
  16  //////////////////////////////////////////////////////////////////////////
  17  // Constructor
  18  //////////////////////////////////////////////////////////////////////////
  19  
  20    new make(FPod pod, OutStream out := Sys.out)
  21    {
  22      this.pod = pod
  23      this.out = out
  24    }
  25  
  26  //////////////////////////////////////////////////////////////////////////
  27  // Dump
  28  //////////////////////////////////////////////////////////////////////////
  29  
  30    Void all()
  31    {
  32      tables
  33      ftypes
  34      out.flush
  35    }
  36  
  37  //////////////////////////////////////////////////////////////////////////
  38  // Const Tables
  39  //////////////////////////////////////////////////////////////////////////
  40  
  41    Void tables()
  42    {
  43      printLine("##### Tables #####");
  44      table("--- names ---",      pod.names)
  45      table("--- typeRefs ---",   pod.typeRefs)
  46      table("--- fieldRefs ---",  pod.fieldRefs)
  47      table("--- methodRefs ---", pod.methodRefs)
  48      table("--- ints ---",       pod.ints)
  49      table("--- floats ---",     pod.floats)
  50      table("--- strs ---",       pod.strs)
  51      table("--- durations ---",  pod.durations)
  52      table("--- uris ---",       pod.uris)
  53      out.flush
  54    }
  55  
  56    Void table(Str title, FTable table)
  57    {
  58      printLine(title)
  59      table.table.each |Obj obj, Int index|
  60      {
  61        m := obj.type.method("format", false)
  62        s := m != null ? m.call([obj, pod]) : obj.toStr
  63        printLine("  [$index]  $s")
  64      }
  65    }
  66  
  67  //////////////////////////////////////////////////////////////////////////
  68  // Types
  69  //////////////////////////////////////////////////////////////////////////
  70  
  71    Void ftypes()
  72    {
  73      printLine("##### Types #####")
  74      pod.ftypes.each |FType t| { ftype(t) }
  75      out.flush
  76    }
  77  
  78    Void ftype(FType t)
  79    {
  80      printLine("--" + typeRef(t.self) + " : " + typeRef(t.fbase) + "--")
  81      if (!t.fmixins.isEmpty)
  82      {
  83        printLine("  mixin " + t.fmixins.join(", ") |Int m->Str| { return typeRef(m) });
  84      }
  85      attrs(t.fattrs)
  86      printLine
  87      t.ffields.each |FField f| { field(f) }
  88      t.fmethods.each |FMethod m| { method(m) }
  89      out.flush
  90    }
  91  
  92    Void slot(FSlot s)
  93    {
  94      if (s is FField)
  95        field((FField)s)
  96      else
  97        method((FMethod)s)
  98      out.flush
  99    }
 100  
 101    Void field(FField f)
 102    {
 103      printLine("  " + name(f.nameIndex) + " -> " + typeRef(f.typeRef) + " [" + flags(f.flags) + "]")
 104      attrs(f.fattrs)
 105      printLine
 106    }
 107  
 108    Void method(FMethod m)
 109    {
 110      print("  " + name(m.nameIndex) + " (")
 111      print(m.fparams.join(", ") |FMethodVar p->Str| { return typeRef(p.typeRef) + " " + name(p.nameIndex) })
 112      print(") -> " + typeRef(m.ret))
 113      if (m.ret != m.inheritedRet) print(" {" + typeRef(m.inheritedRet) + "}")
 114      printLine(" [" + flags(m.flags) + "]")
 115      m.vars.each |FMethodVar v, Int reg|
 116      {
 117        role := v.isParam ?  "Param" : "Local"
 118        if (m.flags & FConst.Static == 0) reg++
 119        printLine("    [" + role + " " + reg + "] " + pod.n(v.nameIndex) + " -> " + typeRef(v.typeRef))
 120        if (v.def != null) code(v.def)
 121      }
 122      if (m.code != null)
 123      {
 124        printLine("    [Code]")
 125        code(m.code)
 126      }
 127      attrs(m.fattrs)
 128      printLine
 129    }
 130  
 131    Void code(Buf code)
 132    {
 133      if (!showCode) return;
 134      out.flush
 135      codePrinter := FCodePrinter.make(pod, out)
 136      codePrinter.showIndex = showIndex
 137      codePrinter.code(code)
 138    }
 139  
 140  //////////////////////////////////////////////////////////////////////////
 141  // Attributes
 142  //////////////////////////////////////////////////////////////////////////
 143  
 144    Void attrs(FAttr[] attrs)
 145    {
 146      if (attrs == null) return
 147      attrs.each |FAttr a| { attr(a) }
 148    }
 149  
 150    Void attr(FAttr attr)
 151    {
 152      name := name(attr.name)
 153      if (name == LineNumbersAttr && !showLines) return
 154      printLine("    [$name] size=$attr.data.size")
 155      if (name == SourceFileAttr)  sourceFileAttr(attr)
 156      if (name == ErrTableAttr)    errTableAttr(attr)
 157      if (name == LineNumberAttr)  lineNumberAttr(attr)
 158      if (name == LineNumbersAttr) lineNumbersAttr(attr)
 159      if (name == FacetsAttr)      facetsAttr(attr)
 160    }
 161  
 162    Void sourceFileAttr(FAttr attr)
 163    {
 164      printLine("       $attr.utf")
 165    }
 166  
 167   Void lineNumberAttr(FAttr attr)
 168    {
 169      printLine("       $attr.u2")
 170    }
 171  
 172    Void facetsAttr(FAttr attr)
 173    {
 174      buf := attr.data
 175      buf.seek(0)
 176      buf.readU2.times |,|
 177      {
 178        name := name(buf.readU2)
 179        val  := buf.readUtf
 180        printLine("       $name=$val")
 181      }
 182    }
 183  
 184    Void errTableAttr(FAttr attr)
 185    {
 186      buf := attr.data
 187      buf.seek(0)
 188      buf.readU2.times |,|
 189      {
 190        start   := buf.readU2
 191        end     := buf.readU2
 192        handler := buf.readU2
 193        tr      := buf.readU2
 194        printLine("      $start  to $end -> $handler  " + typeRef(tr))
 195      }
 196    }
 197  
 198    Void lineNumbersAttr(FAttr attr)
 199    {
 200      buf := attr.data
 201      buf.seek(0)
 202      buf.readU2.times |,|
 203      {
 204        pc   := buf.readU2
 205        line := buf.readU2
 206        printLine("       $pc: $line")
 207      }
 208    }
 209  
 210  //////////////////////////////////////////////////////////////////////////
 211  // Dump Utils
 212  //////////////////////////////////////////////////////////////////////////
 213  
 214    Str typeRef(Int i)
 215    {
 216      if (i == 65535) return "null"
 217      return pod.typeRefStr(i) + index(i)
 218    }
 219  
 220    Str name(Int i)
 221    {
 222      return pod.n(i) + index(i)
 223    }
 224  
 225    Str flags(Int flags)
 226    {
 227      s := StrBuf.make
 228      if (flags & FConst.Abstract  != 0) s.add("abstract ")
 229      if (flags & FConst.Const     != 0) s.add("const ")
 230      if (flags & FConst.Ctor      != 0) s.add("ctor ")
 231      if (flags & FConst.Enum      != 0) s.add("enum ")
 232      if (flags & FConst.Final     != 0) s.add("final ")
 233      if (flags & FConst.Getter    != 0) s.add("getter ")
 234      if (flags & FConst.Internal  != 0) s.add("internal ")
 235      if (flags & FConst.Mixin     != 0) s.add("mixin ")
 236      if (flags & FConst.Native    != 0) s.add("native ")
 237      if (flags & FConst.Override  != 0) s.add("override ")
 238      if (flags & FConst.Private   != 0) s.add("private ")
 239      if (flags & FConst.Protected != 0) s.add("protected ")
 240      if (flags & FConst.Public    != 0) s.add("public ")
 241      if (flags & FConst.Setter    != 0) s.add("setter ")
 242      if (flags & FConst.Static    != 0) s.add("static ")
 243      if (flags & FConst.Storage   != 0) s.add("storage ")
 244      if (flags & FConst.Synthetic != 0) s.add("synthetic ")
 245      if (flags & FConst.Virtual   != 0) s.add("virtual ")
 246      return s.toStr[0..-2]
 247    }
 248  
 249    Str index(Int index)
 250    {
 251      if (showIndex) return "[" + index + "]"
 252      return ""
 253    }
 254  
 255  //////////////////////////////////////////////////////////////////////////
 256  // Print
 257  //////////////////////////////////////////////////////////////////////////
 258  
 259    FPrinter print(Obj obj) { out.print(obj); return this }
 260    FPrinter printLine(Obj obj := "") { out.printLine(obj); return this }
 261  
 262  //////////////////////////////////////////////////////////////////////////
 263  // Fields
 264  //////////////////////////////////////////////////////////////////////////
 265  
 266    FPod pod
 267    OutStream out
 268    Bool showIndex := false
 269    Bool showCode  := true
 270    Bool showLines := false
 271  
 272  }