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 }