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 / p5 / PrettyPrint.java < prev    next >
Text File  |  2005-11-01  |  28KB  |  1,000 lines

  1. // PrettyPrint.java
  2. //
  3. // Harry Porter -- 10/29/05
  4. //
  5. // This file contains a static method called "prettyPrintAst()" which can be
  6. // called to print an Abstract Syntax Tree in a form closely resembling
  7. // the PCAT program from which the AST originated.  This is useful for
  8. // making sure that the ASTs we are building match the syntax of the source
  9. // program.
  10. //
  11. // The output from "printAst()" tends to be long and difficult to read, since it
  12. // was designed to be a complete and reliable dump of the AST.  However, you may
  13. // wish to see only a small, selected part of the AST, to check see what your
  14. // program is producing.  The code in this file can be modified easily to print
  15. // just the portions of the AST you are interested in.
  16. //
  17. // Of course, the comments and the indentation of the original source file
  18. // are not captured in the AST, so the output from this program will have no
  19. // comments and will have rather mechanical indentation and spacing.
  20. // Nevertheless, the indentation should resemble that a human PCAT programmer
  21. // might use.  Also, this program will fully parenthesize expressions, leaving
  22. // no doubt as to how expressions have been parsed.
  23. //
  24. // For example, here is a simple PCAT program:
  25. //
  26. //       program is
  27. //         var x: integer := 1;
  28. //                   y: integer := 2;   (* funky indentation *)
  29. //             begin
  30. //              x := 5*y;  (* Parens are not used here. *)
  31. //             end;
  32. //
  33. // Here is how prettyPrint() prints the Abstract Syntax Tree we build
  34. // after parsing the above program:
  35. //
  36. // 1.    PROGRAM IS
  37. // 2.        VAR
  38. // 3.            x: integer := 1;
  39. // 4.            y: integer := 2;
  40. // 5.        BEGIN
  41. // 6.            x := (5 * y);
  42. // 7.        END;
  43. //
  44. // (Line numbers have been added for ease of reference in this discussion.)
  45. //
  46. // In addition to printing the tokens, these methods can be easily modified
  47. // to print the "lexLevel", "currentLevel", and "myDef" fields wherever
  48. // desired.  The print statements to print that info are included in
  49. // this program but these lines are currently commented out.  These lines can be
  50. // uncommented to get the output.  Code to print the ValueOf nodes is
  51. // also included, but is also commented out.
  52. //
  53. // For example, the following output shows how these methods would print the
  54. // Abstract Syntax Tree for a simple program if the appropriate statements
  55. // were uncommented.
  56. //
  57. // 1.    PROGRAM IS
  58. // 2.        VAR
  59. // 3.             [#1:] x [lexLevel=0] : integer [myDef=#2]  := 1;
  60. // 4.             [#3:] y [lexLevel=0] : integer [myDef=#2]  := 2;
  61. // 5.        BEGIN
  62. // 6.            x [myDef=#1]  [currLev=0]  := (5 * ValueOf (y [myDef=#3]  [currLev=0] ));
  63. // 7.        END;
  64. //
  65. // Note that the "myDef" fields point back to VarDecl nodes.  To indicate
  66. // which pointers point where, certain structures are labelled as they
  67. // are printed.  For example, the VarDecl structure for "x" is labelled
  68. // "#1".  Later, on line 6, a Variable node for "x" is printed.  The value
  69. // of its "myDef" field is shown using this label.
  70. //
  71. // These methods do not alway check the AST and may crash if the tree is
  72. // messed up.  If, for example, some field is null which should not be null,
  73. // these methods may throw a NullPointerException.
  74. //
  75.  
  76. import java.io.*;
  77. import java.util.*;
  78.  
  79. class PrettyPrint {
  80.  
  81.     //
  82.     // Static Variables
  83.     //
  84.     // "ptrMap" is a mapping from ptrs to integers, used to give each object a
  85.     // unique number.  See the "printPtr" method for more details.
  86.     //
  87.     static private Map ptrMap = new HashMap ();
  88.     static int nextLabel = 1;                     // Next number to use
  89.  
  90.     static final int TAB = 4;                     // Number of spaced for indenting
  91.  
  92.  
  93.     //
  94.     //  Constructor.
  95.     //
  96.     private PrettyPrint () { }
  97.     
  98.     
  99.     // prettyPrintAst (body)
  100.     //
  101.     // This method prints the Abstract Syntax Tree with formatting.
  102.     // It is passed a pointer to a Body node.
  103.     //
  104.     // This method will create a "PrettyPrint" object, which is only used
  105.     // during the pretty-printing.  It has no fields.  All of the remaining
  106.     // methods are instance methods, but they could just as easily have been
  107.     // static methods, since the receiver is never really used.
  108.     //
  109.     static void prettyPrintAst (Ast.Body body) {
  110.         PrettyPrint pp = new PrettyPrint ();
  111.         System.out.println ("PROGRAM IS");
  112.         pp.ppBody (TAB, body);
  113.     }
  114.     
  115.     
  116.     
  117.     //
  118.     // ppBody (indent, body)
  119.     //
  120.     // Print the Body, indented by "indent" spaces.
  121.     //
  122.     void ppBody (int indent, Ast.Body body) {
  123.         if (body.typeDecls != null) {
  124.             printLine (indent, "TYPE");
  125.             ppTypeDecls (indent + TAB, body.typeDecls);
  126.         }
  127.         if (body.varDecls != null) {
  128.             printLine (indent, "VAR");
  129.             ppVarDecls (indent + TAB, body.varDecls);
  130.         }
  131.         ppProcDecls (indent, body.procDecls);
  132.         printLine (indent, "BEGIN");
  133.         ppStmts (indent + TAB, body.stmts);
  134.         printLine (indent, "END;");
  135.     }
  136.     
  137.     
  138.     
  139.     //
  140.     // ppTypeDecls (indent, typeDeclList)
  141.     //
  142.     // Print all the TypeDecls pointed to by "typeDeclList",
  143.     // indented by "indent" spaces.
  144.     //
  145.     void ppTypeDecls (int indent, Ast.TypeDecl p) {
  146.         while (p != null) {
  147.             printIndent (indent);
  148.             // For testing; feel free to uncomment the following...
  149.             // printLabel (p);
  150.             System.out.print (p.id);
  151.             System.out.print (" IS ");
  152.             ppCompoundType (p.compoundType);
  153.             System.out.println (";");
  154.             p = p.next;
  155.         }
  156.     }
  157.     
  158.     
  159.     
  160.     //
  161.     // ppVarDecls (indent, varDeclList)
  162.     //
  163.     // Print the list of VarDecls pointed to by "varDeclList",
  164.     // indented by "indent" spaces.
  165.     //
  166.     void ppVarDecls (int indent, Ast.VarDecl p) {
  167.         while (p != null) {
  168.             printIndent (indent);
  169.             // For testing; feel free to uncomment the following...
  170.             // printLabel (p);
  171.             System.out.print (p.id);
  172.             // For testing; feel free to uncomment the following...
  173.             // System.out.print (" [lexLevel=" + p.lexLevel + "] ");
  174.             if (p.typeName != null) {
  175.                 System.out.print (": ");
  176.                 ppTypeName (p.typeName);
  177.             }
  178.             if (p.expr != null) {
  179.                 System.out.print (" := ");
  180.                 ppExpr (p.expr);
  181.             }
  182.             System.out.println (";");
  183.             p = p.next;
  184.         }
  185.     }
  186.     
  187.     
  188.     
  189.     //
  190.     // ppProcDecls (indent, procDeclList)
  191.     //
  192.     // Print the list of ProcDecls pointed to by "procDeclList",
  193.     // indented by "indent" spaces.
  194.     //
  195.     void ppProcDecls (int indent, Ast.ProcDecl p) {
  196.         while (p != null) {
  197.             ppProcDecl (indent, p);
  198.             p = p.next;
  199.         }
  200.     }
  201.     
  202.     
  203.     
  204.     //
  205.     // ppProcDecl (indent, procDecl)
  206.     //
  207.     // Print the ProcDecl, indented by "indent" spaces.
  208.     //
  209.     void ppProcDecl (int indent, Ast.ProcDecl p) {
  210.         printIndent (indent);
  211.         System.out.print ("PROCEDURE ");
  212.         // For testing; feel free to uncomment the following...
  213.         // printLabel (p);
  214.         System.out.print (p.id);
  215.         // For testing; feel free to uncomment the following...
  216.         // System.out.print (" [lexLevel=" + p.lexLevel + "] ");
  217.         ppFormals (p.formals);
  218.         if (p.retType != null) {
  219.             System.out.print (" : ");
  220.             ppTypeName (p.retType);
  221.         }
  222.         System.out.println (" IS");
  223.         ppBody (indent+TAB, p.body);
  224.     }
  225.     
  226.     
  227.     
  228.     //
  229.     // ppFormals (formalList)
  230.     //
  231.     // Print the list of Formals pointed to by "formalList".
  232.     //
  233.     void ppFormals (Ast.Formal p) {
  234.         System.out.print (" (");
  235.         while (p != null) {
  236.             // For testing; feel free to uncomment the following...
  237.             // printLabel (p);
  238.             System.out.print (p.id);
  239.             // For testing; feel free to uncomment the following...
  240.             // System.out.print (" [lexLevel=" + p.lexLevel + "] ");
  241.             System.out.print (": ");
  242.             ppTypeName (p.typeName);
  243.             p = p.next;
  244.             if (p != null) {
  245.               System.out.print ("; ");
  246.             }
  247.         }
  248.         System.out.print (")");
  249.     }
  250.     
  251.     
  252.     
  253.     //
  254.     // ppTypeName (typeName)
  255.     //
  256.     // Print the TypeName.
  257.     //
  258.     void ppTypeName (Ast.TypeName p) {
  259.         System.out.print (p.id);
  260.         // For testing; feel free to uncomment the following...
  261.         // printMyDef (p.myDef);
  262.  
  263.     }
  264.  
  265.  
  266.  
  267.     //
  268.     // ppCompoundType (compoundType)
  269.     //
  270.     // Print the CompoundType.
  271.     //
  272.     void ppCompoundType (Ast.CompoundType p) {
  273.         if (p == null) {
  274.             System.out.print ("NULL");
  275.         } else if (p instanceof Ast.ArrayType) {
  276.             ppArrayType ((Ast.ArrayType) p);
  277.         } else if (p instanceof Ast.RecordType) {
  278.             ppRecordType ((Ast.RecordType) p);
  279.         } else {
  280.             System.out.print ("*****  Unknown class in ppCompoundType!  *****");
  281.         }
  282.     }
  283.     
  284.     
  285.     
  286.     //
  287.     // ppArrayType (arrayType)
  288.     //
  289.     // Print the ArrayType.
  290.     //
  291.     void ppArrayType (Ast.ArrayType p) {
  292.         System.out.print ("ARRAY OF ");
  293.         ppTypeName (p.elementType);
  294.     }
  295.     
  296.     
  297.     
  298.     //
  299.     // ppRecordType (recordType)
  300.     //
  301.     // Print the RecordType.
  302.     //
  303.     void ppRecordType (Ast.RecordType p) {
  304.         System.out.print ("RECORD ");
  305.         ppFieldDecls (p.fieldDecls);
  306.         System.out.print ("END");
  307.     }
  308.     
  309.     
  310.     
  311.     //
  312.     // ppFieldDecls (fieldDecl)
  313.     //
  314.     // Print the FieldDecl.
  315.     //
  316.     void ppFieldDecls (Ast. FieldDecl p) {
  317.         while (p != null) {
  318.             System.out.print (p.id);
  319.             System.out.print (": ");
  320.             ppTypeName (p.typeName);
  321.             System.out.print ("; ");
  322.             p = p.next;
  323.         }
  324.     }
  325.     
  326.     
  327.     
  328.     //
  329.     // ppStmts (indent, stmt)
  330.     //
  331.     // Print the list of statements pointed to by "stmt", indented by
  332.     // "indent" spaces.  The argument "stmt" may be NULL; in that case
  333.     // nothing will be printed.
  334.     //
  335.     void ppStmts (int indent, Ast.Stmt stmt) {
  336.         while (stmt != null) {
  337.             if (stmt instanceof Ast.AssignStmt) {
  338.                 ppAssignStmt (indent, (Ast.AssignStmt) stmt);
  339.             } else if (stmt instanceof Ast.CallStmt) {
  340.                 ppCallStmt (indent, (Ast.CallStmt) stmt);
  341.             } else if (stmt instanceof Ast.ReadStmt) {
  342.                 ppReadStmt (indent, (Ast. ReadStmt) stmt);
  343.             } else if (stmt instanceof Ast.WriteStmt) {
  344.                 ppWriteStmt (indent, (Ast.WriteStmt) stmt);
  345.             } else if (stmt instanceof Ast.WhileStmt) {
  346.                 ppWhileStmt (indent, (Ast.WhileStmt) stmt);
  347.             } else if (stmt instanceof Ast.LoopStmt) {
  348.                 ppLoopStmt (indent, (Ast.LoopStmt) stmt);
  349.             } else if (stmt instanceof Ast.ForStmt) {
  350.                 ppForStmt (indent, (Ast.ForStmt) stmt);
  351.             } else if (stmt instanceof Ast.IfStmt) {
  352.                 ppIfStmt (indent, (Ast.IfStmt) stmt);
  353.             } else if (stmt instanceof Ast.ExitStmt) {
  354.                 ppExitStmt (indent, (Ast.ExitStmt) stmt);
  355.             } else if (stmt instanceof Ast.ReturnStmt) {
  356.                 ppReturnStmt (indent, (Ast.ReturnStmt) stmt);
  357.             } else {
  358.                 System.out.print ("*****  Unknown class within ppStmts!  *****");
  359.             }
  360.             stmt = stmt.next;
  361.         }
  362.     }
  363.     
  364.     
  365.     
  366.     //
  367.     // ppAssignStmt (indent, assignStmt)
  368.     //
  369.     // Print the AssignStmt, indented by "indent" spaces.
  370.     //
  371.     void ppAssignStmt (int indent, Ast.AssignStmt p) {
  372.         printIndent (indent);
  373.         ppLValue (p.lValue);
  374.         System.out.print (" :=");
  375.         System.out.print (" ");
  376.         ppExpr (p.expr);
  377.         System.out.println (";");
  378.     }
  379.     
  380.     
  381.     
  382.     //
  383.     // ppCallStmt (indent, callStmt)
  384.     //
  385.     // Print the CallStmt, indented by "indent" spaces.
  386.     //
  387.     void ppCallStmt (int indent, Ast.CallStmt p) {
  388.         printIndent (indent);
  389.         System.out.print (p.id);
  390.         // For testing; feel free to uncomment the following...
  391.         // printMyDef (p.myDef);
  392.         ppArguments (p.args);
  393.         System.out.println (";");
  394.     }
  395.     
  396.     
  397.     
  398.     //
  399.     // ppReadStmt (indent, readStmt)
  400.     //
  401.     // Print the ReadStmt, indented by "indent" spaces.
  402.     //
  403.     void ppReadStmt (int indent, Ast.ReadStmt p) {
  404.         printIndent (indent);
  405.         System.out.print ("READ (");
  406.         ppReadArgs (p.readArgs);
  407.         System.out.println (");");
  408.     }
  409.     
  410.     
  411.     
  412.     //
  413.     // ppReadArgs (readArg)
  414.     //
  415.     // Print the list of ReadArgs.
  416.     //
  417.     void ppReadArgs (Ast.ReadArg p) {
  418.         while (p != null) {
  419.             ppLValue (p.lValue);
  420.             // printMode (p.mode);
  421.             p = p.next;
  422.             if (p != null) {
  423.               System.out.print (", ");
  424.             }
  425.         }
  426.     }
  427.     
  428.     
  429.     
  430.     //
  431.     // ppWriteStmt (indent, writeStmt)
  432.     //
  433.     // Print the WriteStmt, indented by "indent" spaces.
  434.     //
  435.     void ppWriteStmt (int indent, Ast.WriteStmt p) {
  436.         printIndent (indent);
  437.         System.out.print ("WRITE");
  438.         ppArguments (p.args);
  439.         System.out.println (";");
  440.     }
  441.     
  442.     
  443.     
  444.     //
  445.     // ppIfStmt (indent, ifStmt)
  446.     //
  447.     // Print the IfStmt, indented by "indent" spaces.
  448.     //
  449.     void ppIfStmt (int indent, Ast.IfStmt p) {
  450.         printIndent (indent);
  451.         System.out.print ("IF ");
  452.         ppExpr (p.expr);
  453.         System.out.println (" THEN");
  454.         ppStmts (indent + TAB, p.thenStmts);
  455.         if (p.elseStmts != null) {
  456.             printLine (indent, "ELSE");
  457.             ppStmts (indent + TAB, p.elseStmts);
  458.         }
  459.         printLine (indent, "END;");
  460.     }
  461.     
  462.     
  463.     
  464.     //
  465.     // ppWhileStmt (indent, whileStmt)
  466.     //
  467.     // Print the WhileStmt, indented by "indent" spaces.
  468.     //
  469.     void ppWhileStmt (int indent, Ast.WhileStmt p) {
  470.         printIndent (indent);
  471.         // For testing; feel free to uncomment the following...
  472.         // printLabel (p);
  473.         System.out.print ("WHILE ");
  474.         ppExpr (p.expr);
  475.         System.out.println (" DO");
  476.         ppStmts (indent + TAB, p.stmts);
  477.         printLine (indent, "END;");
  478.     }
  479.     
  480.     
  481.     
  482.     //
  483.     // ppLoopStmt (indent, loopStmt)
  484.     //
  485.     // Print the LoopStmt, indented by "indent" spaces.
  486.     //
  487.     void ppLoopStmt (int indent, Ast.LoopStmt p) {
  488.         printIndent (indent);
  489.         // For testing; feel free to uncomment the following...
  490.         // printLabel (p);
  491.         System.out.println ("LOOP");
  492.         ppStmts (indent + TAB, p.stmts);
  493.         printLine (indent, "END;");
  494.     }
  495.     
  496.     
  497.     
  498.     //
  499.     // ppForStmt (indent, forStmt)
  500.     //
  501.     // Print the ForStmt, indented by "indent" spaces.
  502.     //
  503.     void ppForStmt (int indent, Ast.ForStmt p) {
  504.         printIndent (indent);
  505.         // For testing; feel free to uncomment the following...
  506.         // printLabel (p);
  507.         System.out.print ("FOR ");
  508.         ppLValue (p.lValue);
  509.         System.out.print (" := ");
  510.         ppExpr (p.expr1);
  511.         System.out.print (" TO ");
  512.         ppExpr (p.expr2);
  513.         if (p.expr3 != null) {
  514.             System.out.print (" BY ");
  515.             ppExpr (p.expr3);
  516.         }
  517.         System.out.println (" DO");
  518.         ppStmts (indent + TAB, p.stmts);
  519.         printLine (indent, "END;");
  520.     }
  521.     
  522.     
  523.     
  524.     //
  525.     // ppExitStmt (indent, exitStmt)
  526.     //
  527.     // Print the ExitStmt, indented by "indent" spaces.
  528.     //
  529.     void ppExitStmt (int indent, Ast.ExitStmt p) {
  530.         printIndent (indent);
  531.         System.out.print ("EXIT");
  532.         // For testing; feel free to uncomment the following...
  533.         // System.out.print (" [myLoop=");
  534.         // printPtr (p.myLoop);
  535.         // System.out.print ("] ");
  536.         System.out.println (";");
  537.     }
  538.     
  539.     
  540.     
  541.     //
  542.     // ppReturnStmt (indent, returnStmt)
  543.     //
  544.     // Print the ReturnStmt, indented by "indent" spaces.
  545.     //
  546.     void ppReturnStmt (int indent, Ast.ReturnStmt p) {
  547.         printIndent (indent);
  548.         System.out.print ("RETURN");
  549.         if (p.expr != null) {
  550.             System.out.print (" ");
  551.             ppExpr (p.expr);
  552.         }
  553.         // For testing; feel free to uncomment the following...
  554.         // System.out.print (" [myProc=");
  555.         // printPtr (p.myProc);
  556.         // System.out.print ("] ");
  557.         System.out.println (";");
  558.     }
  559.     
  560.     
  561.     
  562.     //
  563.     // ppExpr (p)
  564.     //
  565.     // Print the expression pointed to by "p".
  566.     //
  567.     void ppExpr (Ast.Expr p) {
  568.         if (p instanceof Ast.BinaryOp) {
  569.             ppBinaryOp ((Ast.BinaryOp) p);
  570.         } else if (p instanceof Ast.UnaryOp) {
  571.             ppUnaryOp ((Ast.UnaryOp) p);
  572.         } else if (p instanceof Ast.IntToReal) {
  573.             ppIntToReal ((Ast.IntToReal) p);
  574.         } else if (p instanceof Ast.FunctionCall) {
  575.             ppFunctionCall ((Ast.FunctionCall) p);
  576.         } else if (p instanceof Ast.ArrayConstructor) {
  577.             ppArrayConstructor ((Ast.ArrayConstructor) p);
  578.         } else if (p instanceof Ast.RecordConstructor) {
  579.             ppRecordConstructor ((Ast.RecordConstructor) p);
  580.         } else if (p instanceof Ast.IntegerConst) {
  581.             System.out.print (((Ast.IntegerConst) p).iValue);
  582.         } else if (p instanceof Ast.RealConst) {
  583.             System.out.print (((Ast.RealConst) p).rValue);
  584.         } else if (p instanceof Ast.StringConst) {
  585.             System.out.print ("\"" + ((Ast.StringConst) p).sValue + "\"");
  586.         } else if (p instanceof Ast.BooleanConst) {
  587.             if (((Ast.BooleanConst) p).iValue == 0) {
  588.                 System.out.print ("FALSE");
  589.             } else {
  590.                 System.out.print ("TRUE");
  591.             }
  592.         } else if (p instanceof Ast.NilConst) {
  593.             System.out.print ("NIL");
  594.         } else if (p instanceof Ast.ValueOf) {
  595.             ppValueOf ((Ast.ValueOf) p);
  596.         } else {
  597.             System.out.print ("*****  Unknown class within ppExpr!  *****");
  598.         }
  599.     }
  600.     
  601.     
  602.     
  603.     //
  604.     // ppBinaryOp (binaryOp)
  605.     //
  606.     // Print the BinaryOp.
  607.     //
  608.     void ppBinaryOp (Ast.BinaryOp p) {
  609.         System.out.print ("(");
  610.         ppExpr (p.expr1);
  611.         switch (p.op) {
  612.             case Token.DIV:
  613.               System.out.print (" DIV ");
  614.               break;
  615.             case Token.MOD:
  616.               System.out.print (" MOD ");
  617.               break;
  618.             case Token.OR:
  619.               System.out.print (" OR ");
  620.               break;
  621.             case Token.AND:
  622.               System.out.print (" AND ");
  623.               break;
  624.             case Token.LEQ:
  625.               System.out.print (" <= ");
  626.               break;
  627.             case Token.GEQ:
  628.               System.out.print (" >= ");
  629.               break;
  630.             case Token.NEQ:
  631.               System.out.print (" <> ");
  632.               break;
  633.             case Token.LESS:
  634.               System.out.print (" < ");
  635.               break;
  636.             case Token.GREATER:
  637.               System.out.print (" > ");
  638.               break;
  639.             case Token.EQUAL:
  640.               System.out.print (" = ");
  641.               break;
  642.             case Token.PLUS:
  643.               System.out.print (" + ");
  644.               break;
  645.             case Token.MINUS:
  646.               System.out.print (" - ");
  647.               break;
  648.             case Token.STAR:
  649.               System.out.print (" * ");
  650.               break;
  651.             case Token.SLASH:
  652.               System.out.print (" / ");
  653.               break;
  654.             default:
  655.               System.out.print (" *****  Bad op in ppBinaryOp!  ***** ");
  656.               break;
  657.         }
  658.         // printMode (p.mode);
  659.         ppExpr (p.expr2);
  660.         System.out.print (")");
  661.     }
  662.     
  663.     
  664.     
  665.     //
  666.     // ppUnaryOp (unaryOp)
  667.     //
  668.     // Print the UnaryOp.
  669.     //
  670.     void ppUnaryOp (Ast.UnaryOp p) {
  671.         switch (p.op) {
  672.             case Token.NOT:
  673.               System.out.print ("NOT ");
  674.               break;
  675.             case Token.PLUS:
  676.               System.out.print ("+ ");
  677.               break;
  678.             case Token.MINUS:
  679.               System.out.print ("- ");
  680.               break;
  681.             default:
  682.               System.out.print ("*****  Bad op in ppUnaryOp!  *****");
  683.               break;
  684.         }
  685.         // printMode (p.mode);
  686.         ppExpr (p.expr);
  687.     }
  688.     
  689.     
  690.     
  691.     //
  692.     // ppIntToReal (intToReal)
  693.     //
  694.     // Print the IntToReal.
  695.     //
  696.     void ppIntToReal (Ast.IntToReal p) {
  697.         System.out.print ("intToReal (");
  698.         ppExpr (p.expr);
  699.         System.out.print (")");
  700.     }
  701.     
  702.     
  703.     
  704.     //
  705.     // ppFunctionCall (functionCall)
  706.     //
  707.     // Print the FunctionCall.
  708.     //
  709.     void ppFunctionCall (Ast.FunctionCall p) {
  710.         System.out.print (p.id);
  711.         // For testing; feel free to uncomment the following...
  712.         // printMyDef (p.myDef);
  713.         ppArguments (p.args);
  714.     }
  715.     
  716.     
  717.     
  718.     //
  719.     // ppArguments (p)
  720.     //
  721.     // Print the lists of Arguments pointed to by "p".
  722.     //
  723.     void ppArguments (Ast.Argument p) {
  724.         System.out.print (" (");
  725.         while (p != null) {
  726.             ppExpr (p.expr);
  727.             // printMode (p.mode);
  728.             p = p.next;
  729.             if (p != null) {
  730.                 System.out.print (", ");
  731.             }
  732.         }
  733.         System.out.print (")");
  734.     }
  735.     
  736.     
  737.     
  738.     //
  739.     // ppArrayConstructor (arrayConstructor)
  740.     //
  741.     // Print the ArrayConstructor.
  742.     //
  743.     void ppArrayConstructor (Ast.ArrayConstructor p) {
  744.         System.out.print (p.id);
  745.         // For testing; feel free to uncomment the following...
  746.         // printMyDef (p.myDef);
  747.         System.out.print (" {{ ");
  748.         ppArrayValues (p.values);
  749.         System.out.print (" }}");
  750.     }
  751.     
  752.     
  753.     
  754.     //
  755.     // ppArrayValues (arrayValueList)
  756.     //
  757.     // Print the list of ArrayValues pointed to by "arrayValueList".
  758.     //
  759.     void ppArrayValues (Ast.ArrayValue p) {
  760.         while (p != null) {
  761.             if (p.countExpr != null) {
  762.               ppExpr (p.countExpr);
  763.               System.out.print (" OF ");
  764.             }
  765.             ppExpr (p.valueExpr);
  766.             p = p.next;
  767.             if (p != null) {
  768.               System.out.print (", ");
  769.             }
  770.         }
  771.     }
  772.     
  773.     
  774.     
  775.     //
  776.     // ppRecordConstructor (recordConstructor)
  777.     //
  778.     // Print the RecordConstructor.
  779.     //
  780.     void ppRecordConstructor (Ast.RecordConstructor p) {
  781.         System.out.print (p.id);
  782.         // For testing; feel free to uncomment the following...
  783.         // printMyDef (p.myDef);
  784.         System.out.print (" { ");
  785.         ppFieldInits (p.fieldInits);
  786.         System.out.print (" }");
  787.     }
  788.     
  789.     
  790.     
  791.     //
  792.     // ppFieldInits (fieldInitList)
  793.     //
  794.     // Print the list of FieldInits pointed to by "fieldInitList".
  795.     //
  796.     void ppFieldInits (Ast.FieldInit p) {
  797.         while (p != null) {
  798.             System.out.print (p.id + " := ");
  799.             ppExpr (p.expr);
  800.             p = p.next;
  801.             if (p != null) {
  802.               System.out.print ("; ");
  803.             }
  804.         }
  805.     }
  806.     
  807.     
  808.     
  809.     //
  810.     // ppValueOf (valueOf)
  811.     //
  812.     // Print the ValueOf.
  813.     //
  814.     void ppValueOf (Ast.ValueOf p) {
  815.         // For testing; feel free to uncomment the following...
  816.         // System.out.print ("ValueOf (");
  817.         ppLValue (p.lValue);
  818.         // For testing; feel free to uncomment the following...
  819.         // System.out.print (")");
  820.     }
  821.     
  822.     
  823.     
  824.     //
  825.     // ppLValue (LValue)
  826.     //
  827.     // Print the LValue.
  828.     //
  829.     void ppLValue (Ast.LValue p) {
  830.         if (p instanceof Ast.Variable) {
  831.             ppVariable ((Ast.Variable) p);
  832.         } else if (p instanceof Ast.ArrayDeref) {
  833.             ppArrayDeref ((Ast.ArrayDeref) p);
  834.         } else if (p instanceof Ast.RecordDeref) {
  835.             ppRecordDeref ((Ast.RecordDeref) p);
  836.         } else {
  837.             System.out.print ("*****  Unknown class in ppLValue!  *****");
  838.         }
  839.     }
  840.     
  841.     
  842.     
  843.     //
  844.     // ppVariable (variable)
  845.     //
  846.     // Print the Variable.
  847.     //
  848.     void ppVariable (Ast.Variable p) {
  849.         System.out.print (p.id);
  850.         // For testing; feel free to uncomment the following...
  851.         // printMyDef (p.myDef);
  852.         // For testing; feel free to uncomment the following...
  853.         // System.out.print (" [currLev=" + p.currentLevel + "] ");
  854.     }
  855.     
  856.     
  857.     
  858.     //
  859.     // ppArrayDeref (arrayDeref)
  860.     //
  861.     // Print the ArrayDeref.
  862.     //
  863.     void ppArrayDeref (Ast.ArrayDeref p) {
  864.         ppLValue (p.lValue);
  865.         System.out.print ("[");
  866.         ppExpr (p.expr);
  867.         System.out.print ("]");
  868.     }
  869.     
  870.     
  871.     
  872.     //
  873.     // ppRecordDeref (recordDeref)
  874.     //
  875.     // Print the RecordDeref.
  876.     //
  877.     void ppRecordDeref (Ast.RecordDeref p) {
  878.         ppLValue (p.lValue);
  879.         System.out.print ("." + p.id);
  880.     }
  881.     
  882.     
  883.     
  884.     //
  885.     // printIndent (indent)
  886.     //
  887.     // This method prints "indent" space characters.
  888.     //
  889.     void printIndent (int indent) {
  890.         for (int i=indent; i>0; i--) {
  891.             System.out.print (" ");
  892.         }
  893.     }
  894.     
  895.     
  896.     
  897.     //
  898.     // printLine (indent, str)
  899.     //
  900.     // This method indents, then prints the given string, then prints newline.
  901.     //
  902.     void printLine (int indent, String str) {
  903.         printIndent (indent);
  904.         System.out.println (str);
  905.     }
  906.  
  907.  
  908.  
  909.     //
  910.     // printPtr (p)
  911.     //
  912.     // This method is passed a pointer, possibly null.  It prints the pointer.
  913.     // The actual address is not printed, since these may vary from run to run.
  914.     // Instead, this method assigns "labels" to each address and prints the
  915.     // same label each time.  It saves the mapping between label and address
  916.     // in a static hashMap called "ptrMap".
  917.     //
  918.     void printPtr (Ast.Node p) {
  919.         int i;
  920.  
  921.         // If the pointer is null, then print "NULL"...
  922.         if (p == null) {
  923.             System.out.print ("NULL");
  924.             return;
  925.         }
  926.  
  927.         // Figure out what integer goes with this ptr...
  928.         Integer val = (Integer) ptrMap.get (p);
  929.         if (val != null) {
  930.           i = val.intValue ();
  931.         } else {
  932.           i = nextLabel++;
  933.           ptrMap.put (p, new Integer (i));
  934.         }
  935.  
  936.         // Print the number...
  937.         System.out.print ("#");
  938.         System.out.print (i);
  939.     }
  940.     
  941.     
  942.     
  943.     //
  944.     // printLabel (p)
  945.     //
  946.     // This method prints something like " [#123:] "
  947.     //
  948.     void printLabel (Ast.Node p) {
  949.         System.out.print (" [");
  950.         printPtr (p);
  951.         System.out.print (":] ");
  952.     }
  953.     
  954.     
  955.     
  956.     //
  957.     // printMyDef (p)
  958.     //
  959.     // This method prints something like " [myDef=#123] "
  960.     //
  961.     void printMyDef (Ast.Node p) {
  962.         System.out.print (" [myDef=");
  963.         printPtr (p);
  964.         System.out.print ("] ");
  965.     }
  966.  
  967.  
  968.  
  969.     // printMode (m)
  970.     //
  971.     // Print something like "[mode=INTEGER] " to indicate the value of argument m.
  972.     //
  973.     void printMode (int m) {
  974.         final int INTEGER_MODE = 1;
  975.         final int REAL_MODE = 2;
  976.         final int STRING_MODE = 3;
  977.         final int BOOLEAN_MODE = 4;
  978.         switch (m) {
  979.             case INTEGER_MODE:
  980.                 System.out.print ("[mode=INTEGER] ");
  981.                 break;
  982.             case REAL_MODE:
  983.                 System.out.print ("[mode=REAL] ");
  984.                 break;
  985.             case BOOLEAN_MODE:
  986.                 System.out.print ("[mode=BOOLEAN] ");
  987.                 break;
  988.             case STRING_MODE:
  989.                 System.out.print ("[mode=STRING] ");
  990.                 break;
  991.             case 0:
  992.                 System.out.print ("[mode=0] ");
  993.                 break;
  994.             default:
  995.                 System.out.print ("[mode=***** Garbage *****] ");
  996.                 break;
  997.         }
  998.     }
  999.  
  1000. }