home *** CD-ROM | disk | FTP | other *** search
/ ftp.ee.pdx.edu / 2014.02.ftp.ee.pdx.edu.tar / ftp.ee.pdx.edu / pub / users / Harry / compilers / p4 / PrintAst.java < prev    next >
Text File  |  2005-10-25  |  35KB  |  1,005 lines

  1. // --------------------------- PrintAst ------------------------------
  2. //
  3. // Code to Print the Abstract Syntax Tree - Project 4 Version
  4. //
  5. // Harry Porter -- 10/22/05
  6. //
  7. // This class contains a method to print an Abstract Syntax Tree (AST) in
  8. // all is gory detail.  This is useful for debugging, to make sure the AST
  9. // is being built properly.
  10. //
  11. // The primary method here is called "printAst" and it can be invoked as follows
  12. //       Ast.Node ast = ...;
  13. //       ...
  14. //       PrintAst.printAst (ast);
  15. //
  16. // All methods in this class are static; no instances are created.
  17. //
  18. // Each node in the AST is printed on several lines.  For example, a BinaryOp
  19. // node might be printed like this:
  20. //
  21. //       ---------- BinaryOp ----------
  22. //         lineNumber=2
  23. //         op=PLUS
  24. //         expr1=
  25. //           ... left subtree ...
  26. //         expr2=
  27. //           ... right subtree ...
  28. //       ------------------------------
  29. //
  30. // Note that each field of the object is printed.  When some field points to
  31. // another node in the AST, that node will be printed, with proper indentation,
  32. // to show the branching structure of the tree.  Here is the same example,
  33. // showing a little more of the two child nodes of the BinaryOp node.
  34. //
  35. //       ---------- BinaryOp ----------
  36. //         lineNumber=2
  37. //         op=PLUS
  38. //         expr1=
  39. //           ---------- UnaryOp ----------
  40. //             lineNumber=2
  41. //             ... other fields in this node ...
  42. //           ------------------------------
  43. //         expr2=
  44. //           ---------- IntegerConst ----------
  45. //             lineNumber=2
  46. //             ... other fields in this node ...
  47. //           ------------------------------
  48. //       ------------------------------
  49. //
  50. // In a tree, every node (except the root) is pointed to by exactly one other
  51. // node (its parent).  However, a given AST may not be a "proper" tree.  For example,
  52. // some node may be pointed to by several other nodes.  The methods here are designed
  53. // to print such an AST in a way that will make clear the actual shape of the AST.
  54. // In particular, a shared node (one with multiple parents) will be printed only once,
  55. // to avoid confusion.
  56. //
  57. // During printing, each node is assigned a number, which is prefixed with a # sign.
  58. // This number serves to identify the node in case it is pointed to by more than
  59. // one other node.
  60. //
  61. // Here is a fragment, showing how trees with shared nodes are printed.
  62. //
  63. //    #2:       ---------- VarDecl ----------
  64. //                lineNumber=2
  65. //                id="x"
  66. //                typeName=
  67. //    #3:           ---------- TypeName ----------
  68. //                    lineNumber=2
  69. //                    id="integer"
  70. //                  ------------------------------
  71. //                expr=
  72. //                  ...
  73. //              ------------------------------
  74. //    #5:       ---------- VarDecl ----------
  75. //                lineNumber=2
  76. //                id="y"
  77. //                typeName=
  78. //                  *****  This node was printed earlier (#3: TypeName) *****
  79. //                expr=
  80. //                  ...
  81. //              ------------------------------
  82. //
  83. // This technique allows graphs (not just trees or DAGs) to be printed out without
  84. // infinite looping.
  85. //
  86. // The methods here are written in such a way as to be as "bullet-proof" as possible.
  87. // No matter how badly mangled your AST might be, I believe that these methods will
  88. // succeed in printing something reasonable.  As a consequence, the way I have coded
  89. // these methods is not altogether clear and simple.  If, during the course of your
  90. // debugging, problems arise while printing your AST (for example, one of the methods
  91. // here crashes or loops), please let me know.
  92. //
  93. // The printing of some fields may be commented out; These fields are not needed until
  94. // a later project and can be ignored safely.
  95. //
  96. // Complex, higly nested expressions generate lots of output and even with the
  97. // indenting to help, it is difficult to check that the expression is being parsed
  98. // correctly and, if not, exactly what is occurring.  To help understand
  99. // expression trees, the printing of return statements has been augmented to print
  100. // the return expression with full parentheses.  For example, the program
  101. //
  102. //    program is
  103. //      begin
  104. //        return 1 * 2 + 3 and 4 / 5 - 6 < 7 * 8;
  105. //      end;
  106. //
  107. // produces this output:
  108. //
  109. //    #1:   ---------- Body ----------
  110. //            lineNumber=2
  111. //            typeDecls=NULL
  112. //            procDecls=NULL
  113. //            varDecls=NULL
  114. //            stmts=
  115. //    #2:       ---------- ReturnStmt ----------
  116. //                lineNumber=3
  117. //                summary= ((((1 * 2) + ((3 AND 4) / 5)) - 6) < (7 * 8))
  118. //                expr=
  119. //                  ... about 74 lines omitted here ...
  120. //              ------------------------------
  121. //          ------------------------------
  122. //
  123. // The field named "summary" is not really a field in the ReturnStmt object, but
  124. // is just used to print the summary of the return expression with parentheses.
  125. //
  126. // While you are free to study the code here, it is not necessary that you understand
  127. // how it works it in order to complete the class projects.
  128. //
  129.  
  130.  
  131.  
  132. import java.io.*;
  133. import java.util.*;
  134.  
  135.  
  136. class PrintAst {
  137.  
  138.  
  139.     //
  140.     // Constants
  141.     //
  142.     final static int TABAMT = 2;    // The number of spaces by which to indent
  143.  
  144.  
  145.     //
  146.     // Static Variables
  147.     //
  148.     // "ptrMap" is a mapping from ptrs to integers, used to give each object a
  149.     // unique number.  See the "printPtr" method for more details.
  150.     //
  151.     static private Map ptrMap = new HashMap ();
  152.     static int nextLabel = 1;                      // Next number to use
  153.     //
  154.     // "alreadyPrinted" is a mapping used to see if we have already
  155.     // printed a node before.
  156.     //
  157.     static private Map alreadyPrinted = new HashMap ();
  158.     //
  159.     // "alreadyPrinted2" is a mapping used to see if we have already
  160.     // printed a node before in printExpr ()...
  161.     //
  162.     static private Map alreadyPrinted2 = new HashMap ();
  163.  
  164.  
  165.  
  166.     //
  167.     // printAst (ptrToNode)
  168.     //
  169.     // This method prints the abstract syntax tree pointed to by "ptrToNode".
  170.     //
  171.     static void printAst (Ast.Node ptrToNode) {
  172.         printAst (6, ptrToNode);
  173.     }
  174.  
  175.  
  176.  
  177.     //
  178.     // printAst (indent, ptrToNode)
  179.     //
  180.     // This method prints the node pointed to by "ptrToNode".  This is
  181.     // a recursive method that calls itself to print the children of
  182.     // this node.
  183.     //
  184.     // The tree is printed with "indent" characters of indentation.
  185.     // Initially, it should be called with an "indent" of about 6 (to
  186.     // allow enough space to print the #999: labels.)  The indentation is
  187.     // increased for the children.
  188.     //
  189.     static void printAst (int indent, Ast.Node ptrToNode) {
  190.  
  191.         // If we have are passed a null pointer, print "NULL"...
  192.         if (ptrToNode == null) {
  193.             printLine (indent, "NULL");
  194.             return;
  195.         }
  196.  
  197.         // Check to see if we have printed out this node before.
  198.         // If so, print a message...
  199.         if (alreadyPrinted.get (ptrToNode) != null) {
  200.           printIndent (indent);
  201.           System.out.print ("*****  This node was printed earlier (");
  202.           printPtr (ptrToNode);
  203.           System.out.print (": ");
  204.           System.out.print (ptrToNode.getClass ().getName ().substring (4));
  205.           System.out.println (") *****");
  206.           return;
  207.         } else {
  208.           alreadyPrinted.put (ptrToNode, ptrToNode);   // Value doesn't matter as
  209.                                                        // long as it is not null.
  210.         }
  211.  
  212.         // Look at the class of this node and print it accordingly...
  213.         if (ptrToNode instanceof Ast.Body) {
  214.             Ast.Body p = (Ast.Body) ptrToNode;
  215.             printHeader (indent, p);
  216.             printItem (indent, "typeDecls=", p.typeDecls);
  217.             printItem (indent, "procDecls=", p.procDecls);
  218.             printItem (indent, "varDecls=",  p.varDecls);
  219.             printItem (indent, "stmts=",     p.stmts);
  220. //          printFieldName (indent, "frameSize=");
  221. //          System.out.println (p.frameSize);
  222.             printFooter (indent);
  223.  
  224.         } else if (ptrToNode instanceof Ast.VarDecl) {
  225.             Ast.VarDecl p = (Ast.VarDecl) ptrToNode;
  226.             printHeader (indent, p);
  227.             printId (indent, p.id);
  228.             printItem (indent, "typeName=", p.typeName);
  229.             printItem (indent, "expr=", p.expr);
  230. //          printFieldName (indent, "lexLevel=");
  231. //          System.out.println (p.lexLevel);
  232. //          printFieldName (indent, "offset=");
  233. //          System.out.println (p.offset);
  234.             printFooter (indent);
  235.             if (p.next != null) {
  236.                 printAst (indent, p.next);
  237.             }
  238.  
  239.         } else if (ptrToNode instanceof Ast.TypeDecl) {
  240.             Ast.TypeDecl p = (Ast.TypeDecl) ptrToNode;
  241.             printHeader (indent, p);
  242.             printId (indent, p.id);
  243.             printItem (indent, "compoundType=", p.compoundType);
  244.             printFooter (indent);
  245.             if (p.next != null) {
  246.                 printAst (indent, p.next);
  247.             }
  248.  
  249.         } else if (ptrToNode instanceof Ast.TypeName) { 
  250.             Ast.TypeName p = (Ast.TypeName) ptrToNode;
  251.             printHeader (indent, p);
  252.             printId (indent, p.id);
  253. //          printItem (indent, "myDef=", p.myDef);
  254.             printFooter (indent);
  255.  
  256.         } else if (ptrToNode instanceof Ast.ProcDecl) {
  257.             Ast.ProcDecl p = (Ast.ProcDecl) ptrToNode;
  258.             printHeader (indent, p);
  259.             printId (indent, p.id);
  260. //          printFieldName (indent, "lexLevel=");
  261. //          System.out.println (p.lexLevel);
  262.             printItem (indent, "formals=", p.formals);
  263.             printItem (indent, "retType=", p.retType);
  264.             printItem (indent, "body=", p.body);
  265.             printFooter (indent);
  266.             if (p.next != null) {
  267.                 printAst (indent, p.next);
  268.             }
  269.  
  270.         } else if (ptrToNode instanceof Ast.Formal) {
  271.             Ast.Formal p = (Ast.Formal) ptrToNode;
  272.             printHeader (indent, p);
  273.             printId (indent, p.id);
  274.             printItem (indent, "typeName=", p.typeName);
  275. //          printFieldName (indent, "lexLevel=");
  276. //          System.out.println (p.lexLevel);
  277. //          printFieldName (indent, "offset=");
  278. //          System.out.println (p.offset);
  279.             printFooter (indent);
  280.             if (p.next != null) {
  281.                 printAst (indent, p.next);
  282.             }
  283.  
  284.         } else if (ptrToNode instanceof Ast.ArrayType) {
  285.             Ast.ArrayType p = (Ast.ArrayType) ptrToNode;
  286.             printHeader (indent, p);
  287.             printItem (indent, "elementType=", p.elementType);
  288.             printFooter (indent);
  289.  
  290.         } else if (ptrToNode instanceof Ast.RecordType) {
  291.             Ast.RecordType p = (Ast.RecordType) ptrToNode;
  292.             printHeader (indent, p);
  293.             printItem (indent, "fieldDecls=", p.fieldDecls);
  294. //          printFieldName (indent, "size=");
  295. //          System.out.println (p.size);
  296.             printFooter (indent);
  297.  
  298.         } else if (ptrToNode instanceof Ast.FieldDecl) {
  299.             Ast.FieldDecl p = (Ast.FieldDecl) ptrToNode;
  300.             printHeader (indent, p);
  301.             printId (indent, p.id);
  302.             printItem (indent, "typeName=", p.typeName);
  303. //          printFieldName (indent, "offset=");
  304. //          System.out.println (p.offset);
  305.             printFooter (indent);
  306.             if (p.next != null) {
  307.                 printAst (indent, p.next);
  308.             }
  309.  
  310.         } else if (ptrToNode instanceof Ast.AssignStmt) {
  311.             Ast.AssignStmt p = (Ast.AssignStmt) ptrToNode;
  312.             printHeader (indent, p);
  313.             printItem (indent, "lValue=", p.lValue);
  314.             printItem (indent, "expr=", p.expr);
  315.             printFooter (indent);
  316.             if (p.next != null) {
  317.                 printAst (indent, p.next);
  318.             }
  319.  
  320.         } else if (ptrToNode instanceof Ast.CallStmt) {
  321.             Ast.CallStmt p = (Ast.CallStmt) ptrToNode;
  322.             printHeader (indent, p);
  323.             printId (indent, p.id);
  324.             printItem (indent, "args=", p.args);
  325. //          printMyDef (indent, p.myDef);
  326.             printFooter (indent);
  327.             if (p.next != null) {
  328.                 printAst (indent, p.next);
  329.             }
  330.  
  331.         } else if (ptrToNode instanceof Ast.ReadStmt) {
  332.             Ast.ReadStmt p = (Ast.ReadStmt) ptrToNode;
  333.             printHeader (indent, p);
  334.             printItem (indent, "readArgs=", p.readArgs);
  335.             printFooter (indent);
  336.             if (p.next != null) {
  337.                 printAst (indent, p.next);
  338.             }
  339.  
  340.         } else if (ptrToNode instanceof Ast.ReadArg) {
  341.             Ast.ReadArg p = (Ast.ReadArg) ptrToNode;
  342.             printHeader (indent, p);
  343.             printItem (indent, "lValue=", p.lValue);
  344. //          printMode (indent, p.mode);
  345.             printFooter (indent);
  346.             if (p.next != null) {
  347.                 printAst (indent, p.next);
  348.             }
  349.  
  350.         } else if (ptrToNode instanceof Ast.WriteStmt) {
  351.             Ast.WriteStmt p = (Ast.WriteStmt) ptrToNode;
  352.             printHeader (indent, p);
  353.             printItem (indent, "args=", p.args);
  354.             printFooter (indent);
  355.             if (p.next != null) {
  356.                 printAst (indent, p.next);
  357.             }
  358.  
  359.         } else if (ptrToNode instanceof Ast.IfStmt) {
  360.             Ast.IfStmt p = (Ast.IfStmt) ptrToNode;
  361.             printHeader (indent, p);
  362.             printItem (indent, "expr=", p.expr);
  363.             printItem (indent, "thenStmts=", p.thenStmts);
  364.             printItem (indent, "elseStmts=", p.elseStmts);
  365.             printFooter (indent);
  366.             if (p.next != null) {
  367.                 printAst (indent, p.next);
  368.             }
  369.  
  370.         } else if (ptrToNode instanceof Ast.WhileStmt) {
  371.             Ast.WhileStmt p = (Ast.WhileStmt) ptrToNode;
  372.             printHeader (indent, p);
  373.             printItem (indent, "expr=", p.expr);
  374.             printItem (indent, "stmts=", p.stmts);
  375. //          printStringField (indent, "exitLabel=", p.exitLabel);
  376.             printFooter (indent);
  377.             if (p.next != null) {
  378.                 printAst (indent, p.next);
  379.             }
  380.  
  381.         } else if (ptrToNode instanceof Ast.LoopStmt) {
  382.             Ast.LoopStmt p = (Ast.LoopStmt) ptrToNode;
  383.             printHeader (indent, p);
  384.             printItem (indent, "stmts=", p.stmts);
  385. //          printStringField (indent, "exitLabel=", p.exitLabel);
  386.             printFooter (indent);
  387.             if (p.next != null) {
  388.                 printAst (indent, p.next);
  389.             }
  390.  
  391.         } else if (ptrToNode instanceof Ast.ForStmt) {
  392.             Ast.ForStmt p = (Ast.ForStmt) ptrToNode;
  393.             printHeader (indent, p);
  394.             printItem (indent, "lValue=", p.lValue);
  395.             printItem (indent, "expr1=", p.expr1);
  396.             printItem (indent, "expr2=", p.expr2);
  397.             printItem (indent, "expr3=", p.expr3);
  398.             printItem (indent, "stmts=", p.stmts);
  399. //          printStringField (indent, "exitLabel=", p.exitLabel);
  400.             printFooter (indent);
  401.             if (p.next != null) {
  402.                 printAst (indent, p.next);
  403.             }
  404.  
  405.         } else if (ptrToNode instanceof Ast.ExitStmt) {
  406.             Ast.ExitStmt p = (Ast.ExitStmt) ptrToNode;
  407.             printHeader (indent, p);
  408. //          printItem (indent, "myLoop=", p.myLoop);
  409.             printFooter (indent);
  410.             if (p.next != null) {
  411.                 printAst (indent, p.next);
  412.             }
  413.  
  414.         } else if (ptrToNode instanceof Ast.ReturnStmt) {
  415.             Ast.ReturnStmt p = (Ast.ReturnStmt) ptrToNode;
  416.             printHeader (indent, p);
  417.             printFieldName (indent, "summary= ");
  418.             printExpr (p.expr);
  419.             System.out.println ();
  420.             printItem (indent, "expr=", p.expr);
  421. //          printItem (indent, "myProc=", p.myProc);
  422.             printFooter (indent);
  423.             if (p.next != null) {
  424.                 printAst (indent, p.next);
  425.             }
  426.  
  427.         } else if (ptrToNode instanceof Ast.BinaryOp) {
  428.             Ast.BinaryOp p = (Ast.BinaryOp) ptrToNode;
  429.             printHeader (indent, p);
  430.             printOperator (indent, p.op);
  431.             printItem (indent, "expr1=", p.expr1);
  432.             printItem (indent, "expr2=", p.expr2);
  433. //          printMode (indent, p.mode);
  434.             printFooter (indent);
  435.  
  436.         } else if (ptrToNode instanceof Ast.UnaryOp) {
  437.             Ast.UnaryOp p = (Ast.UnaryOp) ptrToNode;
  438.             printHeader (indent, p);
  439.             printOperator (indent, p.op);
  440.             printItem (indent, "expr=", p.expr);
  441. //          printMode (indent, p.mode);
  442.             printFooter (indent);
  443.  
  444.         } else if (ptrToNode instanceof Ast.IntToReal) {
  445.             Ast.IntToReal p = (Ast.IntToReal) ptrToNode;
  446.             printHeader (indent, p);
  447.             printItem (indent, "expr=", p.expr);
  448.             printFooter (indent);
  449.  
  450.         } else if (ptrToNode instanceof Ast.FunctionCall) {
  451.             Ast.FunctionCall p = (Ast.FunctionCall) ptrToNode;
  452.             printHeader (indent, p);
  453.             printId (indent, p.id);
  454.             printItem (indent, "args=", p.args);
  455. //          printMyDef (indent, p.myDef);
  456.             printFooter (indent);
  457.  
  458.         } else if (ptrToNode instanceof Ast.Argument) {
  459.             Ast.Argument p = (Ast.Argument) ptrToNode;
  460.             printHeader (indent, p);
  461.             printItem (indent, "expr=", p.expr);
  462. //          printMode (indent, p.mode);
  463. //          printItem (indent, "location=", p.location);
  464.             printFooter (indent);
  465.             if (p.next != null) {
  466.                 printAst (indent, p.next);
  467.             }
  468.  
  469.         } else if (ptrToNode instanceof Ast.ArrayConstructor) {
  470.             Ast.ArrayConstructor p = (Ast.ArrayConstructor) ptrToNode;
  471.             printHeader (indent, p);
  472.             printId (indent, p.id);
  473.             printItem (indent, "values=", p.values);
  474. //          printMyDef (indent, p.myDef);
  475.             printFooter (indent);
  476.  
  477.         } else if (ptrToNode instanceof Ast.ArrayValue) {
  478.             Ast.ArrayValue p = (Ast.ArrayValue) ptrToNode;
  479.             printHeader (indent, p);
  480.             printItem (indent, "countExpr=", p.countExpr);
  481.             printItem (indent, "valueExpr=", p.valueExpr);
  482. //          printItem (indent, "tempCount=", p.tempCount);
  483. //          printItem (indent, "tempValue=", p.tempValue);
  484.             printFooter (indent);
  485.             if (p.next != null) {
  486.                 printAst (indent, p.next);
  487.             }
  488.  
  489.         } else if (ptrToNode instanceof Ast.RecordConstructor) {
  490.             Ast.RecordConstructor p = (Ast.RecordConstructor) ptrToNode;
  491.             printHeader (indent, p);
  492.             printId (indent, p.id);
  493.             printItem (indent, "fieldInits=", p.fieldInits);
  494. //          printMyDef (indent, p.myDef);
  495.             printFooter (indent);
  496.  
  497.         } else if (ptrToNode instanceof Ast.FieldInit) {
  498.             Ast.FieldInit p = (Ast.FieldInit) ptrToNode;
  499.             printHeader (indent, p);
  500.             printId (indent, p.id);
  501.             printItem (indent, "expr=", p.expr);
  502. //          printItem (indent, "myFieldDecl=", p.myFieldDecl);
  503.             printFooter (indent);
  504.             if (p.next != null) {
  505.                 printAst (indent, p.next);
  506.             }
  507.  
  508.         } else if (ptrToNode instanceof Ast.IntegerConst) {
  509.             Ast.IntegerConst p = (Ast.IntegerConst) ptrToNode;
  510.             printHeader (indent, p);
  511.             printIndent (indent+TABAMT);
  512.             System.out.println ("iValue=" + p.iValue);
  513.             printFooter (indent);
  514.  
  515.         } else if (ptrToNode instanceof Ast.RealConst) {
  516.             Ast.RealConst p = (Ast.RealConst) ptrToNode;
  517.             printHeader (indent, p);
  518.             printIndent (indent+TABAMT);
  519.             System.out.println ("rValue=" + p.rValue);
  520. //          printStringField (indent, "nameOfConstant=", p.nameOfConstant);
  521. //          printItem (indent, "next=", p.next);
  522.             printFooter (indent);
  523.  
  524.         } else if (ptrToNode instanceof Ast.StringConst) {
  525.             Ast.StringConst p = (Ast.StringConst) ptrToNode;
  526.             printHeader (indent, p);
  527.             printStringField (indent, "sValue=", p.sValue);
  528. //          printStringField (indent, "nameOfConstant=", p.nameOfConstant);
  529. //          printItem (indent, "next=", p.next);
  530.             printFooter (indent);
  531.  
  532.         } else if (ptrToNode instanceof Ast.BooleanConst) {
  533.             Ast.BooleanConst p = (Ast.BooleanConst) ptrToNode;
  534.             printHeader (indent, p);
  535.             printFieldName (indent, "iValue=");
  536.             System.out.println (p.iValue);
  537.             printFooter (indent);
  538.  
  539.         } else if (ptrToNode instanceof Ast.NilConst) {
  540.             printHeader (indent, ptrToNode);
  541.             printFooter (indent);
  542.  
  543.         } else if (ptrToNode instanceof Ast.ValueOf) {
  544.             Ast.ValueOf p = (Ast.ValueOf) ptrToNode;
  545.             printHeader (indent, p);
  546.             printItem (indent, "lValue=", p.lValue);
  547.             printFooter (indent);
  548.  
  549.         } else if (ptrToNode instanceof Ast.Variable) {
  550.             Ast.Variable p = (Ast.Variable) ptrToNode;
  551.             printHeader (indent, p);
  552.             printId (indent, p.id);
  553. //          printMyDef (indent, p.myDef);
  554. //          printFieldName (indent, "currentLevel=");
  555. //          System.out.println (p.currentLevel);
  556.             printFooter (indent);
  557.  
  558.         } else if (ptrToNode instanceof Ast.ArrayDeref) {
  559.             Ast.ArrayDeref p = (Ast.ArrayDeref) ptrToNode;
  560.             printHeader (indent, p);
  561.             printItem (indent, "lValue=", p.lValue);
  562.             printItem (indent, "expr=", p.expr);
  563.             printFooter (indent);
  564.  
  565.         } else if (ptrToNode instanceof Ast.RecordDeref) {
  566.             Ast.RecordDeref p = (Ast.RecordDeref) ptrToNode;
  567.             printHeader (indent, p);
  568.             printItem (indent, "lValue=", p.lValue);
  569.             printId (indent, p.id);
  570. //          printItem (indent, "myFieldDecl=", p.myFieldDecl);
  571.             printFooter (indent);
  572.  
  573.         } else {
  574.             printLine (indent, "(********** Class is unknown!!! **********)");
  575.         }
  576.     }
  577.  
  578.  
  579.  
  580.     //
  581.     // printHeader (indent, p)
  582.     //
  583.     // This method indents, then prints the class of object p, then
  584.     // prints p.lineNumber, then finally prints a newline.
  585.     //
  586.     static void printHeader (int indent, Ast.Node p) {
  587.         int i = printPtr (p);
  588.         System.out.print (": ");
  589.         i = indent - i - TABAMT;
  590.         printIndent (i);
  591.         System.out.print ("---------- ");
  592.         System.out.print (p.getClass ().getName ().substring (4));
  593.         System.out.println (" ----------");
  594.         printFieldName (indent, "lineNumber=");
  595.         System.out.println (p.lineNumber);
  596.     }
  597.  
  598.  
  599.  
  600.     //
  601.     // printFooter (indent)
  602.     //
  603.     // This method indents, then the closing bracketting symbol.
  604.     //
  605.     static void printFooter (int indent) {
  606.         printIndent (indent);
  607.         System.out.println ("------------------------------");
  608.     }
  609.  
  610.  
  611.  
  612.     //
  613.     // printIndent (indent)
  614.     //
  615.     // This method prints "indent" spaces.
  616.     //
  617.     static void printIndent (int indent) {
  618.         for (int i = indent; i>0; i--) {
  619.             System.out.print (" ");
  620.         }
  621.     }
  622.  
  623.  
  624.  
  625.     //
  626.     // printLine (indent, str)
  627.     //
  628.     // This method indents, then prints the given string, then prints newline.
  629.     //
  630.     static void printLine (int indent, String str) {
  631.         printIndent (indent);
  632.         System.out.println (str);
  633.     }
  634.  
  635.  
  636.  
  637.     //
  638.     // printStringField (indent, str1, str2)
  639.     //
  640.     // This method indents by "indent" + TABAMT, then prints str1, then prints
  641.     // str2, then prints newline.
  642.     //
  643.     static void printStringField (int indent, String str1, String str2) {
  644.         printIndent (indent + TABAMT);
  645.         if (str2 == null) {
  646.             System.out.print (str1);
  647.             System.out.println ("NULL");
  648.         } else {
  649.             System.out.print (str1);
  650.             System.out.print ("\"");
  651.             System.out.print (str2);
  652.             System.out.println ("\"");
  653.         }
  654.     }
  655.  
  656.  
  657.  
  658.     //
  659.     // printId (indent, id)
  660.     //
  661.     // This method indents by "indent" + TABAMT, then prints "id=", then prints
  662.     // the id argument, then prints newline.
  663.     //
  664.     static void printId (int indent, String id) {
  665.         printStringField (indent, "id=", id);
  666.     }
  667.  
  668.  
  669.  
  670.     //
  671.     // printMyDef (indent, p)
  672.     //
  673.     // This method indents by "indent" + TABAMT, then prints "myDef=", then prints
  674.     // the argument, then prints newline.
  675.     //
  676.     static void printMyDef (int indent, Ast.Node p) {
  677.         printItem (indent, "myDef=", p);
  678.     }
  679.  
  680.  
  681.  
  682.     //
  683.     // printFieldName (indent, str)
  684.     //
  685.     // This method indents by "indent" + TABAMT, then prints the given string.  It
  686.     // prints no newline.
  687.     //
  688.     static void printFieldName (int indent, String str) {
  689.         printIndent (indent + TABAMT);
  690.         System.out.print (str);
  691.     }
  692.  
  693.  
  694.  
  695.     //
  696.     // printItem (indent, s, t)
  697.     //
  698.     // This method prints the given string on one line (indented by TABAMT more
  699.     // than "indent") and then calls printAst() to print the tree "t" (indented by
  700.     // 2*TABAMT more spaces than "indent").
  701.     //
  702.     static void printItem (int indent, String s, Ast.Node t) {
  703.         printIndent (indent + TABAMT);
  704.         System.out.print (s);
  705.         if (t == null) {
  706.             System.out.println ("NULL");
  707.         } else {
  708.             System.out.println ();
  709.             printAst (indent + TABAMT + TABAMT, t);
  710.         }
  711.     }
  712.  
  713.  
  714.  
  715.     //
  716.     // printOperator (indent, op)
  717.     //
  718.     // This method is passed a token type in "op".  It prints it out in the form:
  719.     //       op=PLUS
  720.     ///
  721.     static void printOperator (int in, int op) {
  722.         printIndent (in+TABAMT);
  723.         switch (op) {
  724.             case Token.LEQ:
  725.                 System.out.println ("op=LEQ");
  726.                 return;
  727.             case Token.GEQ:
  728.                 System.out.println ("op=GEQ");
  729.                 return;
  730.             case Token.NEQ:
  731.                 System.out.println ("op=NEQ");
  732.                 return;
  733.             case Token.AND:
  734.                 System.out.println ("op=AND");
  735.                 return;
  736.             case Token.DIV:
  737.                 System.out.println ("op=DIV");
  738.                 return;
  739.             case Token.MOD:
  740.                 System.out.println ("op=MOD");
  741.                 return;
  742.             case Token.NOT:
  743.                 System.out.println ("op=NOT");
  744.                 return;
  745.             case Token.OR:
  746.                 System.out.println ("op=OR");
  747.                 return;
  748.             case Token.LESS:
  749.                 System.out.println ("op=LESS");
  750.                 return;
  751.             case Token.GREATER:
  752.                 System.out.println ("op=GREATER");
  753.                 return;
  754.             case Token.EQUAL:
  755.                 System.out.println ("op=EQUAL");
  756.                 return;
  757.             case Token.PLUS:
  758.                 System.out.println ("op=PLUS");
  759.                 return;
  760.             case Token.MINUS:
  761.                 System.out.println ("op=MINUS");
  762.                 return;
  763.             case Token.STAR:
  764.                 System.out.println ("op=STAR");
  765.                 return;
  766.             case Token.SLASH:
  767.                 System.out.println ("op=SLASH");
  768.                 return;
  769.             default:
  770.                 System.out.println ("op=***** ERROR: op IS GARBAGE *****");
  771.         }
  772.     }
  773.  
  774.  
  775.  
  776.     //
  777.     // printPtr (p)
  778.     //
  779.     // This method is passed a pointer, possibly NULL.  It prints the pointer.
  780.     // The actual address is not printed, since these may vary from run to run.
  781.     // Instead, this method assigns 'labels' to each address and prints the
  782.     // same label each time.  It saves the mapping between label and address
  783.     // in a static hashMap called "ptrMap".
  784.     //
  785.     // This method returns the number of characters printed.
  786.     //
  787.     static int printPtr (Ast.Node p) {
  788.         int i;
  789.  
  790.         // If the pointer is null, then print "NULL"...
  791.         if (p == null) {
  792.             System.out.print ("NULL");
  793.             return 4;
  794.         }
  795.  
  796.         // Figure out what integer goes with this ptr...
  797.         Integer val = (Integer) ptrMap.get (p);
  798.         if (val != null) {
  799.           i = val.intValue ();
  800.         } else {
  801.           i = nextLabel++;
  802.           ptrMap.put (p, new Integer (i));
  803.         }
  804.  
  805.         // Print the number...
  806.         String str = "#" + i;
  807.         System.out.print (str);
  808.  
  809.         // Return the number of characters just printed...
  810.         return str.length ();
  811.     }
  812.  
  813.  
  814.  
  815.     //
  816.     // printExpr (p)
  817.     //
  818.     // This method is passed a pointer, possibly NULL, which should point to
  819.     // an expression or an LValue.  It prints it out in a way that is intended
  820.     // to be more human-readable.  It is used for the "summary=" printout.
  821.     //
  822.     // This method method assumes that it is passed a tree-shaped data
  823.     // structure.  If not, it will print a warning.
  824.     //
  825.     static void printExpr (Ast.Node p) {
  826.  
  827.         // Deal with and print a NULL...
  828.         if (p == null) {
  829.             System.out.print ("NULL");
  830.             return;
  831.         }
  832.  
  833.         // Check to see if we have printed this node before.
  834.         // If so, this is not a tree, so print a message...
  835.         if (alreadyPrinted2.get (p) != null) {
  836.           System.out.print ("*****  Node Sharing detected!  *****");
  837.           return;
  838.         } else {
  839.           alreadyPrinted2.put (p, p);   // Value doesn't matter as
  840.                                         // long as it is not null.
  841.         }
  842.         if (p instanceof Ast.BinaryOp) {
  843.             Ast.BinaryOp p2 = (Ast.BinaryOp) p;
  844.             System.out.print ("(");
  845.             printExpr (p2.expr1);
  846.             System.out.print (" ");
  847.             System.out.print (Token.stringOf [p2.op]);
  848.             System.out.print (" ");
  849.             printExpr (p2.expr2);
  850.             System.out.print (")");
  851.  
  852.         } else if (p instanceof Ast.UnaryOp) {
  853.             Ast.UnaryOp p2 = (Ast.UnaryOp) p;
  854.             System.out.print ("(");
  855.             System.out.print (Token.stringOf [p2.op]);
  856.             System.out.print (" ");
  857.             printExpr (p2.expr);
  858.             System.out.print (")");
  859.  
  860.         } else if (p instanceof Ast.IntToReal) {
  861.             Ast.IntToReal p2 = (Ast.IntToReal) p;
  862.             System.out.print ("intToReal (");
  863.             printExpr (p2.expr);
  864.             System.out.print (")");
  865.  
  866.         } else if (p instanceof Ast.FunctionCall) {
  867.             Ast.FunctionCall p2 = (Ast.FunctionCall) p;
  868.             System.out.print (p2.id);
  869.             System.out.print ("(");
  870.             for (Ast.Argument arg = p2.args; arg != null; arg = arg.next) {
  871.               printExpr (arg.expr);
  872.               if (arg.next != null) {
  873.                 System.out.print (",");
  874.               }
  875.             }
  876.             System.out.print (")");
  877.  
  878.         } else if (p instanceof Ast.ArrayConstructor) {
  879.             Ast.ArrayConstructor p2 = (Ast.ArrayConstructor) p;
  880.             System.out.print (p2.id);
  881.             System.out.print ("{{");
  882.             for (Ast.ArrayValue arrayValue = p2.values;
  883.                  arrayValue != null;
  884.                  arrayValue = arrayValue.next) {
  885.               if (arrayValue.countExpr != null) {
  886.                 printExpr (arrayValue.countExpr);
  887.                 System.out.print (" of ");
  888.               }
  889.               printExpr (arrayValue.valueExpr);
  890.               if (arrayValue.next != null) {
  891.                 System.out.print (", ");
  892.               }
  893.             }
  894.             System.out.print ("}}");
  895.  
  896.         } else if (p instanceof Ast.RecordConstructor) {
  897.             Ast.RecordConstructor p2 = (Ast.RecordConstructor) p;
  898.             System.out.print (p2.id);
  899.             System.out.print ("{");
  900.             for (Ast.FieldInit fieldInit = p2.fieldInits;
  901.                  fieldInit != null;
  902.                  fieldInit = fieldInit.next) {
  903.               System.out.print (fieldInit.id);
  904.               System.out.print (" := ");
  905.               printExpr (fieldInit.expr);
  906.               if (fieldInit.next != null) {
  907.                 System.out.print ("; ");
  908.               }
  909.             }
  910.             System.out.print ("}");
  911.  
  912.         } else if (p instanceof Ast.IntegerConst) {
  913.             Ast.IntegerConst p2 = (Ast.IntegerConst) p;
  914.             System.out.print (p2.iValue);
  915.  
  916.         } else if (p instanceof Ast.RealConst) {
  917.             Ast.RealConst p2 = (Ast.RealConst) p;
  918.             System.out.print (p2.rValue);
  919.  
  920.         } else if (p instanceof Ast.StringConst) {
  921.             Ast.StringConst p2 = (Ast.StringConst) p;
  922.             System.out.print ("\"");
  923.             System.out.print (p2.sValue);
  924.             System.out.print ("\"");
  925.  
  926.         } else if (p instanceof Ast.BooleanConst) {
  927.             Ast.BooleanConst p2 = (Ast.BooleanConst) p;
  928.             if (p2.iValue == 0) {
  929.               System.out.print ("FALSE");
  930.             } else {
  931.               System.out.print ("TRUE");
  932.             }
  933.  
  934.         } else if (p instanceof Ast.NilConst) {
  935.             System.out.print ("NIL");
  936.  
  937.         } else if (p instanceof Ast.ValueOf) {
  938.             Ast.ValueOf p2 = (Ast.ValueOf) p;
  939.             System.out.print ("valueof(");
  940.             printExpr (p2.lValue);
  941.             System.out.print (")");
  942.  
  943.         } else if (p instanceof Ast.Variable) {
  944.             Ast.Variable p2 = (Ast.Variable) p;
  945.             System.out.print (p2.id);
  946.  
  947.         } else if (p instanceof Ast.ArrayDeref) {
  948.             Ast.ArrayDeref p2 = (Ast.ArrayDeref) p;
  949.             System.out.print ("(");
  950.             printExpr (p2.lValue);
  951.             System.out.print ("[");
  952.             printExpr (p2.expr);
  953.             System.out.print ("])");
  954.  
  955.         } else if (p instanceof Ast.RecordDeref) {
  956.             Ast.RecordDeref p2 = (Ast.RecordDeref) p;
  957.             System.out.print ("(");
  958.             printExpr (p2.lValue);
  959.             System.out.print (".");
  960.             System.out.print (p2.id);
  961.             System.out.print (")");
  962.  
  963.         } else {
  964.             System.out.print ("********** ??? **********");
  965.         }
  966.  
  967.     }
  968.  
  969.  
  970.  
  971.     // printMode (indent, m)
  972.     //
  973.     // Print something like "mode=INTEGER_MODE" to indicate the value of argument m.
  974.     //
  975.     static void printMode (int indent, int m) {
  976.         final int INTEGER_MODE = 1;
  977.         final int REAL_MODE = 2;
  978.         final int STRING_MODE = 3;
  979.         final int BOOLEAN_MODE = 4;
  980.         printFieldName (indent, "mode=");
  981.         switch (m) {
  982.             case INTEGER_MODE:
  983.                 System.out.print ("INTEGER_MODE");
  984.                 break;
  985.             case REAL_MODE:
  986.                 System.out.print ("REAL_MODE");
  987.                 break;
  988.             case BOOLEAN_MODE:
  989.                 System.out.print ("BOOLEAN_MODE");
  990.                 break;
  991.             case STRING_MODE:
  992.                 System.out.print ("STRING_MODE");
  993.                 break;
  994.             case 0:
  995.                 System.out.print ("0");
  996.                 break;
  997.             default:
  998.                 System.out.print ("***** Mode is garbage! *****");
  999.                 break;
  1000.         }
  1001.         System.out.println ();
  1002.     }
  1003.  
  1004. }
  1005.