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:
|