00001: package clogs.ast; 00002: 00003: import java.io.PrintWriter; 00004: import java.io.StringWriter; 00005: import java.util.Iterator; 00006: 00007: import clogs.util.List; 00008: import clogs.util.Optional; 00009: 00010: 00011: public class PrettyPrinter 00012: { 00013: private final StringWriter sw = new StringWriter (); 00014: private final PrintWriter pw = new PrintWriter (sw); 00015: private int indentation = 0; 00016: private boolean breakline = false; 00017: 00018: 00019: public String toString () 00020: { 00021: return sw.toString (); 00022: } 00023: 00024: 00025: private void indent () 00026: { 00027: indentation += 2; 00028: breakline = true; 00029: } 00030: 00031: 00032: private void outdent () 00033: { 00034: indentation -= 2; 00035: breakline = true; 00036: } 00037: 00038: 00039: private void newline () 00040: { 00041: breakline = true; 00042: } 00043: 00044: 00045: public void print (Object obj) { 00046: if (breakline) { 00047: pw.println (""); 00048: for (int i = 0; i < indentation; i++) { 00049: pw.print (" "); 00050: } 00051: breakline = false; 00052: } 00053: pw.print (obj); 00054: } 00055: 00056: 00057: public void printEmptyLine () { 00058: print (""); 00059: newline (); 00060: } 00061: 00062: 00063: public void printExtDecls (List<ExtDecl> edecls) 00064: { 00065: for (ExtDecl edecl : edecls) { 00066: printExtDecl (edecl); 00067: printEmptyLine (); 00068: } 00069: } 00070: 00071: 00072: public void printExtDecl (ExtDecl edecl) 00073: { 00074: if (edecl instanceof Decl) { 00075: Decl decl = (Decl) edecl; 00076: printDecl (decl); 00077: print (";"); 00078: newline (); 00079: 00080: } else if (edecl instanceof FunDef) { 00081: FunDef fundef = (FunDef) edecl; 00082: printFunDef (fundef); 00083: 00084: } else { 00085: throw new RuntimeException ("Missing ExtDecl case: " + edecl.getClass ().getName ()); 00086: } 00087: } 00088: 00089: 00090: public void printType (Type type) 00091: { 00092: if (type instanceof TypeArray) { 00093: TypeArray typeA = (TypeArray) type; 00094: printType (typeA.type); 00095: print ("[]"); 00096: 00097: } else if (type instanceof TypeInt) { 00098: print ("int"); 00099: 00100: } else if (type instanceof TypeVoid) { 00101: print ("void"); 00102: } else { 00103: throw new RuntimeException ("Missing Type case: " + type.getClass ().getName ()); 00104: } 00105: } 00106: 00107: 00108: public void printParams (List<Decl> decls) 00109: { 00110: boolean first = true; 00111: for (Decl decl : decls) { 00112: if (!first) { 00113: print (", "); 00114: } 00115: first = false; 00116: printDecl (decl); 00117: } 00118: } 00119: 00120: 00121: public void printDecls (List<Decl> decls) 00122: { 00123: for (Decl decl : decls) { 00124: printDecl (decl); 00125: print (";"); 00126: newline (); 00127: } 00128: } 00129: 00130: 00131: public void printDecl (Decl decl) 00132: { 00133: printType (decl.type); 00134: print (" "); 00135: print (decl.name); 00136: if (!decl.eo.isEmpty ()) { 00137: print (" = "); 00138: printExp (decl.eo.get ()); 00139: } 00140: } 00141: 00142: 00143: public void printFunDef (FunDef fundef) 00144: { 00145: printType (fundef.type); 00146: print (" "); 00147: print (fundef.name); 00148: print (" ("); 00149: printParams (fundef.params); 00150: print (")"); 00151: newline (); 00152: printStat (fundef.body); 00153: newline (); 00154: } 00155: 00156: 00157: public void printBlock (List<Stat> stats) 00158: { 00159: for (Stat stat : stats) { 00160: printStat (stat); 00161: } 00162: } 00163: 00164: 00165: public void printStat (Stat stat) 00166: { 00167: for (String label : stat.labels) { 00168: print (label); 00169: print (":"); 00170: newline (); 00171: } 00172: 00173: if (stat instanceof StatCompound) { 00174: StatCompound statC = (StatCompound) stat; 00175: print ("{"); 00176: indent (); 00177: newline (); 00178: printDecls (statC.decls); 00179: printBlock (statC.stats); 00180: outdent (); 00181: print ("}"); 00182: 00183: } else if (stat instanceof StatExp) { 00184: StatExp statE = (StatExp) stat; 00185: printExp (statE.exp); 00186: print (";"); 00187: 00188: } else if (stat instanceof StatGoto) { 00189: StatGoto statG = (StatGoto) stat; 00190: print ("goto "); 00191: print (statG.target); 00192: print (";"); 00193: 00194: } else if (stat instanceof StatIf) { 00195: StatIf statI = (StatIf) stat; 00196: print ("if ("); 00197: printExp (statI.exp); 00198: print (")"); 00199: indent (); 00200: newline (); 00201: printStat (statI.statT); 00202: outdent (); 00203: newline (); 00204: print ("else"); 00205: indent (); 00206: newline (); 00207: printStat (statI.statF); 00208: outdent (); 00209: 00210: } else if (stat instanceof StatReturn) { 00211: StatReturn statR = (StatReturn) stat; 00212: print ("return"); 00213: if (!statR.oe.isEmpty ()) { 00214: print (" "); 00215: printExp (statR.oe.get ()); 00216: } 00217: print (";"); 00218: 00219: } else if (stat instanceof StatSkip) { 00220: print ("skip;"); 00221: 00222: } else if (stat instanceof StatWhile) { 00223: StatWhile statW = (StatWhile) stat; 00224: print ("while ("); 00225: printExp (statW.exp); 00226: print (")"); 00227: indent (); 00228: newline (); 00229: printStat (statW.stat); 00230: outdent (); 00231: 00232: } else { 00233: throw new RuntimeException ("Missing Stat case: " + stat.getClass ().getName ()); 00234: } 00235: 00236: newline (); 00237: } 00238: 00239: 00240: public void printExp (Exp exp) 00241: { 00242: if (!exp.to.isEmpty ()) { 00243: print ("("); 00244: } 00245: if (exp instanceof ExpArrayAccess) { 00246: ExpArrayAccess expA = (ExpArrayAccess) exp; 00247: printExp (expA.array); 00248: print ("["); 00249: printExp (expA.index); 00250: print ("]"); 00251: 00252: } else if (exp instanceof ExpAssign) { 00253: ExpAssign expA = (ExpAssign) exp; 00254: print ("("); 00255: printExp (expA.left); 00256: print (" = "); 00257: printExp (expA.right); 00258: print (")"); 00259: 00260: } else if (exp instanceof ExpBinOp) { 00261: ExpBinOp expB = (ExpBinOp) exp; 00262: print ("("); 00263: printExp (expB.left); 00264: print (" "); 00265: print (expB.op); 00266: print (" "); 00267: printExp (expB.right); 00268: print (")"); 00269: 00270: } else if (exp instanceof ExpComma) { 00271: ExpComma expC = (ExpComma) exp; 00272: print ("("); 00273: printExp (expC.left); 00274: print (", "); 00275: printExp (expC.right); 00276: print (")"); 00277: 00278: } else if (exp instanceof ExpFunCall) { 00279: ExpFunCall expF = (ExpFunCall) exp; 00280: print ("("); 00281: print (expF.name); 00282: print (" ("); 00283: boolean first = true; 00284: for (Exp arg : expF.args) { 00285: if (!first) { 00286: print (", "); 00287: } 00288: first = false; 00289: printExp (arg); 00290: } 00291: print (")"); 00292: print (")"); 00293: 00294: } else if (exp instanceof ExpInt) { 00295: ExpInt expI = (ExpInt) exp; 00296: print (Integer.toString (expI.value)); 00297: 00298: } else if (exp instanceof ExpNew) { 00299: ExpNew expN = (ExpNew) exp; 00300: print ("(new "); 00301: print (expN.contentType); 00302: print ("["); 00303: print (expN.size); 00304: print ("]"); 00305: print (")"); 00306: 00307: } else if (exp instanceof ExpString) { 00308: ExpString expS = (ExpString) exp; 00309: print ("\"" + expS.value + "\""); 00310: 00311: } else if (exp instanceof ExpUnOp) { 00312: ExpUnOp expU = (ExpUnOp) exp; 00313: print ("("); 00314: print (expU.op); 00315: print (" "); 00316: printExp (expU.exp); 00317: print (")"); 00318: 00319: } else if (exp instanceof ExpVar) { 00320: ExpVar expV = (ExpVar) exp; 00321: print (expV.name); 00322: 00323: } else { 00324: throw new RuntimeException ("Missing Exp case: " + exp.getClass ().getName ()); 00325: } 00326: 00327: if (!exp.to.isEmpty ()) { 00328: print (" :: "); 00329: printType (exp.to.get ()); 00330: print (")"); 00331: } 00332: 00333: } 00334: } 00335: