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 / Blitz / version-1-0 / BlitzSrc / kpl / printAst.cc < prev   
C/C++ Source or Header  |  2006-09-25  |  44KB  |  1,407 lines

  1. // printAst.cc  --  Routines to print the Abstract Syntax Tree
  2. //
  3. // KPL Compiler
  4. //
  5. // Copyright 2002-2006, Harry H. Porter III
  6. //
  7. // This file may be freely copied, modified and compiled, on the sole
  8. // condition that if you modify it...
  9. //   (1) Your name and the date of modification is added to this comment
  10. //       under "Modifications by", and
  11. //   (2) Your name and the date of modification is added to the printHelp()
  12. //       routine in file "main.cc" under "Modifications by".
  13. //
  14. // Original Author:
  15. //   06/15/02 - Harry H. Porter III
  16. //
  17. // Modifcations by:
  18. //   03/15/06 - Harry H. Porter III
  19. //
  20. // This file contains a routine "printAst()" which can be called to print
  21. // out an Abstract Syntax Tree (AST).  It can be invoked as follows:
  22. //
  23. //     AstNode *p = ... ;
  24. //     ...
  25. //     printAst (6, p);
  26. //
  27.  
  28. #include "main.h"
  29.  
  30.  
  31.  
  32. #define TABAMT 2
  33.  
  34.  
  35.  
  36. // printAst (indent, p)
  37. //
  38. // This routine prints the abstract syntax tree pointed to by p.
  39. // The tree is printed with "indent" characters of indentation.
  40. // Initially, it should be called with an "indent" of about 6 to
  41. // allow enough space to print the #999: labels.
  42. //
  43. void printAst (int indent, AstNode *p) {
  44.  
  45.     Header * header;
  46.     Code * code;
  47.     Uses * uses;
  48.     Renaming * renaming;
  49.     Interface * interface;
  50.     ClassDef * cl;
  51.     Behavior * behavior;
  52.     TypeDef * typeDef;
  53.     ConstDecl * constDecl;
  54.     ErrorDecl * errorDecl;
  55.     FunctionProto * functionProto;
  56.     Function * fun;
  57.     MethodProto * methodProto;
  58.     Method * meth;
  59.     TypeParm * typeParm;
  60.     TypeArg * typeArg;
  61.     CharType * charType;
  62.     IntType * intType;
  63.     DoubleType * doubleType;
  64.     BoolType * boolType;
  65.     VoidType * voidType;
  66.     TypeOfNullType * typeOfNullType;
  67.     AnyType * anyType;
  68.     PtrType * pType;
  69.     ArrayType * aType;
  70.     RecordType * rType;
  71.     FunctionType * fType;
  72.     NamedType * nType;
  73.     IfStmt * ifStmt;
  74.     AssignStmt * assignStmt;
  75.     CallStmt * callStmt;
  76.     SendStmt * sendStmt;
  77.     WhileStmt * whileStmt;
  78.     DoStmt * doStmt;
  79.     BreakStmt * breakStmt;
  80.     ContinueStmt * continueStmt;
  81.     ReturnStmt * returnStmt;
  82.     ForStmt * forStmt;
  83.     SwitchStmt * switchStmt;
  84.     TryStmt * tryStmt;
  85.     ThrowStmt * throwStmt;
  86.     FreeStmt * freeStmt;
  87.     DebugStmt * debugStmt;
  88.     Case * cas;
  89.     Catch * cat;
  90.     Global * global;
  91.     Local * local;
  92.     Parameter * parm;
  93.     ClassField * classField;
  94.     RecordField * recordField;
  95.     IntConst * intConst;
  96.     DoubleConst * doubleConst;
  97.     CharConst * charConst;
  98.     StringConst * stringConst;
  99.     BoolConst * boolConst;
  100.     NullConst * nullConst;
  101.     CallExpr * callExpr;
  102.     SendExpr * sendExpr;
  103.     SelfExpr * selfExpr;
  104.     SuperExpr * superExpr;
  105.     FieldAccess * fieldAccess;
  106.     ArrayAccess * arrayAccess;
  107.     Constructor * constructor;
  108.     ClosureExpr * closureExpr;
  109.     VariableExpr * var;
  110.     AsPtrToExpr * asPtrToExpr;
  111.     AsIntegerExpr * asIntegerExpr;
  112.     ArraySizeExpr * arraySizeExpr;
  113.     IsInstanceOfExpr * isInstanceOfExpr;
  114.     IsKindOfExpr * isKindOfExpr;
  115.     SizeOfExpr * sizeOfExpr;
  116.     DynamicCheck * dynamicCheck;
  117.     Argument * arg;
  118.     CountValue * countValue;
  119.     FieldInit * fieldInit;
  120.  
  121.  
  122.   if (p==NULL) {
  123.     printLine (indent, "NULL");
  124.     return;
  125.   }
  126.  
  127.   printHeader (indent, symbolName (p->op), p);
  128.  
  129.   switch (p->op) {
  130.  
  131.     case HEADER:
  132.       header = (Header *) p;
  133.       printStringField (indent, "packageName:", header->packageName);
  134.       printItem (indent, "uses:", header->uses);
  135.       printItem (indent, "consts:", header->consts);
  136.       printItem (indent, "errors:", header->errors);
  137.       printItem (indent, "globals:", header->globals);
  138.       printItem (indent, "typeDefs:", header->typeDefs);
  139.       printItem (indent, "functionProtos:", header->functionProtos);
  140.       printItem (indent, "functions:", header->functions);
  141.       printItem (indent, "closures:", header->closures);
  142.       printItem (indent, "interfaces:", header->interfaces);
  143.       printItem (indent, "classes:", header->classes);
  144.       printIntField (indent, "hashVal:", header->hashVal);
  145.       printIndent (indent);
  146.       printf ("packageMapping:\n");
  147.       if (header->packageMapping != NULL) {
  148.         header->packageMapping->print (indent+2);
  149.       } else {
  150.         printf ("NULL\n");
  151.       }
  152.       printIndent (indent);
  153.       printf ("errorMapping:\n");
  154.       if (header->errorMapping != NULL) {
  155.         header->errorMapping->print (indent+2);
  156.       } else {
  157.         printf ("NULL\n");
  158.       }
  159.       printFooter (indent);
  160.       if (header->next) {
  161.         printAst (indent, header->next);
  162.       }
  163.       break;
  164.     case CODE:
  165.       code = (Code *) p;
  166.       printStringField (indent, "packageName:", code->packageName);
  167.       printItem (indent, "consts:", code->consts);
  168.       printItem (indent, "errors:", code->errors);
  169.       printItem (indent, "globals:", code->globals);
  170.       printItem (indent, "typeDefs:", code->typeDefs);
  171.       printItem (indent, "functions:", code->functions);
  172.       printItem (indent, "interfaces:", code->interfaces);
  173.       printItem (indent, "classes:", code->classes);
  174.       printItem (indent, "behaviors:", code->behaviors);
  175.       printIntField (indent, "hashVal:", code->hashVal);
  176.       printFooter (indent);
  177.       break;
  178.     case USES:
  179.       uses = (Uses *) p;
  180.       printId (indent, uses->id);
  181.       printPtrField (indent, "myDef:", uses-> myDef);
  182.       printItem (indent, "renamings:", uses->renamings);
  183.       printFooter (indent);
  184.       if (uses->next) {
  185.         printAst (indent, uses->next);
  186.       }
  187.       break;
  188.     case RENAMING:
  189.       renaming = (Renaming *) p;
  190.       printStringField (indent, "from:", renaming->from);
  191.       printStringField (indent, "to:", renaming->to);
  192.       printFooter (indent);
  193.       if (renaming->next) {
  194.         printAst (indent, renaming->next);
  195.       }
  196.       break;
  197.     case INTERFACE:
  198.       interface = (Interface *) p;
  199.       printId (indent, interface->id);
  200.       printCharPtrField (indent, "newName:", interface->newName);
  201.       printBoolField (indent, "isPrivate:", interface->isPrivate);
  202.       printItem (indent, "typeParms:", interface->typeParms);
  203.       printItem (indent, "extends:", interface->extends);
  204.       printItem (indent, "methodProtos:", interface->methodProtos);
  205.       printIntField (indent, "mark:", interface->mark);
  206.       printPtrField (indent, "myHeader:", interface->myHeader);
  207.       printPtrField (indent, "tempNext:", interface->tempNext);
  208.       printIndent (indent+2);
  209.       printf ("selectorMapping: \n");
  210.       if (interface->selectorMapping) {
  211.         interface->selectorMapping->print (indent+4);
  212.       } else {
  213.         printf ("NULL\n");
  214.       }
  215.       printItem (indent, "inheritedMethodProtos:", interface->inheritedMethodProtos);
  216.       printFooter (indent);
  217.       if (interface->next) {
  218.         printAst (indent, interface->next);
  219.       }
  220.       break;
  221.     case CLASS_DEF:
  222.       cl = (ClassDef *) p;
  223.       printId (indent, cl->id);
  224.       printCharPtrField (indent, "newName:", cl->newName);
  225.       printBoolField (indent, "isPrivate:", cl->isPrivate);
  226.       printIntField (indent, "mark:", cl->mark);
  227.       printIntField (indent, "sizeInBytes:", cl->sizeInBytes);
  228.       printPtrField (indent, "myHeader:", cl->myHeader);
  229.       printPtrField (indent, "tempNext:", cl->tempNext);
  230.       printPtrField (indent, "superclassDef:", cl->superclassDef);
  231.       printItem (indent, "typeParms:", cl->typeParms);
  232.       printItem (indent, "typeOfSelf:", cl->typeOfSelf);
  233.       printItem (indent, "implements:", cl->implements);
  234.       printItem (indent, "superclass:", cl->superclass);
  235.       printItem (indent, "fields:", cl->fields);
  236.       printItem (indent, "methodProtos:", cl->methodProtos);
  237.       printItem (indent, "methods:", cl->methods);
  238. /***
  239.       printIndent (indent+2);
  240.       printf ("superclassMapping: \n");
  241.       if (cl->superclassMapping) {
  242.         cl->superclassMapping->print (indent+4);
  243.       } else {
  244.         printf ("NULL\n");
  245.       }
  246.       printIndent (indent+2);
  247.       printf ("classMapping: \n");
  248.       if (cl->classMapping) {
  249.         cl->classMapping->print (indent+4);
  250.       } else {
  251.         printf ("NULL\n");
  252.       }
  253. ***/
  254.       printIndent (indent+2);
  255.       printf ("localMethodMapping: \n");
  256.       if (cl-> localMethodMapping) {
  257.         cl-> localMethodMapping->print (indent+4);
  258.       } else {
  259.         printf ("NULL\n");
  260.       }
  261.       printIndent (indent+2);
  262.       printf ("selectorMapping: \n");
  263.       if (cl->selectorMapping) {
  264.         cl-> selectorMapping->print (indent+4);
  265.       } else {
  266.         printf ("NULL\n");
  267.       }
  268. /***
  269.       printIndent (indent+2);
  270.       printf ("knownSubAbstracts: \n");
  271.       if (cl->knownSubAbstracts) {
  272.         cl->knownSubAbstracts->print (indent+4);
  273.       } else {
  274.         printf ("NULL\n");
  275.       }
  276.  
  277.       printIndent (indent+2);
  278.       printf ("superAbstractsInThisPackage: \n");
  279.       if (cl->superAbstractsInThisPackage) {
  280.         cl->superAbstractsInThisPackage->print (indent+4);
  281.       } else {
  282.         printf ("NULL\n");
  283.       }
  284.  
  285.       printIndent (indent+2);
  286.       printf ("supersAbstractsInOtherPackages: \n");
  287.       if (cl->supersAbstractsInOtherPackages) {
  288.         cl->supersAbstractsInOtherPackages->print (indent+4);
  289.       } else {
  290.         printf ("NULL\n");
  291.       }
  292.  
  293. ***/
  294.       printFooter (indent);
  295.       if (cl->next) {
  296.         printAst (indent, cl->next);
  297.       }
  298.       break;
  299.     case BEHAVIOR:
  300.       behavior = (Behavior *) p;
  301.       printId (indent, behavior->id);
  302.       printItem (indent, "methods:", behavior->methods);
  303.       printFooter (indent);
  304.       if (behavior->next) {
  305.         printAst (indent, behavior->next);
  306.       }
  307.       break;
  308.     case TYPE_DEF:
  309.       typeDef = (TypeDef *) p;
  310.       printId (indent, typeDef->id);
  311.       printIntField (indent, "mark:", typeDef->mark);
  312.       printItem (indent, "type:", typeDef->type);
  313.       printFooter (indent);
  314.       if (typeDef->next) {
  315.         printAst (indent, typeDef->next);
  316.       }
  317.       break;
  318.     case CONST_DECL:
  319.       constDecl = (ConstDecl *) p;
  320.       printId (indent, constDecl->id);
  321.       printItem (indent, "expr:", constDecl->expr);
  322.       printBoolField (indent, "isPrivate:", constDecl->isPrivate);
  323.       printFooter (indent);
  324.       if (constDecl->next) {
  325.         printAst (indent, constDecl->next);
  326.       }
  327.       break;
  328.     case ERROR_DECL:
  329.       errorDecl = (ErrorDecl *) p;
  330.       printId (indent, errorDecl->id);
  331.       printCharPtrField (indent, "newName:", errorDecl->newName);
  332.       printIntField (indent, "totalParmSize:", errorDecl->totalParmSize);
  333.       printItem (indent, "parmList:", errorDecl->parmList);
  334.       // printBoolField (indent, "isPrivate:", errorDecl->isPrivate);
  335.       printFooter (indent);
  336.       if (errorDecl->next) {
  337.         printAst (indent, errorDecl->next);
  338.       }
  339.       break;
  340.     case FUNCTION_PROTO:
  341.       functionProto = (FunctionProto *) p;
  342.       printCharPtrField (indent, "newName:", functionProto->newName);
  343.       printBoolField (indent, "isExternal:", functionProto->isExternal);
  344.       printBoolField (indent, "isPrivate:", functionProto->isPrivate);
  345.       printPtrField (indent, "myFunction:", functionProto->myFunction);
  346.       printPtrField (indent, "myHeader:", functionProto->myHeader);
  347.       printId (indent, functionProto->id);
  348.       printItem (indent, "parmList:", functionProto->parmList);
  349.       printItem (indent, "retType:", functionProto->retType);
  350.       printIntField (indent, "totalParmSize:", functionProto->totalParmSize);
  351.       printIntField (indent, "retSize:", functionProto->retSize);
  352.       printFooter (indent);
  353.       if (functionProto->next) {
  354.         printAst (indent, functionProto->next);
  355.       }
  356.       break;
  357.     case METHOD_PROTO:
  358.       methodProto = (MethodProto *) p;
  359.       printSymbolField (indent, "kind:", methodProto->kind);
  360.       printStringField (indent, "selector:", methodProto-> selector);
  361.       printPtrField (indent, "myMethod:", methodProto->myMethod);
  362.       printItem (indent, "parmList:", methodProto->parmList);
  363.       printItem (indent, "retType:", methodProto->retType);
  364.       printIntField (indent, "totalParmSize:", methodProto->totalParmSize);
  365.       printIntField (indent, "retSize:", methodProto->retSize);
  366.       printIntField (indent, "offset:", methodProto->offset);
  367.       printFooter (indent);
  368.       if (methodProto->next) {
  369.         printAst (indent, methodProto->next);
  370.       }
  371.       break;
  372.     case FUNCTION:
  373.       fun = (Function *) p;
  374.       printId (indent, fun->id);
  375.       printCharPtrField (indent, "newName:", fun->newName);
  376.       printPtrField (indent, "myProto:", fun->myProto);
  377.       printPtrField (indent, "catchList:", fun->catchList);
  378.       printIntField (indent, "frameSize:", fun->frameSize);
  379.       printIntField (indent, "maxArgBytes:", fun->maxArgBytes);
  380.       printIntField (indent, "totalParmSize:", fun->totalParmSize);
  381.       printBoolField (indent, "containsTry:", fun->containsTry);
  382.       printItem (indent, "catchStackSave:", fun->catchStackSave);
  383.       printItem (indent, "parmList:", fun->parmList);
  384.       printItem (indent, "retType:", fun->retType);
  385.       printItem (indent, "locals:", fun->locals);
  386.       printItem (indent, "stmts:", fun->stmts);
  387.       printFooter (indent);
  388.       if (fun->next) {
  389.         printAst (indent, fun->next);
  390.       }
  391.       break;
  392.     case METHOD:
  393.       meth = (Method *) p;
  394.       printSymbolField (indent, "kind:", meth->kind);
  395.       printStringField (indent, "selector:", meth->selector);
  396.       printCharPtrField (indent, "newName:", meth->newName);
  397.       printPtrField (indent, "myMethodProto:", meth->myMethodProto);
  398.       printPtrField (indent, "myClass:", meth->myClass);
  399.       printPtrField (indent, "catchList:", meth->catchList);
  400.       printIntField (indent, "frameSize:", meth->frameSize);
  401.       printIntField (indent, "maxArgBytes:", meth->maxArgBytes);
  402.       printIntField (indent, "totalParmSize:", meth->totalParmSize);
  403.       printBoolField (indent, "containsTry:", meth->containsTry);
  404.       printItem (indent, "catchStackSave:", meth->catchStackSave);
  405.       printItem (indent, "parmList:", meth->parmList);
  406.       printItem (indent, "retType:", meth->retType);
  407.       printItem (indent, "locals:", meth->locals);
  408.       printItem (indent, "stmts:", meth->stmts);
  409.       printFooter (indent);
  410.       if (meth->next) {
  411.         printAst (indent, meth->next);
  412.       }
  413.       break;
  414.     case TYPE_PARM:
  415.       typeParm = (TypeParm *) p;
  416.       printId (indent, typeParm->id);
  417.       printBoolField (indent, "fourByteRestricted:", typeParm->fourByteRestricted);
  418.       printItem (indent, "type:", typeParm->type);
  419.       printFooter (indent);
  420.       if (typeParm->next) {
  421.         printAst (indent, typeParm->next);
  422.       }
  423.       break;
  424.     case TYPE_ARG:
  425.       typeArg = (TypeArg *) p;
  426.       printIntField (indent, "offset:", typeArg->offset);
  427.       printIntField (indent, "sizeInBytes:", typeArg->sizeInBytes);
  428.       printItem (indent, "type:", typeArg->type);
  429.       printFooter (indent);
  430.       if (typeArg->next) {
  431.         printAst (indent, typeArg->next);
  432.       }
  433.       break;
  434.     case CHAR_TYPE:
  435.       charType = (CharType *) p;
  436.       printFooter (indent);
  437.       break;
  438.     case INT_TYPE:
  439.       intType = (IntType *) p;
  440.       printFooter (indent);
  441.       break;
  442.     case DOUBLE_TYPE:
  443.       doubleType = (DoubleType *) p;
  444.       printFooter (indent);
  445.       break;
  446.     case BOOL_TYPE:
  447.       boolType = (BoolType *) p;
  448.       printFooter (indent);
  449.       break;
  450.     case VOID_TYPE:
  451.       voidType = (VoidType *) p;
  452.       printFooter (indent);
  453.       break;
  454.     case TYPE_OF_NULL_TYPE:
  455.       typeOfNullType = (TypeOfNullType *) p;
  456.       printFooter (indent);
  457.       break;
  458.     case ANY_TYPE:
  459.       anyType = (AnyType *) p;
  460.       printFooter (indent);
  461.       break;
  462.     case PTR_TYPE:
  463.       pType = (PtrType *) p;
  464.       printItem (indent, "baseType:", pType->baseType);
  465.       printFooter (indent);
  466.       break;
  467.     case ARRAY_TYPE:
  468.       aType = (ArrayType *) p;
  469.       printIntField (indent, "sizeInBytes:", aType->sizeInBytes);
  470.       printIntField (indent, "sizeOfElements:", aType->sizeOfElements);
  471.       printItem (indent, "sizeExpr:", aType->sizeExpr);
  472.       printItem (indent, "baseType:", aType->baseType);
  473.       printFooter (indent);
  474.       break;
  475.     case RECORD_TYPE:
  476.       rType = (RecordType *) p;
  477.       printIntField (indent, "sizeInBytes:", rType->sizeInBytes);
  478.       printItem (indent, "fields:", rType->fields);
  479.       printIndent (indent+2);
  480.       printf ("fieldMapping: \n");
  481.       if (rType-> fieldMapping) {
  482.         rType-> fieldMapping->print (indent+4);
  483.       } else {
  484.         printf ("NULL\n");
  485.       }
  486.       printFooter (indent);
  487.       break;
  488.     case FUNCTION_TYPE:
  489.       fType = (FunctionType *) p;
  490.       printItem (indent, "parmTypes:", fType-> parmTypes);
  491.       printItem (indent, "retType:", fType-> retType);
  492.       printIntField (indent, "totalParmSize:", fType->totalParmSize);
  493.       printIntField (indent, "retSize:", fType->retSize);
  494.       printFooter (indent);
  495.       break;
  496.     case NAMED_TYPE:
  497.       nType = (NamedType *) p;
  498.       printId (indent, nType->id);
  499.       printItem (indent, "typeArgs:", nType-> typeArgs);
  500.       printPtrField (indent, "myDef:", nType->myDef);
  501.       printIndent (indent+2);
  502.       printf ("subst: ");
  503.       if (nType->subst) {
  504.         printf ("...\n");
  505.         // printf ("\n");
  506.         // nType->subst->print (indent+4);
  507.       } else {
  508.         printf ("NULL\n");
  509.       }
  510.       printFooter (indent);
  511.       break;
  512.     case IF_STMT:
  513.       ifStmt = (IfStmt *) p;
  514.       printItem (indent, "expr:", ifStmt->expr);
  515.       printItem (indent, "thenStmts:", ifStmt->thenStmts);
  516.       printItem (indent, "elseStmts:", ifStmt->elseStmts);
  517.       printFooter (indent);
  518.       if (ifStmt->next) {
  519.         printAst (indent, ifStmt->next);
  520.       }
  521.       break;
  522.     case ASSIGN_STMT:
  523.       assignStmt = (AssignStmt *) p;
  524.       printIntField (indent, "sizeInBytes:", assignStmt->sizeInBytes);
  525.       printIntField (indent, "dynamicCheck:", assignStmt->dynamicCheck);
  526.       printPtrField (indent, "classDef:", assignStmt->classDef);
  527.       printIntField (indent, "arraySize:", assignStmt->arraySize);
  528.       printItem (indent, "lvalue:", assignStmt->lvalue);
  529.       printItem (indent, "expr:", assignStmt->expr);
  530.       printFooter (indent);
  531.       if (assignStmt->next) {
  532.         printAst (indent, assignStmt->next);
  533.       }
  534.       break;
  535.     case CALL_STMT:
  536.       callStmt = (CallStmt *) p;
  537.       printItem (indent, "expr:", callStmt->expr);
  538.       printFooter (indent);
  539.       if (callStmt->next) {
  540.         printAst (indent, callStmt->next);
  541.       }
  542.       break;
  543.     case SEND_STMT:
  544.       sendStmt = (SendStmt *) p;
  545.       printItem (indent, "expr:", sendStmt->expr);
  546.       printFooter (indent);
  547.       if (sendStmt->next) {
  548.         printAst (indent, sendStmt->next);
  549.       }
  550.       break;
  551.     case WHILE_STMT:
  552.       whileStmt = (WhileStmt *) p;
  553.       printCharPtrField (indent, "topLabel:", whileStmt->topLabel);
  554.       printCharPtrField (indent, "exitLabel:", whileStmt->exitLabel);
  555.       printItem (indent, "expr:", whileStmt->expr);
  556.       printItem (indent, "stmts:", whileStmt->stmts);
  557.       printBoolField (indent, "containsAnyBreaks:", whileStmt->containsAnyBreaks);
  558.       printBoolField (indent, "containsAnyContinues:", whileStmt->containsAnyContinues);
  559.       printFooter (indent);
  560.       if (whileStmt->next) {
  561.         printAst (indent, whileStmt->next);
  562.       }
  563.       break;
  564.     case DO_STMT:
  565.       doStmt = (DoStmt *) p;
  566.       printCharPtrField (indent, "exitLabel:", doStmt->exitLabel);
  567.       printCharPtrField (indent, "testLabel:", doStmt->testLabel);
  568.       printItem (indent, "stmts:", doStmt->stmts);
  569.       printItem (indent, "expr:", doStmt->expr);
  570.       printBoolField (indent, "containsAnyBreaks:", doStmt->containsAnyBreaks);
  571.       printBoolField (indent, "containsAnyContinues:", doStmt->containsAnyContinues);
  572.       printFooter (indent);
  573.       if (doStmt->next) {
  574.         printAst (indent, doStmt->next);
  575.       }
  576.       break;
  577.     case BREAK_STMT:
  578.       breakStmt = (BreakStmt *) p;
  579.       printPtrField (indent, "enclosingStmt:", breakStmt->enclosingStmt);
  580.       printFooter (indent);
  581.       if (breakStmt->next) {
  582.         printAst (indent, breakStmt->next);
  583.       }
  584.       break;
  585.     case CONTINUE_STMT:
  586.       continueStmt = (ContinueStmt *) p;
  587.       printPtrField (indent, "enclosingStmt:", continueStmt->enclosingStmt);
  588.       printFooter (indent);
  589.       if (continueStmt->next) {
  590.         printAst (indent, continueStmt->next);
  591.       }
  592.       break;
  593.     case RETURN_STMT:
  594.       returnStmt = (ReturnStmt *) p;
  595.       printItem (indent, "expr:", returnStmt->expr);
  596.       printPtrField (indent, "enclosingMethOrFunction:",
  597.                              returnStmt-> enclosingMethOrFunction);
  598.       printIntField (indent, "retSize:", returnStmt->retSize);
  599.       printFooter (indent);
  600.       if (returnStmt->next) {
  601.         printAst (indent, returnStmt->next);
  602.       }
  603.       break;
  604.     case FOR_STMT:
  605.       forStmt = (ForStmt *) p;
  606.       printCharPtrField (indent, "incrLabel:", forStmt->incrLabel);
  607.       printCharPtrField (indent, "exitLabel:", forStmt->exitLabel);
  608.       printItem (indent, "lvalue:", forStmt->lvalue);
  609.       printItem (indent, "expr1:", forStmt->expr1);
  610.       printItem (indent, "expr2:", forStmt->expr2);
  611.       printItem (indent, "expr3:", forStmt->expr3);
  612.       printItem (indent, "stmts:", forStmt->stmts);
  613.       printBoolField (indent, "containsAnyBreaks:", forStmt->containsAnyBreaks);
  614.       printBoolField (indent, "containsAnyContinues:", forStmt->containsAnyContinues);
  615.       printFooter (indent);
  616.       if (forStmt->next) {
  617.         printAst (indent, forStmt->next);
  618.       }
  619.       break;
  620.     case SWITCH_STMT:
  621.       switchStmt = (SwitchStmt *) p;
  622.       printBoolField (indent, "containsAnyBreaks:", switchStmt->containsAnyBreaks);
  623.       printBoolField (indent, "defaultIncluded:", switchStmt->defaultIncluded);
  624.       printIntField (indent, "lowValue:", switchStmt->lowValue);
  625.       printIntField (indent, "highValue:", switchStmt->highValue);
  626.       printCharPtrField (indent, "exitLabel:", switchStmt->exitLabel);
  627.       printItem (indent, "expr:", switchStmt->expr);
  628.       printItem (indent, "caseList:", switchStmt-> caseList);
  629.       printItem (indent, "defaultStmts:", switchStmt-> defaultStmts);
  630.       printFooter (indent);
  631.       if (switchStmt->next) {
  632.         printAst (indent, switchStmt->next);
  633.       }
  634.       break;
  635.     case TRY_STMT:
  636.       tryStmt = (TryStmt *) p;
  637.       printItem (indent, "stmts:", tryStmt->stmts);
  638.       printItem (indent, "catchList:", tryStmt-> catchList);
  639.       printFooter (indent);
  640.       if (tryStmt->next) {
  641.         printAst (indent, tryStmt->next);
  642.       }
  643.       break;
  644.     case THROW_STMT:
  645.       throwStmt = (ThrowStmt *) p;
  646.       printId (indent, throwStmt->id);
  647.       printPtrField (indent, "myDef:", throwStmt->myDef);
  648.       printItem (indent, "argList:", throwStmt->argList);
  649.       printFooter (indent);
  650.       if (throwStmt->next) {
  651.         printAst (indent, throwStmt->next);
  652.       }
  653.       break;
  654.     case FREE_STMT:
  655.       freeStmt = (FreeStmt *) p;
  656.       printItem (indent, "expr:", freeStmt->expr);
  657.       printFooter (indent);
  658.       if (freeStmt->next) {
  659.         printAst (indent, freeStmt->next);
  660.       }
  661.       break;
  662.     case DEBUG_STMT:
  663.       debugStmt = (DebugStmt *) p;
  664.       printFooter (indent);
  665.       if (debugStmt->next) {
  666.         printAst (indent, debugStmt->next);
  667.       }
  668.       break;
  669.     case CASE:
  670.       cas = (Case *) p;
  671.       printIntField (indent, "ivalue:", cas->ivalue);
  672.       printCharPtrField (indent, "label:", cas->label);
  673.       printItem (indent, "expr:", cas->expr);
  674.       printItem (indent, "stmts:", cas-> stmts);
  675.       printFooter (indent);
  676.       if (cas->next) {
  677.         printAst (indent, cas->next);
  678.       }
  679.       break;
  680.     case CATCH:
  681.       cat = (Catch *) p;
  682.       printId (indent, cat->id);
  683.       printCharPtrField (indent, "label:", cat->label);
  684.       printPtrField (indent, "nextInMethOrFunction:", cat->nextInMethOrFunction);
  685.       printPtrField (indent, "myDef:", cat->myDef);
  686.       printPtrField (indent, "enclosingMethOrFunction:", cat->enclosingMethOrFunction);
  687.       printItem (indent, "parmList:", cat->parmList);
  688.       printItem (indent, "stmts:", cat-> stmts);
  689.       printFooter (indent);
  690.       if (cat->next) {
  691.         printAst (indent, cat->next);
  692.       }
  693.       break;
  694.     case GLOBAL:
  695.       global = (Global *) p;
  696.       printId (indent, global->id);
  697.       printIntField (indent, "sizeInBytes:", global->sizeInBytes);
  698.       printBoolField (indent, "isPrivate:", global->isPrivate);
  699.       printItem (indent, "type:", global->type);
  700.       printItem (indent, "initExpr:", global->initExpr);
  701.       printFooter (indent);
  702.       if (global->next) {
  703.         printAst (indent, global->next);
  704.       }
  705.       break;
  706.     case LOCAL:
  707.       local = (Local *) p;
  708.       printId (indent, local->id);
  709.       printIntField (indent, "offset:", local->offset);
  710.       printIntField (indent, "sizeInBytes:", local->sizeInBytes);
  711.       printCharPtrField (indent, "varDescLabel:", local->varDescLabel);
  712.       printItem (indent, "type:", local->type);
  713.       printItem (indent, "initExpr:", local->initExpr);
  714.       printBoolField (indent, "wasUsed:", local->wasUsed);
  715.       printFooter (indent);
  716.       if (local->next) {
  717.         printAst (indent, local->next);
  718.       }
  719.       break;
  720.     case PARAMETER:
  721.       parm = (Parameter *) p;
  722.       printId (indent, parm->id);
  723.       printIntField (indent, "offset:", parm->offset);
  724.       printIntField (indent, "throwSideOffset:", parm->throwSideOffset);
  725.       printIntField (indent, "sizeInBytes:", parm->sizeInBytes);
  726.       printCharPtrField (indent, "varDescLabel:", parm->varDescLabel);
  727.       printItem (indent, "type:", parm->type);
  728.       printFooter (indent);
  729.       if (parm->next) {
  730.         printAst (indent, parm->next);
  731.       }
  732.       break;
  733.     case CLASS_FIELD:
  734.       classField = (ClassField *) p;
  735.       printId (indent, classField->id);
  736.       printIntField (indent, "offset:", classField->offset);
  737.       printIntField (indent, "sizeInBytes:", classField->sizeInBytes);
  738.       printCharPtrField (indent, "varDescLabel:", classField->varDescLabel);
  739.       printItem (indent, "type:", classField->type);
  740.       printFooter (indent);
  741.       if (classField->next) {
  742.         printAst (indent, classField->next);
  743.       }
  744.       break;
  745.     case RECORD_FIELD:
  746.       recordField = (RecordField *) p;
  747.       printId (indent, recordField->id);
  748.       printIntField (indent, "offset:", recordField->offset);
  749.       printIntField (indent, "sizeInBytes:", recordField->sizeInBytes);
  750.       printCharPtrField (indent, "varDescLabel:", recordField->varDescLabel);
  751.       printItem (indent, "type:", recordField->type);
  752.       printFooter (indent);
  753.       if (recordField->next) {
  754.         printAst (indent, recordField->next);
  755.       }
  756.       break;
  757.     case INT_CONST:
  758.       intConst = (IntConst *) p;
  759.       printIntField (indent, "ivalue:", intConst->ivalue);
  760.       printFooter (indent);
  761.       break;
  762.     case DOUBLE_CONST:
  763.       doubleConst = (DoubleConst *) p;
  764.       printFieldName (indent, "rvalue=");
  765.       printf ("%.17g\n", doubleConst->rvalue);
  766.       printCharPtrField (indent, "nameOfConstant:", doubleConst->nameOfConstant);
  767.       printPtrField (indent, "next=", doubleConst->next);
  768.       printFooter (indent);
  769.       break;
  770.     case CHAR_CONST:
  771.       charConst = (CharConst *) p;
  772.       printFieldName (indent, "ivalue=");
  773.       printf ("%d", charConst->ivalue);
  774.       printf ("\n");
  775.       printFooter (indent);
  776.       break;
  777.     case STRING_CONST:
  778.       stringConst = (StringConst *) p;
  779.       printStringField (indent, "svalue:", stringConst->svalue);
  780.       printPtrField (indent, "next=", stringConst->next);
  781.       printFooter (indent);
  782.       break;
  783.     case BOOL_CONST:
  784.       boolConst = (BoolConst *) p;
  785.       printBoolField (indent, "ivalue:", boolConst->ivalue);
  786.       printFooter (indent);
  787.       break;
  788.     case NULL_CONST:
  789.       nullConst = (NullConst *) p;
  790.       printFooter (indent);
  791.       break;
  792.     case CALL_EXPR:
  793.       callExpr = (CallExpr *) p;
  794.       printId (indent, callExpr->id);
  795.       printSymbolField (indent, "primitiveSymbol:", callExpr->primitiveSymbol);
  796.       printIntField (indent, "retSize:", callExpr->retSize);
  797.       printItem (indent, "argList:", callExpr->argList);
  798.       printPtrField (indent, "myDef:", callExpr->myDef);
  799.       printFooter (indent);
  800.       break;
  801.     case SEND_EXPR:
  802.       sendExpr = (SendExpr *) p;
  803.       printStringField (indent, "selector:", sendExpr->selector);
  804.       printSymbolField (indent, "kind:", sendExpr->kind);
  805.       printSymbolField (indent, "primitiveSymbol:", sendExpr->primitiveSymbol);
  806.       printPtrField (indent, "myProto:", sendExpr->myProto);
  807.       printItem (indent, "receiver:", sendExpr->receiver);
  808.       printItem (indent, "argList:", sendExpr->argList);
  809.       printFooter (indent);
  810.       break;
  811.     case SELF_EXPR:
  812.       selfExpr = (SelfExpr *) p;
  813.       printFooter (indent);
  814.       break;
  815.     case SUPER_EXPR:
  816.       superExpr = (SuperExpr *) p;
  817.       printFooter (indent);
  818.       break;
  819.     case FIELD_ACCESS:
  820.       fieldAccess = (FieldAccess *) p;
  821.       printId (indent, fieldAccess->id);
  822.       printIntField (indent, "offset:", fieldAccess->offset);
  823.       printItem (indent, "expr:", fieldAccess->expr);
  824.       printFooter (indent);
  825.       break;
  826.     case ARRAY_ACCESS:
  827.       arrayAccess = (ArrayAccess *) p;
  828.       printIntField (indent, "sizeOfElements:", arrayAccess->sizeOfElements);
  829.       printItem (indent, "arrayExpr:", arrayAccess->arrayExpr);
  830.       printItem (indent, "indexExpr:", arrayAccess->indexExpr);
  831.       printFooter (indent);
  832.       break;
  833.     case CONSTRUCTOR:
  834.       constructor = (Constructor *) p;
  835.       printSymbolField (indent, "kind:", constructor->kind);
  836.       printSymbolField (indent, "allocKind:", constructor->allocKind);
  837.       printIntField (indent, "sizeInBytes:", constructor->sizeInBytes);
  838.       printPtrField (indent, "myClass:", constructor->myClass);
  839.       printItem (indent, "type:", constructor->type);
  840.       printItem (indent, "countValueList:", constructor->countValueList);
  841.       printItem (indent, "fieldInits:", constructor->fieldInits);
  842.       printFooter (indent);
  843.       break;
  844.     case CLOSURE_EXPR:
  845.       closureExpr = (ClosureExpr *) p;
  846.       printItem (indent, "function:", closureExpr->function);
  847.       printFooter (indent);
  848.       break;
  849.     case VARIABLE_EXPR:
  850.       var = (VariableExpr *) p;
  851.       printStringField (indent, "id:", var->id);
  852.       printPtrField (indent, "myDef:", var->myDef);
  853.       break;
  854.     case AS_PTR_TO_EXPR:
  855.       asPtrToExpr = (AsPtrToExpr *) p;
  856.       printItem (indent, "expr:", asPtrToExpr->expr);
  857.       printItem (indent, "type:", asPtrToExpr->type);
  858.       printFooter (indent);
  859.       break;
  860.     case AS_INTEGER_EXPR:
  861.       asIntegerExpr = (AsIntegerExpr *) p;
  862.       printItem (indent, "expr:", asIntegerExpr->expr);
  863.       printFooter (indent);
  864.       break;
  865.     case ARRAY_SIZE_EXPR:
  866.       arraySizeExpr = (ArraySizeExpr *) p;
  867.       printItem (indent, "expr:", arraySizeExpr->expr);
  868.       printFooter (indent);
  869.       break;
  870.     case IS_INSTANCE_OF_EXPR:
  871.       isInstanceOfExpr = (IsInstanceOfExpr *) p;
  872.       printPtrField (indent, "classDef:", isInstanceOfExpr->classDef);
  873.       printItem (indent, "expr:", isInstanceOfExpr->expr);
  874.       printItem (indent, "type:", isInstanceOfExpr->type);
  875.       printFooter (indent);
  876.       break;
  877.     case IS_KIND_OF_EXPR:
  878.       isKindOfExpr = (IsKindOfExpr *) p;
  879.       printPtrField (indent, "classOrInterface:", isKindOfExpr->classOrInterface);
  880.       printItem (indent, "expr:", isKindOfExpr->expr);
  881.       printItem (indent, "type:", isKindOfExpr->type);
  882.       printFooter (indent);
  883.       break;
  884.     case SIZE_OF_EXPR:
  885.       sizeOfExpr = (SizeOfExpr *) p;
  886.       printItem (indent, "type:", sizeOfExpr->type);
  887.       printFooter (indent);
  888.       break;
  889.     case DYNAMIC_CHECK:
  890.       dynamicCheck = (DynamicCheck *) p;
  891.       printIntField (indent, "kind:", dynamicCheck->kind);
  892.       printIntField (indent, "expectedArraySize:", dynamicCheck->expectedArraySize);
  893.       printIntField (indent, "arraySizeInBytes:", dynamicCheck->arraySizeInBytes);
  894.       printPtrField (indent, "expectedClassDef:", dynamicCheck->expectedClassDef);
  895.       printItem (indent, "expr:", dynamicCheck->expr);
  896.       printFooter (indent);
  897.       break;
  898.     case ARGUMENT:
  899.       arg = (Argument *) p;
  900.       printItem (indent, "expr:", arg->expr);
  901.       printItem (indent, "tempName:", arg->tempName);
  902.       printFooter (indent);
  903.       if (arg->next) {
  904.         printAst (indent, arg->next);
  905.       }
  906.       break;
  907.     case COUNT_VALUE:
  908.       countValue = (CountValue *) p;
  909.       printItem (indent, "count:", countValue->count);
  910.       printItem (indent, "value:", countValue->value);
  911.       printItem (indent, "countTemp:", countValue->countTemp);
  912.       printItem (indent, "valueTemp:", countValue->valueTemp);
  913.       printFooter (indent);
  914.       if (countValue->next) {
  915.         printAst (indent, countValue->next);
  916.       }
  917.       break;
  918.     case FIELD_INIT:
  919.       fieldInit = (FieldInit *) p;
  920.       printId (indent, fieldInit->id);
  921.       printIntField (indent, "offset:", fieldInit->offset);
  922.       printIntField (indent, "sizeInBytes:", fieldInit->sizeInBytes);
  923.       printItem (indent, "expr:", fieldInit->expr);
  924.       printFooter (indent);
  925.       if (fieldInit->next) {
  926.         printAst (indent, fieldInit->next);
  927.       }
  928.       break;
  929.  
  930.     default:
  931.       printLine (indent, "(********** op is garbage! **********)");
  932.       errorsDetected++;
  933.   }
  934. }
  935.  
  936.  
  937.  
  938. // printHeader (indent, str, p)
  939. //
  940. // This routine indents, then prints a label, then prints str, and then prints
  941. // the p->pos. Finally, a newline is printed.
  942. //
  943. void printHeader (int indent, char * str, AstNode * p) {
  944.   int i = printPtr (p);
  945.   printf (": ");
  946.   i = indent - i - TABAMT;
  947.   printIndent (i);
  948.   printf ("-----%s-----\n", str);
  949.   printFieldName (indent, "token:");
  950.   printf("%s", symbolName (p->tokn.type));
  951.   switch (p->tokn.type) {
  952.     case ID:
  953.       printf(" ");
  954.       printString (stdout, p->tokn.value.svalue);
  955.       break;
  956.     case STRING_CONST:
  957.       printf(" \"");
  958.       printString (stdout, p->tokn.value.svalue);
  959.       printf("\"");
  960.       break;
  961.     case CHAR_CONST:
  962.       printf(" \'");
  963.       printChar (stdout, p->tokn.value.ivalue);
  964.       printf("\'");
  965.       break;
  966.     case INT_CONST:
  967.       printf(" %d", p->tokn.value.ivalue);
  968.       break;
  969.     case DOUBLE_CONST:
  970.       printf(" %.17g", p->tokn.value.rvalue);
  971.       break;
  972.   }
  973.   printf(" (%s: %d)\n", extractFilename (p->tokn), extractLineNumber (p->tokn));
  974.  
  975. }
  976.  
  977.  
  978.  
  979. // printFooter (indent)
  980. //
  981. // This routine indents, then the closing bracketting symbol.
  982. //
  983. void printFooter (int indent) {
  984.   printIndent (indent);
  985.   printf ("--------------------\n");
  986. }
  987.  
  988.  
  989.  
  990. // printIndent (indent)
  991. //
  992. // This routine prints "indent" spaces.
  993. //
  994. void printIndent (int indent) {
  995.   int i;
  996.   for (i=indent; i>0; i--)
  997.     printf (" ");
  998. }
  999.  
  1000.  
  1001.  
  1002. // printLine (indent, str)
  1003. //
  1004. // This routine indents, then prints the given string, then prints newline.
  1005. //
  1006. void printLine (int indent, char * str) {
  1007.   printIndent (indent);
  1008.   printf ("%s\n", str);
  1009. }
  1010.  
  1011.  
  1012.  
  1013. // printPtrField (indent, str, p)
  1014. //
  1015. // This routine indents by "indent" + TABAMT, then prints str, then prints
  1016. // the p argument as a pointer, then prints newline.
  1017. //
  1018. void printPtrField (int indent, char * str, AstNode * p) {
  1019.   printIndent (indent+TABAMT);
  1020.   printf ("%s ", str);
  1021.   printPtr (p);
  1022.   printf ("\n");
  1023. }
  1024.  
  1025.  
  1026.  
  1027. // printIntField (indent, str, i)
  1028. //
  1029. // This routine indents by "indent" + TABAMT, then prints str, then prints
  1030. // the integer i, then prints newline.
  1031. //
  1032. void printIntField (int indent, char * str, int i) {
  1033.   printIndent (indent+TABAMT);
  1034.   printf ("%s %d\n", str, i);
  1035. }
  1036.  
  1037.  
  1038.  
  1039. // printBoolField (indent, str, i)
  1040. //
  1041. // This routine indents by "indent" + TABAMT, then prints str, then prints
  1042. // the integer i (as TRUE or FALSE), then prints newline.
  1043. //
  1044. void printBoolField (int indent, char * str, int i) {
  1045.   printIndent (indent+TABAMT);
  1046.   if (i == 0) {
  1047.     printf ("%s FALSE\n", str);
  1048.   } else if (i == 1) {
  1049.     printf ("%s TRUE\n", str);
  1050.   } else {
  1051.     printf ("%s %d  **********  ERROR: Not 0 or 1  **********\n", str, i);
  1052.     errorsDetected++;
  1053.   }
  1054. }
  1055.  
  1056.  
  1057.  
  1058. // printStringField (indent, str1, str2)
  1059. //
  1060. // This routine indents by "indent" + TABAMT, then prints str1, then prints
  1061. // str2, then prints newline.
  1062. //
  1063. void printStringField (int indent, char * str1, String * str2) {
  1064.   printIndent (indent+TABAMT);
  1065.   if (str2 == NULL) {
  1066.     printf ("%s NULL\n", str1);
  1067.   } else {
  1068.     printf ("%s ", str1);
  1069.     printString (stdout, str2);
  1070.     printf ("\n");
  1071.   }
  1072. }
  1073.  
  1074.  
  1075.  
  1076. // printSymbolField (indent, str, sym)
  1077. //
  1078. // This routine indents by "indent" + TABAMT, then prints str, then prints
  1079. // sym, then prints newline.
  1080. //
  1081. void printSymbolField (int indent, char * str, int sym) {
  1082.   printIndent (indent+TABAMT);
  1083.   if (sym == NULL) {
  1084.     printf ("%s NULL\n", str);
  1085.   } else {
  1086.     printf ("%s %s\n", str, symbolName (sym));
  1087.   }
  1088. }
  1089.  
  1090.  
  1091.  
  1092. // printCharPtrField (indent, str, charPtr)
  1093. //
  1094. // This routine indents by "indent" + TABAMT, then prints str, then prints
  1095. // charPtr, then prints newline.
  1096. //
  1097. void printCharPtrField (int indent, char * str, char * charPtr) {
  1098.   printIndent (indent+TABAMT);
  1099.   if (charPtr == NULL) {
  1100.     printf ("%s NULL\n", str);
  1101.   } else {
  1102.     printf ("%s %s\n", str, charPtr);
  1103.   }
  1104. }
  1105.  
  1106.  
  1107.  
  1108. // printId (indent, id)
  1109. //
  1110. // This routine indents by "indent" + TABAMT, then prints "id:", then prints
  1111. // the id argument, then prints newline.
  1112. //
  1113. void printId (int indent, String * id) {
  1114.   printStringField (indent, "id:", id);
  1115. }
  1116.  
  1117.  
  1118.  
  1119. // printFieldName (indent, str)
  1120. //
  1121. // This routine indents by "indent" + TABAMT, then prints the given string.  It
  1122. // prints no newLine.
  1123. //
  1124. void printFieldName (int indent, char * str) {
  1125.   printIndent (indent+TABAMT);
  1126.   printf ("%s ", str);
  1127. }
  1128.  
  1129.  
  1130.  
  1131. // printItem (indent, str, t)
  1132. //
  1133. // This routine prints the given string on one line (indented by TABAMT more
  1134. // than "indent") and then calls printAst() to print the tree "t" (indented by
  1135. // 2*TABAMT more spaces than "indent").
  1136. //
  1137. void printItem (int indent, char * str, AstNode * t) {
  1138.   printIndent (indent+TABAMT);
  1139.   printf ("%s", str);
  1140.   if (t == NULL) {
  1141.     printf (" NULL\n");
  1142.   } else {
  1143.     printf ("\n");
  1144.     printAst (indent+TABAMT+TABAMT, t);
  1145.   }
  1146. }
  1147.  
  1148.  
  1149.  
  1150. // printOperator (indent, op)
  1151. //
  1152. // This routine is passed a token type in "op".  It prints it out in the form:
  1153. //       op= '+'
  1154. ///
  1155. void printOperator (int in, int op) {
  1156.   printIndent (in+TABAMT);
  1157.   switch (op) {
  1158. /*****
  1159.     case LEQ:
  1160.       printf ("op= LEQ\n");
  1161.       return;
  1162.     case GEQ:
  1163.       printf ("op= GEQ\n");
  1164.       return;
  1165.     case NEQ:
  1166.       printf ("op= NEQ\n");
  1167.       return;
  1168.     case AND:
  1169.       printf ("op= AND\n");
  1170.       return;
  1171.     case DIV:
  1172.       printf ("op= DIV\n");
  1173.       return;
  1174.     case MOD:
  1175.       printf ("op= MOD\n");
  1176.       return;
  1177.     case NOT:
  1178.       printf ("op= NOT\n");
  1179.       return;
  1180.     case OR:
  1181.       printf ("op= OR\n");
  1182.       return;
  1183.     case '<':
  1184.     case '>':
  1185.     case '=':
  1186.     case '+':
  1187.     case '-':
  1188.     case '*':
  1189.     case '/':
  1190.       printf ("op= '%c'\n", op);
  1191.       return;
  1192. *****/
  1193.     default:
  1194.       printf ("op=***** ERROR: op IS GARBAGE *****\n");
  1195.       errorsDetected++;
  1196.   }
  1197. }
  1198.  
  1199.  
  1200.  
  1201. // printPtr (p)
  1202. //
  1203. // This routine is passed a pointer, possibly NULL.  It prints the pointer.
  1204. // The actual address is not printed, since these may vary from run to run.
  1205. // Instead, this routine assigns 'labels' to each address and prints the
  1206. // same label each time.  It saves the mapping between label and address
  1207. // in a static array.
  1208. //
  1209. int printPtr (AstNode * p) {
  1210.  
  1211. #define MAX_LABELS 10000
  1212.  
  1213.   static int a [MAX_LABELS];
  1214.   static int nextLabel = 1;
  1215.   int p1 = (int) p;
  1216.   int i;
  1217.   if (p == NULL) {
  1218.     printf ("NULL");
  1219.     return 4;
  1220.   }
  1221.   for (i=1; i<nextLabel && i<MAX_LABELS; i++) {
  1222.     if (a [i] == p1) {
  1223.       printf ("#%d", i);
  1224.       if (i<10) return 2;
  1225.       if (i<100) return 3;
  1226.       if (i<1000) return 4;
  1227.       if (i<10000) return 5;
  1228.       return 6;
  1229.     }
  1230.   }
  1231.   if (nextLabel == MAX_LABELS) {
  1232.     printf ("**********  Overflow in printPtr!  **********");
  1233.     errorsDetected++;
  1234.     return 30;
  1235.   } else {
  1236.     a [nextLabel] = p1;
  1237.     i = nextLabel++;
  1238.     printf ("#%d", i);
  1239.     if (i<10) return 2;
  1240.     if (i<100) return 3;
  1241.     if (i<1000) return 4;
  1242.     if (i<10000) return 5;
  1243.     return 6;
  1244.   }
  1245. }
  1246.  
  1247.  
  1248.  
  1249. // fpretty (p)
  1250. //
  1251. // This routine is passed a type node.  It prints it on stderr, not followed
  1252. // by a return.  It will deal with a NULL argument, but it should be passed
  1253. // a legal type otherwise.
  1254. //
  1255. void fpretty (Type * p) {
  1256.   fpretty2 (p, 1);
  1257. }
  1258.  
  1259.  
  1260.  
  1261. // fpretty2 (p)
  1262. //
  1263. // This routine does the work.
  1264. //
  1265. // Normally, we print defined types out like:
  1266. //    MyType = record f: int endRecord
  1267. // The "wantRecursion" parameter is to prevent recursion when printing types like:
  1268. //    type MyRec = record
  1269. //                   next: ptr to MyRec
  1270. //                 endRecord
  1271. // We want to print just the NamedType, like this:
  1272. //    MyRec = record next: ptr to MyRec endRecord
  1273. //
  1274. void fpretty2 (Type * p, int wantRecursion) {
  1275.  
  1276.     PtrType * pType;
  1277.     ArrayType * aType;
  1278.     RecordType * rType;
  1279.     FunctionType * fType;
  1280.     NamedType * nType;
  1281.  
  1282.     RecordField * field;
  1283.     TypeParm * typeParm;
  1284.     TypeArg * typeArg;
  1285.  
  1286.   if (p==NULL) {
  1287.     fprintf (stderr, "***** TYPE IS MISSING *****");
  1288.     return;
  1289.   }
  1290.  
  1291.   switch (p->op) {
  1292.  
  1293.     case CHAR_TYPE:
  1294.       fprintf (stderr, "char");
  1295.       return;
  1296.  
  1297.     case INT_TYPE:
  1298.       fprintf (stderr, "int");
  1299.       return;
  1300.  
  1301.     case DOUBLE_TYPE:
  1302.       fprintf (stderr, "double");
  1303.       return;
  1304.  
  1305.     case BOOL_TYPE:
  1306.       fprintf (stderr, "bool");
  1307.       return;
  1308.  
  1309.     case VOID_TYPE:
  1310.       fprintf (stderr, "void");
  1311.       return;
  1312.  
  1313.     case TYPE_OF_NULL_TYPE:
  1314.       fprintf (stderr, "typeOfNull");
  1315.       return;
  1316.  
  1317.     case ANY_TYPE:
  1318.       fprintf (stderr, "anyType");
  1319.       return;
  1320.  
  1321.     case PTR_TYPE:
  1322.       pType = (PtrType *) p;
  1323.       fprintf (stderr, "ptr to ");
  1324.       fpretty2 (pType->baseType, 0);  // wantRecursion = false
  1325.       return;
  1326.  
  1327.     case ARRAY_TYPE:
  1328.       aType = (ArrayType *) p;
  1329.       if (aType->sizeExpr) {
  1330.         if (aType->sizeExpr->op == INT_CONST) {
  1331.           fprintf (stderr, "array [%d] of ", ((IntConst *) (aType->sizeExpr))->ivalue);
  1332.         } else {
  1333.           fprintf (stderr, "array [...] of ");
  1334.         }
  1335.       } else {
  1336.         fprintf (stderr, "array [*] of ");
  1337.       }
  1338.       fpretty2 (aType->baseType, 0);  // wantRecursion = false
  1339.       return;
  1340.  
  1341.     case RECORD_TYPE:
  1342.       rType = (RecordType *) p;
  1343.       fprintf (stderr, "record ");
  1344.       for (field = rType->fields; field != NULL; field = (RecordField *) field->next) {
  1345.         printString (stderr, field->id);
  1346.         fprintf (stderr, ": ");
  1347.         fpretty2 (field->type, 0);  // wantRecursion = false
  1348.         if (field->next) {
  1349.           fprintf (stderr, ", ");
  1350.         }
  1351.       }
  1352.       fprintf (stderr, " endRecord");
  1353.       return;
  1354.  
  1355.     case FUNCTION_TYPE:
  1356.       fType = (FunctionType *) p;
  1357.       fprintf (stderr, "function (");
  1358.       for (typeArg = fType->parmTypes; typeArg != NULL; typeArg = typeArg->next) {
  1359.         fpretty2 (typeArg->type, 0);  // wantRecursion = false
  1360.         if (typeArg->next) {
  1361.           fprintf (stderr, ", ");
  1362.         }
  1363.       }
  1364.       fprintf (stderr, ") returns ");
  1365.       fpretty2 (fType->retType, 0);  // wantRecursion = false
  1366.       return;
  1367.  
  1368.     case TYPE_PARM:
  1369.       typeParm = (TypeParm *) p;
  1370.       printString (stderr, typeParm->id);
  1371.       fprintf (stderr, ": ");
  1372.       fpretty2 (typeParm->type, 0);  // wantRecursion = false
  1373.       return;
  1374.  
  1375.     case NAMED_TYPE:
  1376.       nType = (NamedType *) p;
  1377.       printString (stderr, nType->id);
  1378.       if (nType->typeArgs) {
  1379.         fprintf (stderr, " [");
  1380.         for (typeArg = nType->typeArgs; typeArg != NULL; typeArg = typeArg->next) {
  1381.           fpretty2 (typeArg->type, 0);  // wantRecursion = false
  1382.           if (typeArg->next) {
  1383.             fprintf (stderr, ", ");
  1384.           }
  1385.         }
  1386.         fprintf (stderr, "]");
  1387.       }
  1388.       if ((nType->myDef) &&
  1389.           (nType->myDef->op == TYPE_PARM)) {
  1390.         fprintf (stderr, ": ");
  1391.         fpretty2 (((TypeParm *) nType->myDef)->type, 0);  // wantRecursion = false
  1392.       } else if ((nType->myDef) &&
  1393.           (nType->myDef->op == TYPE_DEF)) {
  1394.         if (wantRecursion) {
  1395.           fprintf (stderr, " = ");
  1396.           fpretty2 (((TypeDef *) nType->myDef)->type, 0);  // wantRecursion = false
  1397.         }
  1398.       }
  1399.       return;
  1400.  
  1401.     default:
  1402.       printf("\np->op = %s\n", symbolName (p->op));
  1403.       programLogicError ("Unexpected OP in fpretty");
  1404.       errorsDetected++;
  1405.   }
  1406. }
  1407.