1 cananian 1.1.2.1  // Print.java, created Wed Jan 13 21:14:57 1999 by cananian
  2 cananian 1.1.2.16 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.16 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1.2.1  package harpoon.IR.Tree;
  5 cananian 1.1.2.1  
  6 cananian 1.1.2.39 import harpoon.ClassFile.HCode.PrintCallback;
  7 cananian 1.1.2.39 import harpoon.ClassFile.HCodeElement;
  8 cananian 1.1.2.39 
  9 cananian 1.1.2.1  import harpoon.Temp.Temp;
 10 cananian 1.1.2.1  import harpoon.Temp.TempMap;
 11 andyb    1.1.2.9  import harpoon.Temp.LabelList;
 12 pnkfelix 1.1.2.33 
 13 pnkfelix 1.1.2.33 import harpoon.Util.Util;
 14 pnkfelix 1.1.2.33 
 15 andyb    1.1.2.8  import java.io.PrintWriter;
 16 pnkfelix 1.1.2.20 import java.io.StringWriter;
 17 cananian 1.1.2.39 import java.util.Map;
 18 cananian 1.1.2.1  
 19 cananian 1.1.2.1  /**
 20 cananian 1.1.2.1   * <code>Print</code> pretty-prints Trees.
 21 cananian 1.1.2.1   * 
 22 cananian 1.1.2.1   * @author  C. Scott Ananian <cananian@alumni.princeton.edu>, based on
 23 cananian 1.1.2.1   *          <i>Modern Compiler Implementation in Java</i> by Andrew Appel.
 24 cananian 1.4       * @version $Id: Print.java,v 1.4 2002/04/10 03:05:45 cananian Exp $
 25 cananian 1.1.2.1   */
 26 andyb    1.1.2.9  public class Print {
 27 witchel  1.1.2.38     public final static void print(PrintWriter pw, Code c, TempMap tm,
 28 cananian 1.3.2.2                                     PrintCallback<Tree> cb) {
 29 andyb    1.1.2.9          Tree tr = (Tree) c.getRootElement();
 30 cananian 1.1.2.39         PrintVisitor pv = new PrintVisitor(pw, tm, cb);
 31 andyb    1.1.2.9  
 32 andyb    1.1.2.9          pw.print("Codeview \""+c.getName()+"\" for "+c.getMethod()+":");
 33 cananian 1.1.2.35         for (StmList slp=linearize((Stm)tr, null); slp!=null; slp=slp.tail)
 34 cananian 1.1.2.35             slp.head.accept(pv);
 35 duncan   1.1.2.13         pw.println();
 36 duncan   1.1.2.13         pw.flush();
 37 duncan   1.1.2.13     }
 38 duncan   1.1.2.13 
 39 cananian 1.1.2.39     public final static void print(PrintWriter pw, Data d, TempMap tm,
 40 cananian 1.3.2.2                                     PrintCallback<Tree> cb) { 
 41 duncan   1.1.2.13         Tree tr = (Tree)d.getRootElement();
 42 cananian 1.1.2.39         PrintVisitor pv = new PrintVisitor(pw, tm, cb);
 43 duncan   1.1.2.13 
 44 cananian 1.1.2.23         pw.print("Dataview \""+d.getDesc()+"\" for "+d.getHClass()+":");
 45 cananian 1.1.2.35         for (StmList slp=linearize((Stm)tr, null); slp!=null; slp=slp.tail)
 46 cananian 1.1.2.35             slp.head.accept(pv);
 47 andyb    1.1.2.9          pw.println();
 48 andyb    1.1.2.9          pw.flush();
 49 andyb    1.1.2.9      }
 50 andyb    1.1.2.9  
 51 cananian 1.3.2.2      public final static void print(PrintWriter pw, Code c, PrintCallback<Tree> cb) {
 52 cananian 1.1.2.39         print(pw, c, null, cb);
 53 cananian 1.1.2.23     }
 54 cananian 1.3.2.2      public final static void print(PrintWriter pw, Data d, PrintCallback<Tree> cb) {
 55 cananian 1.1.2.39         print(pw, d, null, cb);
 56 pnkfelix 1.1.2.20     }
 57 pnkfelix 1.1.2.20 
 58 cananian 1.1.2.39     public final static void print(PrintWriter pw, Code c, final Map ht) {
 59 cananian 1.3.2.2          print(pw, c, null, new PrintCallback<Tree>() {
 60 cananian 1.3.2.2              public void printAfter(PrintWriter _pw_, Tree hce) {
 61 cananian 1.1.2.39                 if (ht.containsKey(hce)) _pw_.print(ht.get(hce));
 62 cananian 1.1.2.39             }
 63 cananian 1.1.2.39         });
 64 witchel  1.1.2.38     }
 65 witchel  1.1.2.38 
 66 pnkfelix 1.1.2.20     public final static void print(PrintWriter pw, Tree t) {
 67 witchel  1.1.2.38         PrintVisitor pv = new PrintVisitor(pw, null, null);
 68 cananian 1.1.2.27         t.accept(pv);
 69 pnkfelix 1.1.2.20         pw.println();
 70 pnkfelix 1.1.2.20         pw.flush();
 71 pnkfelix 1.1.2.20     }
 72 pnkfelix 1.1.2.20 
 73 pnkfelix 1.1.2.20     public final static String print(Tree t) {
 74 pnkfelix 1.1.2.20         StringWriter sw = new StringWriter();
 75 pnkfelix 1.1.2.20         PrintWriter pw = new PrintWriter(sw);
 76 witchel  1.1.2.38         PrintVisitor pv = new PrintVisitor(pw, null, null);
 77 pnkfelix 1.1.2.33         if (t!=null) {
 78 pnkfelix 1.1.2.33             t.accept(pv);
 79 pnkfelix 1.1.2.33         } else {
 80 pnkfelix 1.1.2.33             pw.print("null");
 81 pnkfelix 1.1.2.33         }
 82 pnkfelix 1.1.2.33             
 83 pnkfelix 1.1.2.20         pw.flush();
 84 pnkfelix 1.1.2.20         return sw.toString();
 85 andyb    1.1.2.9      }
 86 andyb    1.1.2.9  
 87 cananian 1.1.2.35     private static StmList linearize(Stm s, StmList tail) {
 88 cananian 1.1.2.35         if (s==null) return tail; // deal gracefully.
 89 cananian 1.1.2.35         if (s instanceof SEQ)
 90 cananian 1.1.2.35             return linearize(((SEQ)s).getLeft(),
 91 cananian 1.1.2.35                              linearize(((SEQ)s).getRight(), tail));
 92 cananian 1.1.2.35         return new StmList(s, tail);
 93 cananian 1.1.2.35     }
 94 cananian 1.1.2.35 
 95 andyb    1.1.2.9      static class PrintVisitor extends TreeVisitor {
 96 andyb    1.1.2.9          private final static int TAB = 1;
 97 andyb    1.1.2.9          private PrintWriter pw;
 98 andyb    1.1.2.9          private TempMap tm;
 99 cananian 1.3.2.2          private PrintCallback<Tree> cb;
100 andyb    1.1.2.9          private int indlevel;
101 andyb    1.1.2.9  
102 cananian 1.3.2.2          PrintVisitor(PrintWriter pw, TempMap tm, PrintCallback<Tree> cb) {
103 andyb    1.1.2.9              indlevel = 1;
104 andyb    1.1.2.9              this.pw = pw;
105 andyb    1.1.2.9              this.tm = tm;
106 cananian 1.3.2.2              this.cb = (cb==null) ? new PrintCallback<Tree>() : cb;
107 pnkfelix 1.1.2.33 
108 cananian 1.3.2.1              // assert false : "Printing Trees is *slow*";
109 andyb    1.1.2.9          }
110 andyb    1.1.2.9  
111 andyb    1.1.2.9          private void indent(int dist) {
112 andyb    1.1.2.9              pw.println();
113 andyb    1.1.2.9              for (int i=0; i < TAB * dist; i++)
114 andyb    1.1.2.9                  pw.print(' ');
115 andyb    1.1.2.9          }
116 andyb    1.1.2.9  
117 duncan   1.1.2.10         public void visit(Tree e) {
118 duncan   1.1.2.10             throw new Error("Can't print abstract class!");
119 cananian 1.1.2.28         }
120 cananian 1.1.2.28 
121 cananian 1.1.2.28         public void visit(ALIGN s) { 
122 cananian 1.1.2.36             indent(indlevel);
123 cananian 1.1.2.28             pw.print(s.toString());
124 cananian 1.1.2.39             cb.printAfter(pw, s);
125 duncan   1.1.2.10         }
126 andyb    1.1.2.9  
127 andyb    1.1.2.9          public void visit(BINOP e) {
128 andyb    1.1.2.9              indent(indlevel++);
129 andyb    1.1.2.9              pw.print("BINOP<" + Type.toString(e.optype) + ">(");
130 andyb    1.1.2.9              pw.print(Bop.toString(e.op) + ", ");
131 duncan   1.1.2.31             e.getLeft().accept(this);
132 andyb    1.1.2.9              pw.print(",");
133 duncan   1.1.2.31             e.getRight().accept(this);
134 andyb    1.1.2.9              pw.print(")");
135 cananian 1.1.2.39             cb.printAfter(pw, e);
136 andyb    1.1.2.9              indlevel--;
137 andyb    1.1.2.9          }
138 andyb    1.1.2.9  
139 andyb    1.1.2.9          public void visit(CALL s) {
140 duncan   1.1.2.31             ExpList list = s.getArgs();
141 andyb    1.1.2.9              indent(indlevel++);
142 cananian 1.1.2.29             pw.print("CALL" + (s.isTailCall?" [tail call] (" : "("));
143 andyb    1.1.2.9              indent(indlevel++);
144 duncan   1.1.2.31             if (s.getRetval()!=null) {
145 cananian 1.1.2.29                 pw.print("return value:");
146 duncan   1.1.2.31                 s.getRetval().accept(this);
147 cananian 1.1.2.29                 pw.print(",");
148 cananian 1.1.2.29                 indent(--indlevel); indlevel++;
149 cananian 1.1.2.29             }
150 andyb    1.1.2.9              pw.print("exceptional value:");
151 duncan   1.1.2.31             s.getRetex().accept(this);
152 andyb    1.1.2.9              pw.print(",");
153 andyb    1.1.2.9              indent(--indlevel); indlevel++;
154 andyb    1.1.2.9              pw.print("function:");
155 duncan   1.1.2.31             s.getFunc().accept(this);
156 andyb    1.1.2.9              pw.print(",");
157 andyb    1.1.2.9              indent(--indlevel); indlevel++;
158 andyb    1.1.2.9              pw.print("arguments:");
159 andyb    1.1.2.9              while (list != null) {
160 cananian 1.1.2.27                 list.head.accept(this);
161 andyb    1.1.2.9                  if (list.tail != null) {
162 andyb    1.1.2.9                      pw.print(",");
163 andyb    1.1.2.9                  }
164 andyb    1.1.2.9                  list = list.tail;
165 andyb    1.1.2.9              }
166 cananian 1.1.2.29             pw.print(",");
167 cananian 1.1.2.29             indent(--indlevel); indlevel++;
168 cananian 1.1.2.29             pw.print("handler:");
169 duncan   1.1.2.31             s.getHandler().accept(this);
170 andyb    1.1.2.9              pw.print(")");
171 cananian 1.1.2.39             cb.printAfter(pw, s);
172 andyb    1.1.2.9              indlevel -= 2;
173 andyb    1.1.2.9          }
174 andyb    1.1.2.9              
175 andyb    1.1.2.9          public void visit(CJUMP s) {
176 andyb    1.1.2.9              indent(indlevel++);
177 andyb    1.1.2.9              pw.print("CJUMP(");
178 duncan   1.1.2.31             s.getTest().accept(this); pw.print(",");
179 andyb    1.1.2.9              indent(indlevel);
180 andyb    1.1.2.9              pw.print("if-true: " + s.iftrue + ",");
181 andyb    1.1.2.9              indent(indlevel);
182 andyb    1.1.2.9              pw.print("if-false: " + s.iffalse + ")");
183 cananian 1.1.2.39             cb.printAfter(pw, s);
184 andyb    1.1.2.9              indlevel--;
185 andyb    1.1.2.9          }
186 andyb    1.1.2.9  
187 andyb    1.1.2.9          public void visit(CONST e) {
188 andyb    1.1.2.9              indent(indlevel);
189 cananian 1.1.2.25             pw.print("CONST<" + Type.toString(e) + ">(" + e.value + ")");
190 cananian 1.1.2.39             cb.printAfter(pw, e);
191 andyb    1.1.2.9          }
192 duncan   1.1.2.11 
193 cananian 1.1.2.32         public void visit(DATUM s) { 
194 duncan   1.1.2.11             indent(indlevel++);
195 cananian 1.1.2.32             pw.print("DATUM<");
196 duncan   1.1.2.31             if (s.getData() instanceof PreciselyTyped)
197 duncan   1.1.2.31                 pw.print(Type.toString((PreciselyTyped)s.getData()));
198 duncan   1.1.2.31             else pw.print(Type.toString(s.getData().type()));
199 cananian 1.1.2.26             pw.print(">(");
200 cananian 1.1.2.26             if (!s.initialized) pw.print("unspecified value");
201 duncan   1.1.2.31             else s.getData().accept(this); 
202 duncan   1.1.2.11             indent(indlevel--);
203 duncan   1.1.2.11             pw.print(")");
204 cananian 1.1.2.39             cb.printAfter(pw, s);
205 duncan   1.1.2.11         }
206 andyb    1.1.2.9  
207 andyb    1.1.2.9          public void visit(ESEQ e) {
208 cananian 1.1.2.36             indent(indlevel++);
209 andyb    1.1.2.9              pw.print("ESEQ(");
210 duncan   1.1.2.31             e.getStm().accept(this);
211 andyb    1.1.2.9              pw.print(",");
212 duncan   1.1.2.31             e.getExp().accept(this);
213 andyb    1.1.2.9              pw.print(")");
214 cananian 1.1.2.39             cb.printAfter(pw, e);
215 cananian 1.1.2.36             indlevel--;
216 andyb    1.1.2.9          }
217 andyb    1.1.2.9  
218 jwhaley  1.1.2.37         public void visit(EXPR s) {
219 andyb    1.1.2.9              indent(indlevel++);
220 jwhaley  1.1.2.37             pw.print("EXPR(");
221 duncan   1.1.2.31             s.getExp().accept(this);
222 andyb    1.1.2.9              pw.print(")");
223 cananian 1.1.2.39             cb.printAfter(pw, s);
224 andyb    1.1.2.9              indlevel--;
225 andyb    1.1.2.9          }
226 andyb    1.1.2.9  
227 andyb    1.1.2.9          public void visit(JUMP s) {
228 andyb    1.1.2.9              LabelList list = s.targets;
229 andyb    1.1.2.9              indent(indlevel++);
230 andyb    1.1.2.9              pw.print("JUMP(");
231 andyb    1.1.2.9              indent(indlevel);
232 andyb    1.1.2.9              pw.print("targets:");
233 andyb    1.1.2.9              while (list != null) {
234 andyb    1.1.2.9                  pw.print(" " + list.head);
235 andyb    1.1.2.9                  if (list.tail != null) 
236 andyb    1.1.2.9                      pw.print(",");
237 andyb    1.1.2.9                  list = list.tail;
238 andyb    1.1.2.9              }
239 duncan   1.1.2.31             s.getExp().accept(this);
240 andyb    1.1.2.9              pw.print(")");
241 cananian 1.1.2.39             cb.printAfter(pw, s);
242 andyb    1.1.2.9              indlevel--;
243 andyb    1.1.2.9          }
244 andyb    1.1.2.9              
245 andyb    1.1.2.9  
246 andyb    1.1.2.9          public void visit(LABEL s) {
247 andyb    1.1.2.9              indent(indlevel);
248 andyb    1.1.2.9              pw.print("LABEL(" + s.label + ")");
249 cananian 1.1.2.39             cb.printAfter(pw, s);
250 andyb    1.1.2.9          }
251 andyb    1.1.2.9  
252 andyb    1.1.2.9          public void visit(MEM e) {
253 andyb    1.1.2.9              indent(indlevel++);
254 cananian 1.1.2.25             pw.print("MEM<" + Type.toString(e) + ">(");
255 duncan   1.1.2.31             e.getExp().accept(this);
256 andyb    1.1.2.9              pw.print(")");
257 cananian 1.1.2.39             cb.printAfter(pw, e);
258 andyb    1.1.2.9              indlevel--;
259 andyb    1.1.2.9          }
260 duncan   1.1.2.17 
261 duncan   1.1.2.17         public void visit(METHOD s) { 
262 duncan   1.1.2.17             indent(indlevel++);
263 duncan   1.1.2.17             pw.print("METHOD(");
264 cananian 1.1.2.34             TEMP[] params = s.getParams();
265 cananian 1.1.2.34             for (int i=0; i<params.length; i++)
266 cananian 1.1.2.34                 params[i].accept(this);
267 duncan   1.1.2.17             pw.print(")");
268 cananian 1.1.2.39             cb.printAfter(pw, s);
269 duncan   1.1.2.17             indlevel--;
270 duncan   1.1.2.17         }
271 andyb    1.1.2.9  
272 andyb    1.1.2.9          public void visit(MOVE s) {
273 andyb    1.1.2.9              indent(indlevel++);
274 andyb    1.1.2.9              pw.print("MOVE(");
275 duncan   1.1.2.31             s.getDst().accept(this);
276 andyb    1.1.2.9              pw.print(",");
277 duncan   1.1.2.31             s.getSrc().accept(this);
278 andyb    1.1.2.9              pw.print(")");
279 cananian 1.1.2.39             cb.printAfter(pw, s);
280 andyb    1.1.2.9              indlevel--;
281 andyb    1.1.2.9          }
282 andyb    1.1.2.9  
283 andyb    1.1.2.9          public void visit(NAME e) {
284 andyb    1.1.2.9              indent(indlevel);
285 andyb    1.1.2.9              pw.print("NAME(" + e.label + ")");
286 cananian 1.1.2.39             cb.printAfter(pw, e);
287 andyb    1.1.2.9          }
288 andyb    1.1.2.9  
289 andyb    1.1.2.9          public void visit(NATIVECALL s) {
290 duncan   1.1.2.31             ExpList list = s.getArgs();
291 duncan   1.1.2.15             indent(indlevel++);
292 duncan   1.1.2.15             pw.print("NATIVECALL" + "(");
293 duncan   1.1.2.15             indent(indlevel++);
294 duncan   1.1.2.31             if (s.getRetval()!=null) {
295 cananian 1.1.2.30                 pw.print("return value:");
296 duncan   1.1.2.31                 s.getRetval().accept(this);
297 cananian 1.1.2.30                 pw.print(",");
298 cananian 1.1.2.30                 indent(--indlevel); indlevel++;
299 cananian 1.1.2.30             }
300 duncan   1.1.2.15             pw.print("function:");
301 duncan   1.1.2.31             s.getFunc().accept(this);
302 duncan   1.1.2.15             pw.print(",");
303 duncan   1.1.2.15             indent(--indlevel); indlevel++;
304 duncan   1.1.2.15             pw.print("arguments:");
305 duncan   1.1.2.15             while (list != null) {
306 cananian 1.1.2.27                 list.head.accept(this);
307 duncan   1.1.2.15                 if (list.tail != null) {
308 duncan   1.1.2.15                     pw.print(",");
309 duncan   1.1.2.15                 }
310 duncan   1.1.2.15                 list = list.tail;
311 duncan   1.1.2.15             }
312 duncan   1.1.2.15             pw.print(")");
313 cananian 1.1.2.39             cb.printAfter(pw, s);
314 duncan   1.1.2.15             indlevel -= 2;
315 andyb    1.1.2.9          }
316 andyb    1.1.2.9  
317 andyb    1.1.2.9          public void visit(RETURN s) {
318 andyb    1.1.2.9              indent(indlevel++);
319 andyb    1.1.2.9              pw.print("RETURN(");
320 duncan   1.1.2.31             s.getRetval().accept(this);
321 andyb    1.1.2.9              pw.print(")");
322 cananian 1.1.2.39             cb.printAfter(pw, s);
323 andyb    1.1.2.9              indlevel--;
324 andyb    1.1.2.9          }
325 duncan   1.1.2.12 
326 duncan   1.1.2.12         public void visit(SEGMENT s) { 
327 cananian 1.1.2.36             indent(indlevel);
328 duncan   1.1.2.12             pw.print(s.toString());
329 cananian 1.1.2.39             cb.printAfter(pw, s);
330 duncan   1.1.2.12         }
331 andyb    1.1.2.9  
332 andyb    1.1.2.9          public void visit(SEQ s) {
333 cananian 1.1.2.35             indent(indlevel++);
334 andyb    1.1.2.9              pw.print("SEQ(");
335 duncan   1.1.2.31             s.getLeft().accept(this);
336 andyb    1.1.2.9              pw.print(",");
337 duncan   1.1.2.31             s.getRight().accept(this);
338 andyb    1.1.2.9              pw.print(")");
339 cananian 1.1.2.39             cb.printAfter(pw, s);
340 cananian 1.1.2.36             indlevel--;
341 andyb    1.1.2.9          }
342 andyb    1.1.2.9  
343 andyb    1.1.2.9          public void visit(TEMP e) {
344 andyb    1.1.2.9              Temp t = (tm == null) ? e.temp : tm.tempMap(e.temp);
345 andyb    1.1.2.9              indent(indlevel);
346 andyb    1.1.2.9              pw.print("TEMP<" + Type.toString(e.type) + ">(" + t + ")");
347 cananian 1.1.2.39             cb.printAfter(pw, e);
348 andyb    1.1.2.9          }
349 andyb    1.1.2.9  
350 andyb    1.1.2.9          public void visit(THROW s) {
351 andyb    1.1.2.9              indent(indlevel++);
352 andyb    1.1.2.9              pw.print("THROW(");
353 duncan   1.1.2.31             s.getRetex().accept(this);
354 duncan   1.1.2.18             pw.print(",");
355 duncan   1.1.2.31             s.getHandler().accept(this);
356 andyb    1.1.2.9              pw.print(")");
357 cananian 1.1.2.39             cb.printAfter(pw, s);
358 andyb    1.1.2.9              indlevel--;
359 andyb    1.1.2.9          }
360 andyb    1.1.2.9  
361 andyb    1.1.2.9          public void visit(UNOP e) {
362 andyb    1.1.2.9              indent(indlevel++);
363 andyb    1.1.2.9              pw.print("UNOP<" + Type.toString(e.optype) + ">(");
364 andyb    1.1.2.9              pw.print(Uop.toString(e.op) + ",");
365 duncan   1.1.2.31             e.getOperand().accept(this);
366 andyb    1.1.2.9              pw.print(")");
367 cananian 1.1.2.39             cb.printAfter(pw, e);
368 andyb    1.1.2.9              indlevel--;
369 andyb    1.1.2.9          }
370 andyb    1.1.2.9      } 
371 cananian 1.2      }