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 / p6 / PrintAst.java < prev    next >
Text File  |  2005-11-18  |  37KB  |  1,066 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.     final static int PROJECT = 6;   // Change to use with different projects
  144.  
  145.  
  146.     //
  147.     // Static Variables
  148.     //
  149.     // "ptrMap" is a mapping from ptrs to integers, used to give each object a
  150.     // unique number.  See the "printPtr" method for more details.
  151.     //
  152.     static private Map ptrMap = new HashMap ();
  153.     static int nextLabel = 1;                      // Next number to use
  154.     //
  155.     // "alreadyPrinted" is a mapping used to see if we have already
  156.     // printed a node before.
  157.     //
  158.     static private Map alreadyPrinted = new HashMap ();
  159.     //
  160.     // "alreadyPrinted2" is a mapping used to see if we have already
  161.     // printed a node before in printExpr ()...
  162.     //
  163.     static private Map alreadyPrinted2 = new HashMap ();
  164.  
  165.  
  166.  
  167.     //
  168.     // printAst (ptrToNode)
  169.     //
  170.     // This method prints the abstract syntax tree pointed to by "ptrToNode".
  171.     //
  172.     static void printAst (Ast.Node ptrToNode) {
  173.         printAst (6, ptrToNode);
  174.     }
  175.  
  176.  
  177.  
  178.     //
  179.     // printAst (indent, ptrToNode)
  180.     //
  181.     // This method prints the node pointed to by "ptrToNode".  This is
  182.     // a recursive method that calls itself to print the children of
  183.     // this node.
  184.     //
  185.     // The tree is printed with "indent" characters of indentation.
  186.     // Initially, it should be called with an "indent" of about 6 (to
  187.     // allow enough space to print the #999: labels.)  The indentation is
  188.     // increased for the children.
  189.     //
  190.     static void printAst (int indent, Ast.Node ptrToNode) {
  191.  
  192.         // If we have are passed a null pointer, print "NULL"...
  193.         if (ptrToNode == null) {
  194.             printLine (indent, "NULL");
  195.             return;
  196.         }
  197.  
  198.         // Check to see if we have printed out this node before.
  199.         // If so, print a message...
  200.         if (alreadyPrinted.get (ptrToNode) != null) {
  201.           printIndent (indent);
  202.           System.out.print ("*****  This node was printed earlier (");
  203.           printPtr (ptrToNode);
  204.           System.out.print (": ");
  205.           System.out.print (ptrToNode.getClass ().getName ().substring (4));
  206.           System.out.println (") *****");
  207.           return;
  208.         } else {
  209.           alreadyPrinted.put (ptrToNode, ptrToNode);   // Value doesn't matter as
  210.                                                        // long as it is not null.
  211.         }
  212.  
  213.         // Look at the class of this node and print it accordingly...
  214.         if (ptrToNode instanceof Ast.Body) {
  215.             Ast.Body p = (Ast.Body) ptrToNode;
  216.             printHeader (indent, p);
  217.             printItem (indent, "typeDecls=", p.typeDecls);
  218.             printItem (indent, "procDecls=", p.procDecls);
  219.             printItem (indent, "varDecls=",  p.varDecls);
  220.             printItem (indent, "stmts=",     p.stmts);
  221.             if (PROJECT >= 9) {
  222.                 printFieldName (indent, "frameSize=");
  223.                 System.out.println (p.frameSize);
  224.             }
  225.             printFooter (indent);
  226.  
  227.         } else if (ptrToNode instanceof Ast.VarDecl) {
  228.             Ast.VarDecl p = (Ast.VarDecl) ptrToNode;
  229.             printHeader (indent, p);
  230.             printId (indent, p.id);
  231.             printItem (indent, "typeName=", p.typeName);
  232.             printItem (indent, "expr=", p.expr);
  233.             if (PROJECT >= 5) {
  234.               printFieldName (indent, "lexLevel=");
  235.               System.out.println (p.lexLevel);
  236.             }
  237.             if (PROJECT >= 9) {
  238.                 printFieldName (indent, "offset=");
  239.                 System.out.println (p.offset);
  240.             }
  241.             printFooter (indent);
  242.             if (p.next != null) {
  243.                 printAst (indent, p.next);
  244.             }
  245.  
  246.         } else if (ptrToNode instanceof Ast.TypeDecl) {
  247.             Ast.TypeDecl p = (Ast.TypeDecl) ptrToNode;
  248.             printHeader (indent, p);
  249.             printId (indent, p.id);
  250.             printItem (indent, "compoundType=", p.compoundType);
  251.             printFooter (indent);
  252.             if (p.next != null) {
  253.                 printAst (indent, p.next);
  254.             }
  255.  
  256.         } else if (ptrToNode instanceof Ast.TypeName) { 
  257.             Ast.TypeName p = (Ast.TypeName) ptrToNode;
  258.             printHeader (indent, p);
  259.             printId (indent, p.id);
  260.             if (PROJECT >= 5) {
  261.                 printItem (indent, "myDef=", p.myDef);
  262.             }
  263.             printFooter (indent);
  264.  
  265.         } else if (ptrToNode instanceof Ast.ProcDecl) {
  266.             Ast.ProcDecl p = (Ast.ProcDecl) ptrToNode;
  267.             printHeader (indent, p);
  268.             printId (indent, p.id);
  269.             if (PROJECT >= 5) {
  270.                 printFieldName (indent, "lexLevel=");
  271.                 System.out.println (p.lexLevel);
  272.             }
  273.             printItem (indent, "formals=", p.formals);
  274.             printItem (indent, "retType=", p.retType);
  275.             printItem (indent, "body=", p.body);
  276.             printFooter (indent);
  277.             if (p.next != null) {
  278.                 printAst (indent, p.next);
  279.             }
  280.  
  281.         } else if (ptrToNode instanceof Ast.Formal) {
  282.             Ast.Formal p = (Ast.Formal) ptrToNode;
  283.             printHeader (indent, p);
  284.             printId (indent, p.id);
  285.             printItem (indent, "typeName=", p.typeName);
  286.             if (PROJECT >= 5) {
  287.                 printFieldName (indent, "lexLevel=");
  288.                 System.out.println (p.lexLevel);
  289.             }
  290.             if (PROJECT >= 9) {
  291.                 printFieldName (indent, "offset=");
  292.                 System.out.println (p.offset);
  293.             }
  294.             printFooter (indent);
  295.             if (p.next != null) {
  296.                 printAst (indent, p.next);
  297.             }
  298.  
  299.         } else if (ptrToNode instanceof Ast.ArrayType) {
  300.             Ast.ArrayType p = (Ast.ArrayType) ptrToNode;
  301.             printHeader (indent, p);
  302.             printItem (indent, "elementType=", p.elementType);
  303.             printFooter (indent);
  304.  
  305.         } else if (ptrToNode instanceof Ast.RecordType) {
  306.             Ast.RecordType p = (Ast.RecordType) ptrToNode;
  307.             printHeader (indent, p);
  308.             printItem (indent, "fieldDecls=", p.fieldDecls);
  309.             if (PROJECT >= 9) {
  310.                 printFieldName (indent, "size=");
  311.                 System.out.println (p.size);
  312.             }
  313.             printFooter (indent);
  314.  
  315.         } else if (ptrToNode instanceof Ast.FieldDecl) {
  316.             Ast.FieldDecl p = (Ast.FieldDecl) ptrToNode;
  317.             printHeader (indent, p);
  318.             printId (indent, p.id);
  319.             printItem (indent, "typeName=", p.typeName);
  320.             if (PROJECT >= 9) {
  321.                 printFieldName (indent, "offset=");
  322.                 System.out.println (p.offset);
  323.             }
  324.             printFooter (indent);
  325.             if (p.next != null) {
  326.                 printAst (indent, p.next);
  327.             }
  328.  
  329.         } else if (ptrToNode instanceof Ast.AssignStmt) {
  330.             Ast.AssignStmt p = (Ast.AssignStmt) ptrToNode;
  331.             printHeader (indent, p);
  332.             printItem (indent, "lValue=", p.lValue);
  333.             printItem (indent, "expr=", p.expr);
  334.             printFooter (indent);
  335.             if (p.next != null) {
  336.                 printAst (indent, p.next);
  337.             }
  338.  
  339.         } else if (ptrToNode instanceof Ast.CallStmt) {
  340.             Ast.CallStmt p = (Ast.CallStmt) ptrToNode;
  341.             printHeader (indent, p);
  342.             printId (indent, p.id);
  343.             printItem (indent, "args=", p.args);
  344.             if (PROJECT >= 5) {
  345.                 printMyDef (indent, p.myDef);
  346.             }
  347.             printFooter (indent);
  348.             if (p.next != null) {
  349.                 printAst (indent, p.next);
  350.             }
  351.  
  352.         } else if (ptrToNode instanceof Ast.ReadStmt) {
  353.             Ast.ReadStmt p = (Ast.ReadStmt) ptrToNode;
  354.             printHeader (indent, p);
  355.             printItem (indent, "readArgs=", p.readArgs);
  356.             printFooter (indent);
  357.             if (p.next != null) {
  358.                 printAst (indent, p.next);
  359.             }
  360.  
  361.         } else if (ptrToNode instanceof Ast.ReadArg) {
  362.             Ast.ReadArg p = (Ast.ReadArg) ptrToNode;
  363.             printHeader (indent, p);
  364.             printItem (indent, "lValue=", p.lValue);
  365.             if (PROJECT >= 6) {
  366.                 printMode (indent, p.mode);
  367.             }
  368.             printFooter (indent);
  369.             if (p.next != null) {
  370.                 printAst (indent, p.next);
  371.             }
  372.  
  373.         } else if (ptrToNode instanceof Ast.WriteStmt) {
  374.             Ast.WriteStmt p = (Ast.WriteStmt) ptrToNode;
  375.             printHeader (indent, p);
  376.             printItem (indent, "args=", p.args);
  377.             printFooter (indent);
  378.             if (p.next != null) {
  379.                 printAst (indent, p.next);
  380.             }
  381.  
  382.         } else if (ptrToNode instanceof Ast.IfStmt) {
  383.             Ast.IfStmt p = (Ast.IfStmt) ptrToNode;
  384.             printHeader (indent, p);
  385.             printItem (indent, "expr=", p.expr);
  386.             printItem (indent, "thenStmts=", p.thenStmts);
  387.             printItem (indent, "elseStmts=", p.elseStmts);
  388.             printFooter (indent);
  389.             if (p.next != null) {
  390.                 printAst (indent, p.next);
  391.             }
  392.  
  393.         } else if (ptrToNode instanceof Ast.WhileStmt) {
  394.             Ast.WhileStmt p = (Ast.WhileStmt) ptrToNode;
  395.             printHeader (indent, p);
  396.             printItem (indent, "expr=", p.expr);
  397.             printItem (indent, "stmts=", p.stmts);
  398.             if (PROJECT >= 8) {
  399.                 printStringField (indent, "exitLabel=", p.exitLabel);
  400.             }
  401.             printFooter (indent);
  402.             if (p.next != null) {
  403.                 printAst (indent, p.next);
  404.             }
  405.  
  406.         } else if (ptrToNode instanceof Ast.LoopStmt) {
  407.             Ast.LoopStmt p = (Ast.LoopStmt) ptrToNode;
  408.             printHeader (indent, p);
  409.             printItem (indent, "stmts=", p.stmts);
  410.             if (PROJECT >= 8) {
  411.                 printStringField (indent, "exitLabel=", p.exitLabel);
  412.             }
  413.             printFooter (indent);
  414.             if (p.next != null) {
  415.                 printAst (indent, p.next);
  416.             }
  417.  
  418.         } else if (ptrToNode instanceof Ast.ForStmt) {
  419.             Ast.ForStmt p = (Ast.ForStmt) ptrToNode;
  420.             printHeader (indent, p);
  421.             printItem (indent, "lValue=", p.lValue);
  422.             printItem (indent, "expr1=", p.expr1);
  423.             printItem (indent, "expr2=", p.expr2);
  424.             printItem (indent, "expr3=", p.expr3);
  425.             printItem (indent, "stmts=", p.stmts);
  426.             if (PROJECT >= 8) {
  427.                 printStringField (indent, "exitLabel=", p.exitLabel);
  428.             }
  429.             printFooter (indent);
  430.             if (p.next != null) {
  431.                 printAst (indent, p.next);
  432.             }
  433.  
  434.         } else if (ptrToNode instanceof Ast.ExitStmt) {
  435.             Ast.ExitStmt p = (Ast.ExitStmt) ptrToNode;
  436.             printHeader (indent, p);
  437.             if (PROJECT >= 6) {
  438.                 printItem (indent, "myLoop=", p.myLoop);
  439.             }
  440.             printFooter (indent);
  441.             if (p.next != null) {
  442.                 printAst (indent, p.next);
  443.             }
  444.  
  445.         } else if (ptrToNode instanceof Ast.ReturnStmt) {
  446.             Ast.ReturnStmt p = (Ast.ReturnStmt) ptrToNode;
  447.             printHeader (indent, p);
  448.             printFieldName (indent, "summary= ");
  449.             printExpr (p.expr);
  450.             System.out.println ();
  451.             printItem (indent, "expr=", p.expr);
  452.             if (PROJECT >= 6) {
  453.                 printItem (indent, "myProc=", p.myProc);
  454.             }
  455.             printFooter (indent);
  456.             if (p.next != null) {
  457.                 printAst (indent, p.next);
  458.             }
  459.  
  460.         } else if (ptrToNode instanceof Ast.BinaryOp) {
  461.             Ast.BinaryOp p = (Ast.BinaryOp) ptrToNode;
  462.             printHeader (indent, p);
  463.             printOperator (indent, p.op);
  464.             printItem (indent, "expr1=", p.expr1);
  465.             printItem (indent, "expr2=", p.expr2);
  466.             if (PROJECT >= 6) {
  467.                 printMode (indent, p.mode);
  468.             }
  469.             printFooter (indent);
  470.  
  471.         } else if (ptrToNode instanceof Ast.UnaryOp) {
  472.             Ast.UnaryOp p = (Ast.UnaryOp) ptrToNode;
  473.             printHeader (indent, p);
  474.             printOperator (indent, p.op);
  475.             printItem (indent, "expr=", p.expr);
  476.             if (PROJECT >= 6) {
  477.                 printMode (indent, p.mode);
  478.             }
  479.             printFooter (indent);
  480.  
  481.         } else if (ptrToNode instanceof Ast.IntToReal) {
  482.             Ast.IntToReal p = (Ast.IntToReal) ptrToNode;
  483.             printHeader (indent, p);
  484.             printItem (indent, "expr=", p.expr);
  485.             printFooter (indent);
  486.  
  487.         } else if (ptrToNode instanceof Ast.FunctionCall) {
  488.             Ast.FunctionCall p = (Ast.FunctionCall) ptrToNode;
  489.             printHeader (indent, p);
  490.             printId (indent, p.id);
  491.             printItem (indent, "args=", p.args);
  492.             if (PROJECT >= 5) {
  493.                 printMyDef (indent, p.myDef);
  494.             }
  495.             printFooter (indent);
  496.  
  497.         } else if (ptrToNode instanceof Ast.Argument) {
  498.             Ast.Argument p = (Ast.Argument) ptrToNode;
  499.             printHeader (indent, p);
  500.             printItem (indent, "expr=", p.expr);
  501.             if (PROJECT >= 6) {
  502.                 printMode (indent, p.mode);
  503.             }
  504.             if (PROJECT >= 8) {
  505.                 printItem (indent, "location=", p.location);
  506.             }
  507.             printFooter (indent);
  508.             if (p.next != null) {
  509.                 printAst (indent, p.next);
  510.             }
  511.  
  512.         } else if (ptrToNode instanceof Ast.ArrayConstructor) {
  513.             Ast.ArrayConstructor p = (Ast.ArrayConstructor) ptrToNode;
  514.             printHeader (indent, p);
  515.             printId (indent, p.id);
  516.             printItem (indent, "values=", p.values);
  517.             if (PROJECT >= 5) {
  518.                 printMyDef (indent, p.myDef);
  519.             }
  520.             printFooter (indent);
  521.  
  522.         } else if (ptrToNode instanceof Ast.ArrayValue) {
  523.             Ast.ArrayValue p = (Ast.ArrayValue) ptrToNode;
  524.             printHeader (indent, p);
  525.             printItem (indent, "countExpr=", p.countExpr);
  526.             printItem (indent, "valueExpr=", p.valueExpr);
  527.             if (PROJECT >= 9) {
  528.                 printItem (indent, "tempCount=", p.tempCount);
  529.                 printItem (indent, "tempValue=", p.tempValue);
  530.             }
  531.             printFooter (indent);
  532.             if (p.next != null) {
  533.                 printAst (indent, p.next);
  534.             }
  535.  
  536.         } else if (ptrToNode instanceof Ast.RecordConstructor) {
  537.             Ast.RecordConstructor p = (Ast.RecordConstructor) ptrToNode;
  538.             printHeader (indent, p);
  539.             printId (indent, p.id);
  540.             printItem (indent, "fieldInits=", p.fieldInits);
  541.             if (PROJECT >= 5) {
  542.                 printMyDef (indent, p.myDef);
  543.             }
  544.             printFooter (indent);
  545.  
  546.         } else if (ptrToNode instanceof Ast.FieldInit) {
  547.             Ast.FieldInit p = (Ast.FieldInit) ptrToNode;
  548.             printHeader (indent, p);
  549.             printId (indent, p.id);
  550.             printItem (indent, "expr=", p.expr);
  551.             if (PROJECT >= 6) {
  552.                 printItem (indent, "myFieldDecl=", p.myFieldDecl);
  553.             }
  554.             printFooter (indent);
  555.             if (p.next != null) {
  556.                 printAst (indent, p.next);
  557.             }
  558.  
  559.         } else if (ptrToNode instanceof Ast.IntegerConst) {
  560.             Ast.IntegerConst p = (Ast.IntegerConst) ptrToNode;
  561.             printHeader (indent, p);
  562.             printIndent (indent+TABAMT);
  563.             System.out.println ("iValue=" + p.iValue);
  564.             printFooter (indent);
  565.  
  566.         } else if (ptrToNode instanceof Ast.RealConst) {
  567.             Ast.RealConst p = (Ast.RealConst) ptrToNode;
  568.             printHeader (indent, p);
  569.             printIndent (indent+TABAMT);
  570.             System.out.println ("rValue=" + p.rValue);
  571.             if (PROJECT >= 9) {
  572.                 printStringField (indent, "nameOfConstant=", p.nameOfConstant);
  573.                 printItem (indent, "next=", p.next);
  574.             }
  575.             printFooter (indent);
  576.  
  577.         } else if (ptrToNode instanceof Ast.StringConst) {
  578.             Ast.StringConst p = (Ast.StringConst) ptrToNode;
  579.             printHeader (indent, p);
  580.             printStringField (indent, "sValue=", p.sValue);
  581.             if (PROJECT >= 6) {
  582.                 printStringField (indent, "nameOfConstant=", p.nameOfConstant);
  583.                 printItem (indent, "next=", p.next);
  584.             }
  585.             printFooter (indent);
  586.  
  587.         } else if (ptrToNode instanceof Ast.BooleanConst) {
  588.             Ast.BooleanConst p = (Ast.BooleanConst) ptrToNode;
  589.             printHeader (indent, p);
  590.             printFieldName (indent, "iValue=");
  591.             System.out.println (p.iValue);
  592.             printFooter (indent);
  593.  
  594.         } else if (ptrToNode instanceof Ast.NilConst) {
  595.             printHeader (indent, ptrToNode);
  596.             printFooter (indent);
  597.  
  598.         } else if (ptrToNode instanceof Ast.ValueOf) {
  599.             Ast.ValueOf p = (Ast.ValueOf) ptrToNode;
  600.             printHeader (indent, p);
  601.             printItem (indent, "lValue=", p.lValue);
  602.             printFooter (indent);
  603.  
  604.         } else if (ptrToNode instanceof Ast.Variable) {
  605.             Ast.Variable p = (Ast.Variable) ptrToNode;
  606.             printHeader (indent, p);
  607.             printId (indent, p.id);
  608.             if (PROJECT >= 5) {
  609.                 printMyDef (indent, p.myDef);
  610.             }
  611.             if (PROJECT >= 5) {
  612.                 printFieldName (indent, "currentLevel=");
  613.                 System.out.println (p.currentLevel);
  614.             }
  615.             printFooter (indent);
  616.  
  617.         } else if (ptrToNode instanceof Ast.ArrayDeref) {
  618.             Ast.ArrayDeref p = (Ast.ArrayDeref) ptrToNode;
  619.             printHeader (indent, p);
  620.             printItem (indent, "lValue=", p.lValue);
  621.             printItem (indent, "expr=", p.expr);
  622.             printFooter (indent);
  623.  
  624.         } else if (ptrToNode instanceof Ast.RecordDeref) {
  625.             Ast.RecordDeref p = (Ast.RecordDeref) ptrToNode;
  626.             printHeader (indent, p);
  627.             printItem (indent, "lValue=", p.lValue);
  628.             printId (indent, p.id);
  629.             if (PROJECT >= 6) {
  630.                 printItem (indent, "myFieldDecl=", p.myFieldDecl);
  631.             }
  632.             printFooter (indent);
  633.  
  634.         } else {
  635.             printLine (indent, "(********** Class is unknown!!! **********)");
  636.         }
  637.     }
  638.  
  639.  
  640.  
  641.     //
  642.     // printHeader (indent, p)
  643.     //
  644.     // This method indents, then prints the class of object p, then
  645.     // prints p.lineNumber, then finally prints a newline.
  646.     //
  647.     static void printHeader (int indent, Ast.Node p) {
  648.         int i = printPtr (p);
  649.         System.out.print (": ");
  650.         i = indent - i - TABAMT;
  651.         printIndent (i);
  652.         System.out.print ("---------- ");
  653.         System.out.print (p.getClass ().getName ().substring (4));
  654.         System.out.println (" ----------");
  655.         printFieldName (indent, "lineNumber=");
  656.         System.out.println (p.lineNumber);
  657.     }
  658.  
  659.  
  660.  
  661.     //
  662.     // printFooter (indent)
  663.     //
  664.     // This method indents, then the closing bracketting symbol.
  665.     //
  666.     static void printFooter (int indent) {
  667.         printIndent (indent);
  668.         System.out.println ("------------------------------");
  669.     }
  670.  
  671.  
  672.  
  673.     //
  674.     // printIndent (indent)
  675.     //
  676.     // This method prints "indent" spaces.
  677.     //
  678.     static void printIndent (int indent) {
  679.         for (int i = indent; i>0; i--) {
  680.             System.out.print (" ");
  681.         }
  682.     }
  683.  
  684.  
  685.  
  686.     //
  687.     // printLine (indent, str)
  688.     //
  689.     // This method indents, then prints the given string, then prints newline.
  690.     //
  691.     static void printLine (int indent, String str) {
  692.         printIndent (indent);
  693.         System.out.println (str);
  694.     }
  695.  
  696.  
  697.  
  698.     //
  699.     // printStringField (indent, str1, str2)
  700.     //
  701.     // This method indents by "indent" + TABAMT, then prints str1, then prints
  702.     // str2, then prints newline.
  703.     //
  704.     static void printStringField (int indent, String str1, String str2) {
  705.         printIndent (indent + TABAMT);
  706.         if (str2 == null) {
  707.             System.out.print (str1);
  708.             System.out.println ("NULL");
  709.         } else {
  710.             System.out.print (str1);
  711.             System.out.print ("\"");
  712.             System.out.print (str2);
  713.             System.out.println ("\"");
  714.         }
  715.     }
  716.  
  717.  
  718.  
  719.     //
  720.     // printId (indent, id)
  721.     //
  722.     // This method indents by "indent" + TABAMT, then prints "id=", then prints
  723.     // the id argument, then prints newline.
  724.     //
  725.     static void printId (int indent, String id) {
  726.         printStringField (indent, "id=", id);
  727.     }
  728.  
  729.  
  730.  
  731.     //
  732.     // printMyDef (indent, p)
  733.     //
  734.     // This method indents by "indent" + TABAMT, then prints "myDef=", then prints
  735.     // the argument, then prints newline.
  736.     //
  737.     static void printMyDef (int indent, Ast.Node p) {
  738.         printItem (indent, "myDef=", p);
  739.     }
  740.  
  741.  
  742.  
  743.     //
  744.     // printFieldName (indent, str)
  745.     //
  746.     // This method indents by "indent" + TABAMT, then prints the given string.  It
  747.     // prints no newline.
  748.     //
  749.     static void printFieldName (int indent, String str) {
  750.         printIndent (indent + TABAMT);
  751.         System.out.print (str);
  752.     }
  753.  
  754.  
  755.  
  756.     //
  757.     // printItem (indent, s, t)
  758.     //
  759.     // This method prints the given string on one line (indented by TABAMT more
  760.     // than "indent") and then calls printAst() to print the tree "t" (indented by
  761.     // 2*TABAMT more spaces than "indent").
  762.     //
  763.     static void printItem (int indent, String s, Ast.Node t) {
  764.         printIndent (indent + TABAMT);
  765.         System.out.print (s);
  766.         if (t == null) {
  767.             System.out.println ("NULL");
  768.         } else {
  769.             System.out.println ();
  770.             printAst (indent + TABAMT + TABAMT, t);
  771.         }
  772.     }
  773.  
  774.  
  775.  
  776.     //
  777.     // printOperator (indent, op)
  778.     //
  779.     // This method is passed a token type in "op".  It prints it out in the form:
  780.     //       op=PLUS
  781.     ///
  782.     static void printOperator (int in, int op) {
  783.         printIndent (in+TABAMT);
  784.         switch (op) {
  785.             case Token.LEQ:
  786.                 System.out.println ("op=LEQ");
  787.                 return;
  788.             case Token.GEQ:
  789.                 System.out.println ("op=GEQ");
  790.                 return;
  791.             case Token.NEQ:
  792.                 System.out.println ("op=NEQ");
  793.                 return;
  794.             case Token.AND:
  795.                 System.out.println ("op=AND");
  796.                 return;
  797.             case Token.DIV:
  798.                 System.out.println ("op=DIV");
  799.                 return;
  800.             case Token.MOD:
  801.                 System.out.println ("op=MOD");
  802.                 return;
  803.             case Token.NOT:
  804.                 System.out.println ("op=NOT");
  805.                 return;
  806.             case Token.OR:
  807.                 System.out.println ("op=OR");
  808.                 return;
  809.             case Token.LESS:
  810.                 System.out.println ("op=LESS");
  811.                 return;
  812.             case Token.GREATER:
  813.                 System.out.println ("op=GREATER");
  814.                 return;
  815.             case Token.EQUAL:
  816.                 System.out.println ("op=EQUAL");
  817.                 return;
  818.             case Token.PLUS:
  819.                 System.out.println ("op=PLUS");
  820.                 return;
  821.             case Token.MINUS:
  822.                 System.out.println ("op=MINUS");
  823.                 return;
  824.             case Token.STAR:
  825.                 System.out.println ("op=STAR");
  826.                 return;
  827.             case Token.SLASH:
  828.                 System.out.println ("op=SLASH");
  829.                 return;
  830.             default:
  831.                 System.out.println ("op=***** ERROR: op IS GARBAGE *****");
  832.         }
  833.     }
  834.  
  835.  
  836.  
  837.     //
  838.     // printPtr (p)
  839.     //
  840.     // This method is passed a pointer, possibly NULL.  It prints the pointer.
  841.     // The actual address is not printed, since these may vary from run to run.
  842.     // Instead, this method assigns 'labels' to each address and prints the
  843.     // same label each time.  It saves the mapping between label and address
  844.     // in a static hashMap called "ptrMap".
  845.     //
  846.     // This method returns the number of characters printed.
  847.     //
  848.     static int printPtr (Ast.Node p) {
  849.         int i;
  850.  
  851.         // If the pointer is null, then print "NULL"...
  852.         if (p == null) {
  853.             System.out.print ("NULL");
  854.             return 4;
  855.         }
  856.  
  857.         // Figure out what integer goes with this ptr...
  858.         Integer val = (Integer) ptrMap.get (p);
  859.         if (val != null) {
  860.           i = val.intValue ();
  861.         } else {
  862.           i = nextLabel++;
  863.           ptrMap.put (p, new Integer (i));
  864.         }
  865.  
  866.         // Print the number...
  867.         String str = "#" + i;
  868.         System.out.print (str);
  869.  
  870.         // Return the number of characters just printed...
  871.         return str.length ();
  872.     }
  873.  
  874.  
  875.  
  876.     //
  877.     // printExpr (p)
  878.     //
  879.     // This method is passed a pointer, possibly NULL, which should point to
  880.     // an expression or an LValue.  It prints it out in a way that is intended
  881.     // to be more human-readable.  It is used for the "summary=" printout.
  882.     //
  883.     // This method method assumes that it is passed a tree-shaped data
  884.     // structure.  If not, it will print a warning.
  885.     //
  886.     static void printExpr (Ast.Node p) {
  887.  
  888.         // Deal with and print a NULL...
  889.         if (p == null) {
  890.             System.out.print ("NULL");
  891.             return;
  892.         }
  893.  
  894.         // Check to see if we have printed this node before.
  895.         // If so, this is not a tree, so print a message...
  896.         if (alreadyPrinted2.get (p) != null) {
  897.           System.out.print ("*****  Node Sharing detected!  *****");
  898.           return;
  899.         } else {
  900.           alreadyPrinted2.put (p, p);   // Value doesn't matter as
  901.                                         // long as it is not null.
  902.         }
  903.         if (p instanceof Ast.BinaryOp) {
  904.             Ast.BinaryOp p2 = (Ast.BinaryOp) p;
  905.             System.out.print ("(");
  906.             printExpr (p2.expr1);
  907.             System.out.print (" ");
  908.             System.out.print (Token.stringOf [p2.op]);
  909.             System.out.print (" ");
  910.             printExpr (p2.expr2);
  911.             System.out.print (")");
  912.  
  913.         } else if (p instanceof Ast.UnaryOp) {
  914.             Ast.UnaryOp p2 = (Ast.UnaryOp) p;
  915.             System.out.print ("(");
  916.             System.out.print (Token.stringOf [p2.op]);
  917.             System.out.print (" ");
  918.             printExpr (p2.expr);
  919.             System.out.print (")");
  920.  
  921.         } else if (p instanceof Ast.IntToReal) {
  922.             Ast.IntToReal p2 = (Ast.IntToReal) p;
  923.             System.out.print ("intToReal (");
  924.             printExpr (p2.expr);
  925.             System.out.print (")");
  926.  
  927.         } else if (p instanceof Ast.FunctionCall) {
  928.             Ast.FunctionCall p2 = (Ast.FunctionCall) p;
  929.             System.out.print (p2.id);
  930.             System.out.print ("(");
  931.             for (Ast.Argument arg = p2.args; arg != null; arg = arg.next) {
  932.               printExpr (arg.expr);
  933.               if (arg.next != null) {
  934.                 System.out.print (",");
  935.               }
  936.             }
  937.             System.out.print (")");
  938.  
  939.         } else if (p instanceof Ast.ArrayConstructor) {
  940.             Ast.ArrayConstructor p2 = (Ast.ArrayConstructor) p;
  941.             System.out.print (p2.id);
  942.             System.out.print ("{{");
  943.             for (Ast.ArrayValue arrayValue = p2.values;
  944.                  arrayValue != null;
  945.                  arrayValue = arrayValue.next) {
  946.               if (arrayValue.countExpr != null) {
  947.                 printExpr (arrayValue.countExpr);
  948.                 System.out.print (" of ");
  949.               }
  950.               printExpr (arrayValue.valueExpr);
  951.               if (arrayValue.next != null) {
  952.                 System.out.print (", ");
  953.               }
  954.             }
  955.             System.out.print ("}}");
  956.  
  957.         } else if (p instanceof Ast.RecordConstructor) {
  958.             Ast.RecordConstructor p2 = (Ast.RecordConstructor) p;
  959.             System.out.print (p2.id);
  960.             System.out.print ("{");
  961.             for (Ast.FieldInit fieldInit = p2.fieldInits;
  962.                  fieldInit != null;
  963.                  fieldInit = fieldInit.next) {
  964.               System.out.print (fieldInit.id);
  965.               System.out.print (" := ");
  966.               printExpr (fieldInit.expr);
  967.               if (fieldInit.next != null) {
  968.                 System.out.print ("; ");
  969.               }
  970.             }
  971.             System.out.print ("}");
  972.  
  973.         } else if (p instanceof Ast.IntegerConst) {
  974.             Ast.IntegerConst p2 = (Ast.IntegerConst) p;
  975.             System.out.print (p2.iValue);
  976.  
  977.         } else if (p instanceof Ast.RealConst) {
  978.             Ast.RealConst p2 = (Ast.RealConst) p;
  979.             System.out.print (p2.rValue);
  980.  
  981.         } else if (p instanceof Ast.StringConst) {
  982.             Ast.StringConst p2 = (Ast.StringConst) p;
  983.             System.out.print ("\"");
  984.             System.out.print (p2.sValue);
  985.             System.out.print ("\"");
  986.  
  987.         } else if (p instanceof Ast.BooleanConst) {
  988.             Ast.BooleanConst p2 = (Ast.BooleanConst) p;
  989.             if (p2.iValue == 0) {
  990.               System.out.print ("FALSE");
  991.             } else {
  992.               System.out.print ("TRUE");
  993.             }
  994.  
  995.         } else if (p instanceof Ast.NilConst) {
  996.             System.out.print ("NIL");
  997.  
  998.         } else if (p instanceof Ast.ValueOf) {
  999.             Ast.ValueOf p2 = (Ast.ValueOf) p;
  1000.             System.out.print ("valueof(");
  1001.             printExpr (p2.lValue);
  1002.             System.out.print (")");
  1003.  
  1004.         } else if (p instanceof Ast.Variable) {
  1005.             Ast.Variable p2 = (Ast.Variable) p;
  1006.             System.out.print (p2.id);
  1007.  
  1008.         } else if (p instanceof Ast.ArrayDeref) {
  1009.             Ast.ArrayDeref p2 = (Ast.ArrayDeref) p;
  1010.             System.out.print ("(");
  1011.             printExpr (p2.lValue);
  1012.             System.out.print ("[");
  1013.             printExpr (p2.expr);
  1014.             System.out.print ("])");
  1015.  
  1016.         } else if (p instanceof Ast.RecordDeref) {
  1017.             Ast.RecordDeref p2 = (Ast.RecordDeref) p;
  1018.             System.out.print ("(");
  1019.             printExpr (p2.lValue);
  1020.             System.out.print (".");
  1021.             System.out.print (p2.id);
  1022.             System.out.print (")");
  1023.  
  1024.         } else {
  1025.             System.out.print ("********** ??? **********");
  1026.         }
  1027.  
  1028.     }
  1029.  
  1030.  
  1031.  
  1032.     // printMode (indent, m)
  1033.     //
  1034.     // Print something like "mode=INTEGER_MODE" to indicate the value of argument m.
  1035.     //
  1036.     static void printMode (int indent, int m) {
  1037.         final int INTEGER_MODE = 1;
  1038.         final int REAL_MODE = 2;
  1039.         final int STRING_MODE = 3;
  1040.         final int BOOLEAN_MODE = 4;
  1041.         printFieldName (indent, "mode=");
  1042.         switch (m) {
  1043.             case INTEGER_MODE:
  1044.                 System.out.print ("INTEGER_MODE");
  1045.                 break;
  1046.             case REAL_MODE:
  1047.                 System.out.print ("REAL_MODE");
  1048.                 break;
  1049.             case BOOLEAN_MODE:
  1050.                 System.out.print ("BOOLEAN_MODE");
  1051.                 break;
  1052.             case STRING_MODE:
  1053.                 System.out.print ("STRING_MODE");
  1054.                 break;
  1055.             case 0:
  1056.                 System.out.print ("0");
  1057.                 break;
  1058.             default:
  1059.                 System.out.print ("***** Mode is garbage! *****");
  1060.                 break;
  1061.         }
  1062.         System.out.println ();
  1063.     }
  1064.  
  1065. }
  1066.