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 / Beta / check.cc < prev    next >
C/C++ Source or Header  |  2007-09-04  |  462KB  |  13,080 lines

  1. // check.cc  --  Routines related to semantic checking
  2. //
  3. // KPL Compiler
  4. //
  5. // Copyright 2002-2007, 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. //   08/01/02 - Harry H. Porter III
  16. //
  17. // Modifcations by:
  18. //   03/15/06 - Harry H. Porter III
  19. //
  20. //
  21.  
  22. #include "main.h"
  23.  
  24.  
  25.  
  26.  
  27. // topoProcessAllPackages ()
  28. //
  29. // This function runs through all packages and reorders the header list so that
  30. // all packages come before their sub-packages.  It also sets the "myDef" field
  31. // for each header.
  32. //
  33. void topoProcessAllPackages () {
  34.   Header * tempList = NULL;
  35.   Header * hdr, * next;
  36.   Mapping<String,AstNode> * tempMapping;
  37.   AstNode * def;
  38.  
  39.   // printf ("Here is the  header list before topoProcessAllPackages:\n");
  40.   // for (hdr = headerList; hdr != NULL; hdr = hdr->next) {
  41.   //   printf ("  ");
  42.   //   printString (stdout, hdr->packageName);
  43.   //   printf ("\n");
  44.   // }
  45.  
  46.   // headerMapping->print (0);
  47.  
  48.   // This mapping is from package names to packages.  It is used to make
  49.   // sure each package has a distinct name.
  50.   tempMapping = new Mapping<String,AstNode> (10, NULL);
  51.  
  52.  
  53.   // Run through all headers and put them on a temp list.
  54.   for (hdr = headerList; hdr != NULL; hdr = next) {
  55.     def = tempMapping->find (hdr->packageName);
  56.     if (def == NULL) {
  57.       tempMapping->enter (hdr->packageName, hdr);
  58.     } else if (def != hdr) {
  59.       error (hdr, "This .h file uses the same package name as another .h file");
  60.       error2 (def, "Here is the other .h file");
  61.     }
  62.     next = hdr->next;
  63.     hdr->next = NULL;
  64.     hdr->tempNext = tempList;
  65.     tempList = hdr;
  66.   }
  67.   headerList = NULL;
  68.   delete tempMapping;
  69.  
  70.   // Run through all headers and call topoProcessOnePackage on each.
  71.   for (hdr = tempList; hdr != NULL; hdr = next) {
  72.     next = hdr->tempNext;
  73.     hdr->tempNext = NULL;
  74.     // printf ("Outer LOOP calling topoProcessOnePackage on %s\n",
  75.     //         hdr->packageName->chars);
  76.     topoProcessOnePackage (hdr);
  77.   }
  78.  
  79.   // Reverse the headerList.
  80.   hdr = headerList;
  81.   headerList = NULL;
  82.   while (hdr != NULL) {
  83.     next = hdr->next;
  84.     hdr->next = headerList;
  85.     headerList = hdr;
  86.     hdr = next;
  87.   }
  88.  
  89.   // printf ("Here is the header list after topoProcessAllPackages:\n");
  90.   // for (hdr = headerList; hdr != NULL; hdr = hdr->next) {
  91.   //   printf ("  ");
  92.   //   printString (stdout, hdr->packageName);
  93.   //   printf ("\n");
  94.   // }
  95.  
  96. }
  97.  
  98.  
  99.  
  100. // topoProcessOnePackage (hdr)
  101. //
  102. // Mark this package as "in process".  Then call self recursively to process
  103. // all super-packages.  Finally mark this package as "done" and add it to
  104. // the growing list of packages.  Also check for cycles.
  105. //
  106. void topoProcessOnePackage (Header * hdr) {
  107.   Header * superHeader;
  108.   Uses * uses;
  109.  
  110.   // printf ("=====  topoProcessOnePackage called on ");
  111.   // printString (stdout, hdr->packageName);
  112.   // printf ("  (mark-in = %d)  =====\n", hdr->mark);
  113.  
  114.   // This header may have been done earlier in the topoProcessing...
  115.   if (hdr->mark == 2) return;
  116.  
  117.   // Check for circularity...
  118.   if (hdr->mark == 1) {
  119.     error (hdr, "Circularity in package-use hierarchy (this package appears to use itself, possibly indirectly)");
  120.     return;
  121.   }
  122.  
  123.   // Set mark to "processing"...
  124.   hdr->mark = 1;
  125.  
  126.   // Process all super-packages first
  127.   for (uses = hdr->uses; uses != NULL; uses = uses->next) {
  128.     // printf ("LOOKING FOR %s\n", uses->id->chars);
  129.     superHeader = headerMapping->find (uses->id);
  130.     if (superHeader) {
  131.       // printf ("  FOUND %s\n", superHeader->packageName->chars);
  132.       uses->myDef = superHeader;
  133.       topoProcessOnePackage (superHeader);
  134.     }
  135.   }
  136.  
  137.   // Set mark to "done"...
  138.   hdr->mark = 2;
  139.  
  140.   // Put this one on the headerList
  141.   hdr->next = headerList;
  142.   headerList = hdr;
  143.  
  144.   // // Fill in the fieldMapping and the methodMapping
  145.   // // Use the superclass's mapping or the global mapping as the
  146.   // // surrounding mapping.  Make the initial mapping size 2 since most
  147.   // // classes have at least 2 fields and 2 methods.
  148.   // if (hdr->superclass == NULL) {
  149.   //   hdr->fieldMapping = new Mapping<String,AstNode> (2, globalMapping);
  150.   //   hdr->methodMapping = new Mapping<String,AstNode> (2, globalMapping);
  151.   // } else {
  152.   //   hdr->fieldMapping = new Mapping<String,AstNode> (2, hdr->superclass->fieldMapping);
  153.   //   hdr->methodMapping = new Mapping<String,AstNode>
  154.   //                                 (2, hdr->superclass->methodMapping);
  155.   // }
  156.  
  157. }
  158.  
  159.  
  160.  
  161. // buildPackageMapping (Header * hdr)
  162. //
  163. // Run through all packages and build their symbol tables.
  164. //
  165. void buildPackageMapping (Header * hdr) {
  166.   Header * superHeader;
  167.   ConstDecl * con, * nextCon;
  168.   ErrorDecl * errorDecl, * nextErrorDecl, * otherErrorDecl;
  169.   Global * global, * nextGlobal, * lastGlobal;
  170.   TypeDef * typeDef, * nextTypeDef;
  171.   FunctionProto * functionProto, * proto;
  172.   Function * fun;
  173.   Interface * interface, * nextInterface;
  174.   ClassDef * cl, * nextClass;
  175.   AstNode * oldDef;
  176.   Uses * uses;
  177.   Mapping <String, AstNode> * superMapping;
  178.   Mapping <String, String> * renaming;
  179.   Mapping <String, AstNode> * behaviorMapping;
  180.   Renaming * ren;
  181.   AstNode * val;
  182.   String * key, * newStr;
  183.   String * strKey, * strVal;
  184.   Behavior * behav;
  185.   Mapping<String,AstNode> * tempMapping;
  186.   Method * meth;
  187.  
  188.   hdr->packageMapping = new Mapping<String, AstNode> (100, NULL);
  189.   hdr->errorMapping = new Mapping<String, ErrorDecl> (5, NULL);
  190.  
  191.   // This mapping is from package names to anything.  It is used to make
  192.   // sure each use clause has a different package name.
  193.   tempMapping = new Mapping<String,AstNode> (5, NULL);
  194.  
  195.   // Run through the uses list...
  196.   for (uses=hdr->uses; uses; uses=uses->next) {
  197.     // Build the renaming map...
  198.     renaming = new Mapping<String, String> (100, NULL);
  199.     for (ren = uses->renamings; ren; ren=ren->next) {
  200.       if (renaming->alreadyDefined (ren->from)) {
  201.         error (ren, "This symbol appears more than once as a 'from' symbol in this renaming clause");
  202.       } else {
  203.         renaming->enter (ren->from, ren->to);
  204.         if (ren->to->primitiveSymbol) {
  205.           error (ren, "The 'to' symbol happens to be the same as the name of a built-in primitive function; please select a different symbol");
  206.         }
  207.       }
  208.  
  209.     }
  210.  
  211.     // Check to make sure this package is only used once...
  212.     oldDef = tempMapping->find (uses->id);
  213.     if (oldDef == NULL) {
  214.       tempMapping->enter (uses->id, uses);
  215.     } else {
  216.       error (oldDef, "This package appears more than once in the 'uses' clause");
  217.       error2 (uses, "Here is the other occurrence");
  218.     }
  219.  
  220.     // printf ("Inheriting from %s\n", uses->id->chars);
  221.     // printf ("  =====Renaming=====\n");
  222.     // for (strVal = renaming->getFirst(); strVal; strVal = renaming->getNext()) {
  223.     //   strKey = renaming->getItsKey ();
  224.     //   printf ("    %s --> %s\n", strKey->chars, strVal->chars);
  225.     // }
  226.     // printf ("  ==================\n");
  227.  
  228.     superHeader = uses->myDef;
  229.     if (superHeader) {
  230.       // Run through the super's package mapping.  Add everything there to this package...
  231.       superMapping = superHeader->packageMapping;
  232.       // superMapping->print (6);
  233.       for (val = superMapping->getFirst (); val; val = superMapping->getNext ()) {
  234.         key = superMapping->getItsKey ();
  235.         // printf ("  Inheriting key=%s\n", key->chars);
  236.         // See if we are renaming this thing...
  237.         newStr = renaming->find (key);
  238.         if (newStr) {
  239.           // printf ("    -- Decided to rename!!!   key=%s newStr=%s\n",
  240.           //         key->chars, newStr->chars);
  241.           key = newStr;
  242.         }
  243.         // See if it is already defined and has a different definition...
  244.         oldDef = hdr->packageMapping->find (key);
  245.         if (oldDef && (oldDef != val)) {
  246.           error (val, "The name to be used for this item also names something else in this package");
  247.           error2 (oldDef, "Here is the other item with the same name");
  248.           error2 (hdr, "The naming conflict was detected within this package");
  249.         } else if (oldDef == NULL) {
  250.           hdr->packageMapping->enter (key, val);
  251.         }
  252.       }
  253.       // Run through the super's "errors" and add these to this package...
  254.       for (errorDecl = superHeader->errors; errorDecl; errorDecl = errorDecl->next) {
  255.         newStr = renaming->find (errorDecl->id);
  256.         if (newStr) {
  257.           // printf ("    -- Decided to rename!!!   key=%s newStr=%s\n",
  258.           //         key->chars, newStr->chars);
  259.           key = newStr;
  260.         } else {
  261.           key = errorDecl->id;
  262.         }
  263.         // See if it is already defined and has a different definition...
  264.         otherErrorDecl = hdr->errorMapping->find (key);
  265.         if (otherErrorDecl && (otherErrorDecl != errorDecl)) {
  266.           error (errorDecl, "The name to be used for this error already names a different error in this package");
  267.           error2 (otherErrorDecl, "Here is the other error with the same name");
  268.           error2 (hdr, "The naming conflict was detected within this package");
  269.         } else if (otherErrorDecl == NULL) {
  270.           hdr->errorMapping->enter (key, errorDecl);
  271.         }
  272.       }
  273.     }
  274.     delete renaming;
  275.   }
  276.  
  277.   delete tempMapping;
  278.  
  279.   // Run through the constants and add them...
  280.   for (con=hdr->consts; con; con=con->next) {
  281.     oldDef = hdr->packageMapping->find (con->id);
  282.     if (oldDef) {
  283.       error (con, "This name is already defined within this package");
  284.       error2 (oldDef, "Here is the other item with the same name");
  285.     } else {
  286.       addToPackage (hdr, con->id, con);
  287.     }
  288.   }
  289.  
  290.   // Run through the errors and add them...
  291.   for (errorDecl=hdr->errors; errorDecl; errorDecl=errorDecl->next) {
  292.     oldDef = hdr->errorMapping->find (errorDecl->id);
  293.     if (oldDef) {
  294.       error (errorDecl, "This error has already been declared within this package");
  295.       error2 (oldDef, "Here is the other declaration");
  296.     } else {
  297.       hdr->errorMapping->enter (errorDecl->id, errorDecl);
  298.     }
  299.   }
  300.  
  301.   // Run through the globals and add them...
  302.   for (global=hdr->globals; global; global= (Global *) global->next) {
  303.     oldDef = hdr->packageMapping->find (global->id);
  304.     if (oldDef) {
  305.       error (global, "This name is already defined within this package");
  306.       error2 (oldDef, "Here is the other item with the same name");
  307.     } else {
  308.       addToPackage (hdr, global->id, global);
  309.     }
  310.   }
  311.  
  312.   // Run through the typeDefs and add them...
  313.   for (typeDef=hdr->typeDefs; typeDef; typeDef=typeDef->next) {
  314.     oldDef = hdr->packageMapping->find (typeDef->id);
  315.     if (oldDef) {
  316.       error (typeDef, "This name is already defined within this package");
  317.       error2 (oldDef, "Here is the other item with the same name");
  318.     } else {
  319.       addToPackage (hdr, typeDef->id, typeDef);
  320.     }
  321.   }
  322.  
  323.   // Run through the functionProtos and add them...
  324.   for (functionProto=hdr->functionProtos;
  325.        functionProto;
  326.        functionProto=functionProto->next) {
  327.     oldDef = hdr->packageMapping->find (functionProto->id);
  328.     if (oldDef) {
  329.       error (functionProto, "This name is already defined within this package");
  330.       error2 (oldDef, "Here is the other item with the same name");
  331.     } else {
  332.       addToPackage (hdr, functionProto->id, functionProto);
  333.     }
  334.     functionProto->myHeader = hdr;
  335.     // printf ("linking protoname = %s to header\n", functionProto->id->chars);
  336.   }
  337.  
  338.   // Run though all functionProtos and link them to their headers...
  339.   for (proto=hdr->functionProtos; proto; proto = proto->next) {
  340.   }
  341.  
  342.   // Run through the interfaces and add them...
  343.   for (interface=hdr->interfaces;
  344.        interface;
  345.        interface=interface->next) {
  346.     oldDef = hdr->packageMapping->find (interface->id);
  347.     if (oldDef) {
  348.       error (interface, "This name is already defined within this package");
  349.       error2 (oldDef, "Here is the other item with the same name");
  350.     } else {
  351.       addToPackage (hdr, interface->id, interface);
  352.     }
  353.   }
  354.  
  355.   // Run through the classDefs and add them...
  356.   for (cl=hdr->classes;
  357.        cl;
  358.        cl=cl->next) {
  359.     oldDef = hdr->packageMapping->find (cl->id);
  360.     if (oldDef) {
  361.       error (cl, "This name is already defined within this package");
  362.       error2 (oldDef, "Here is the other item with the same name");
  363.     } else {
  364.       addToPackage (hdr, cl->id, cl);
  365.     }
  366.   }
  367.  
  368.   // If this is the package we are compiling, keep going.  Else, return now.
  369.   if (hdr != mainHeader) return;
  370.   if (code == NULL) {
  371.     programLogicError ("Should have quit before now if no code file");
  372.   }
  373.  
  374.   // printf ("    Processing the code portion of this package...\n");
  375.  
  376.   // Check that the code and header have the same package name...
  377.   if (code->packageName != hdr->packageName) {
  378.       error (code, "The package name in the code file must be the same as the package name in the header file");
  379.       error2 (hdr, "Here is the name used in the header file");
  380.   }
  381.  
  382.   // Run though the const's and add them to this header...
  383.   for (con=code->consts; con; con = nextCon) {
  384.     nextCon = con->next;
  385.     oldDef = hdr->packageMapping->find (con->id);
  386.     if (oldDef) {
  387.       error (con, "This name is already defined within this package");
  388.       error2 (oldDef, "Here is the other item with the same name");
  389.     } else {
  390.       addToPackage (hdr, con->id, con);
  391.     }
  392.     con->isPrivate = 1;
  393.     // Add this constant to mainHeader's constList...
  394.     con->next = hdr->consts;
  395.     hdr->consts = con;
  396.   }
  397.  
  398.   // Run though the errorDecl's and add them to this header...
  399.   for (errorDecl=code->errors; errorDecl; errorDecl = nextErrorDecl) {
  400.     nextErrorDecl = errorDecl->next;
  401.     oldDef = hdr->errorMapping->find (errorDecl->id);
  402.     if (oldDef) {
  403.       error (errorDecl, "This error has already been declared within this package");
  404.       error2 (oldDef, "Here is the other declaration");
  405.     } else {
  406.       hdr->errorMapping->enter (errorDecl->id, errorDecl);
  407.     }
  408.     // errorDecl->isPrivate = 1;
  409.     // Add this errorDecl to mainHeader's "errors" list...
  410.     errorDecl->next = hdr->errors;
  411.     hdr->errors = errorDecl;
  412.   }
  413.  
  414.   // Run though the globals and add them to this header...
  415.   lastGlobal = hdr->globals;
  416.   if (lastGlobal) {
  417.     while (lastGlobal->next) {
  418.       lastGlobal = (Global *) lastGlobal->next;
  419.     }
  420.   }
  421.   for (global=code->globals; global; global = nextGlobal) {
  422.     nextGlobal = (Global *) global->next;
  423.     oldDef = hdr->packageMapping->find (global->id);
  424.     if (oldDef) {
  425.       error (global, "This name is already defined within this package");
  426.       error2 (oldDef, "Here is the other item with the same name");
  427.     } else {
  428.       addToPackage (hdr, global->id, global);
  429.     }
  430.     global->isPrivate = 1;
  431.     // Add this global to the end of the mainHeader's global list...
  432.     if (lastGlobal) {
  433.       lastGlobal->next = global;
  434.     } else {
  435.       hdr->globals = global;
  436.     }
  437.     lastGlobal = global;
  438.     global->next = NULL;
  439.   }
  440.  
  441.   // Run though the typeDef's and add them to this header...
  442.   for (typeDef=code->typeDefs; typeDef; typeDef = nextTypeDef) {
  443.     nextTypeDef = typeDef->next;
  444.     oldDef = hdr->packageMapping->find (typeDef->id);
  445.     if (oldDef) {
  446.       error (typeDef, "This name is already defined within this package");
  447.       error2 (oldDef, "Here is the other item with the same name");
  448.     } else {
  449.       addToPackage (hdr, typeDef->id, typeDef);
  450.     }
  451.     // Add this typeDef to mainHeader's typeDef List...
  452.     typeDef->next = hdr-> typeDefs;
  453.     hdr->typeDefs = typeDef;
  454.   }
  455.  
  456.   // Run though the functions and add match them to their prototypes...
  457.   for (fun=code->functions; fun; fun = fun->next) {
  458.     // printf ("Looking at function %s...\n", fun->id->chars);
  459.     proto = (FunctionProto *) hdr->packageMapping->find (fun->id);
  460.     if (proto) {
  461.       if (proto->op != FUNCTION_PROTO) {
  462.         error (fun, "This name is already defined within this package");
  463.         error2 (proto, "Here is the other item with the same name");
  464.       } else {
  465.         if (proto->myFunction != NULL) {
  466.           error (fun, "There are two definitions of this function");
  467.           error2 (proto->myFunction, "Here is the other definition");
  468.         } else if (proto->isExternal) {
  469.           error (proto, "External functions must not have definitions in the code file");
  470.           error2 (fun, "Here is a definition");
  471.         } else if (proto->myHeader != hdr) {
  472.           error (fun, "This function has the same name as a function supplied in another package");
  473.           error2 (proto, "Here is a matching prototype from other package");
  474.         } else {
  475.           // Link this function to its prototype...
  476.           //    printf ("found proto, name = %s  protoname = %s\n", fun->id->chars, proto->id->chars);
  477.           //    printf ("fun->op = %s   proto->op = %s\n", symbolName (fun->op), symbolName (proto->op));
  478.           //    printf ("hdr = %s\n", proto->myHeader->packageName->chars);
  479.           proto->myFunction = fun;
  480.           fun->myProto = proto;
  481.         }
  482.       }
  483.     } else {
  484.       // Create a new prototype and link it to this function...
  485.       //     printf ("Creating new proto\n");
  486.       proto = new FunctionProto ();
  487.       proto->positionAt (fun);
  488.       proto->id = fun->id;
  489.       proto->parmList = fun->parmList;
  490.       proto->retType = fun->retType;
  491.       proto->isPrivate = 1;
  492.       proto->myHeader = hdr;
  493.       proto->myFunction = fun;
  494.       fun->myProto = proto;
  495.       proto->next = hdr->functionProtos;
  496.       hdr->functionProtos = proto;
  497.       addToPackage (hdr, proto->id, proto);
  498.     }
  499.   }
  500.   // Make sure all prototypes have functions...
  501.   for (proto=hdr->functionProtos; proto; proto = proto->next) {
  502.     if (proto->isExternal == 0) {
  503.       if (proto->myFunction == NULL) {
  504.         error (proto, "The code file is missing a definition for this function");
  505.       }
  506.     }
  507.   }
  508.   // Move all functions into the header...
  509.   hdr->functions = code->functions;
  510.  
  511.   // Run though the interface's and add them to this header...
  512.   for (interface=code->interfaces; interface; interface = nextInterface) {
  513.     nextInterface = interface->next;
  514.     oldDef = hdr->packageMapping->find (interface->id);
  515.     if (oldDef) {
  516.       error (interface, "This name is already defined within this package");
  517.       error2 (oldDef, "Here is the other item with the same name");
  518.     } else {
  519.       addToPackage (hdr, interface->id, interface);
  520.       interface->isPrivate = 1;
  521.     }
  522.     // Add this interface to mainHeader's interface List...
  523.     interface->next = hdr->interfaces;
  524.     hdr->interfaces = interface;
  525.   }
  526.  
  527.   // Run though the classes and add them to this header...
  528.   for (cl=code->classes; cl; cl = nextClass) {
  529.     nextClass = cl->next;
  530.     oldDef = hdr->packageMapping->find (cl->id);
  531.     if (oldDef) {
  532.       error (cl, "This name is already defined within this package");
  533.       error2 (oldDef, "Here is the other item with the same name");
  534.     } else {
  535.       addToPackage (hdr, cl->id, cl);
  536.       cl->isPrivate = 1;
  537.     }
  538.     // Add this class to mainHeader's class List...
  539.     cl->next = hdr->classes;
  540.     hdr->classes = cl;
  541.   }
  542.  
  543.   // Run though the behaviors and add their methods to the
  544.   // corresponding classes...
  545.   behaviorMapping = new Mapping <String, AstNode> (20, NULL);
  546.   for (behav=code->behaviors; behav; behav = behav->next) {
  547.     // Make sure their is a corresponding class...
  548.     cl = (ClassDef *) hdr->packageMapping->find(behav->id);
  549.     if (cl) {
  550.       if (cl->op != CLASS_DEF) {
  551.         error (behav, "The name used here must match the name of a class");
  552.         error2 (cl, "Here is another item with the same name which is not a class");
  553.       } else {
  554.         // Make sure this behavior does not occur more than once...
  555.         oldDef = behaviorMapping->find (behav->id);
  556.         if (oldDef) {
  557.           error (behav, "There must not be multiple behaviors for any class");
  558.           error2 (oldDef, "Here is another behavior for this class");
  559.         } else {
  560.           // Make a note of this behavior and add its methods to the class...
  561.           behaviorMapping->enter (behav->id, behav);
  562.           if (behav->id->primitiveSymbol) {
  563.             error (behav, "This item happens to have the same name as that of a built-in primitive function; please select a different name");
  564.           }
  565.           cl->methods = behav->methods;
  566.           // Set all methods to point to their "owning" class...
  567.           for (meth = cl->methods; meth; meth = meth->next) {
  568.             meth->myClass = cl;
  569.           }
  570.         }
  571.       }
  572.     } else {
  573.       error (behav, "There is no corresponding class with this name");
  574.     }
  575.   }
  576.   delete behaviorMapping;
  577.  
  578. }
  579.  
  580.  
  581.  
  582. // addToPackage (hdr, id, item)
  583. //
  584. // This routine adds this item to the packageMapping in this header.
  585. //
  586. void addToPackage (Header * hdr, String * id, AstNode * item) {
  587.   hdr->packageMapping->enter (id, item);
  588.   if (id->primitiveSymbol) {
  589.     error (item, "This item happens to have the same name as that of a built-in primitive function; please select a different name");
  590.   }
  591. }
  592.  
  593.  
  594.  
  595. // topoProcessInterfaces (hdr)
  596. //
  597. // Run through all interfaces in this package.  Reorder the interface
  598. // list so that all interfaces come after interfaces they use.  Also set
  599. // the myDef field for every "typeArg" encountered.
  600. //
  601. void topoProcessInterfaces (Header * hdr) {
  602.   Interface * inter, * next;
  603.  
  604.   // printf ("Here is the interface list before topoProcessInterfaces:\n");
  605.   // for (inter = hdr->interfaces; inter; inter = inter->next) {
  606.   //   printf ("  %s\n", inter->id->chars);
  607.   // }
  608.  
  609.   // Run through all interfaces and set their "myHeader" field.
  610.   for (inter = hdr->interfaces; inter; inter = inter->next) {
  611.     inter->myHeader = hdr;
  612.   }
  613.  
  614.   // Run through all interfaces in this hdr and call topoProcessOneInterface on each.
  615.   tempInterList = NULL;
  616.   for (inter = hdr->interfaces; inter; inter = inter->next) {
  617.     topoProcessOneInterface (inter);
  618.   }
  619.  
  620.   // The tempInterList now contains all the interfaces, in order.  Go through it.
  621.   // For each interface, if it is in this header, put it on our "interfaces" list.
  622.   // The order will be reversed.
  623.   // printf ("\n\nGoing though tempInterList...\n");
  624.   hdr->interfaces = NULL;
  625.   for (inter = tempInterList; inter; inter = next) {
  626.     // printf ("  Looking at %s\n", inter->id->chars);
  627.     next = inter->tempNext;
  628.     inter->tempNext = NULL;
  629.     if (inter->myHeader == hdr) {
  630.       // printf ("      Adding it to hdr->interfaces\n");
  631.       inter->next = hdr->interfaces;
  632.       hdr->interfaces = inter;
  633.     }
  634.   }
  635.  
  636.   // printf ("Here is the interface list after topoProcessInterfaces:\n");
  637.   // for (inter = hdr->interfaces; inter != NULL; inter = inter->next) {
  638.   //   printf ("  %s\n", inter->id->chars);
  639.   // }
  640.  
  641. }
  642.  
  643.  
  644.  
  645. // topoProcessOneInterface (inter)
  646. //
  647. // Mark this interface as "in process".  Then call self recursively to process
  648. // all super-interfaces.  Finally mark this interface as "done" and add it to
  649. // the growing list of interfaces.  Also check for cycles.
  650. //
  651. void topoProcessOneInterface (Interface * inter) {
  652.   Interface * superInter;
  653.   TypeArg * typeArg;
  654.   NamedType * namedType;
  655.  
  656.   // printf ("=====  topoProcessOneInterface called on ");
  657.   // printString (stdout, inter->id);
  658.   // printf ("  (mark-in = %d)  =====\n", inter->mark);
  659.  
  660.   // This interface may have been done earlier in the topoProcessing...
  661.   if (inter->mark == 2) return;
  662.  
  663.   // Check for circularity...
  664.   if (inter->mark == 1) {
  665.     error (inter, "Circularity in interface-extends hierarchy (this interface appears to extend itself, possibly indirectly)");
  666.     return;
  667.   }
  668.  
  669.   // Set mark to "processing"...
  670.   inter->mark = 1;
  671.  
  672.   // Process all super-interfaces first...
  673.   for (typeArg = inter->extends; typeArg; typeArg = typeArg->next) {
  674.     namedType = (NamedType *) typeArg->type;
  675.     // printf ("  Looking at namedType = ");
  676.     // pretty (namedType);
  677.     if ((namedType == NULL) || (namedType->op != NAMED_TYPE)) {
  678.       programLogicError ("ParseInterface calls parseNamedType for extends clause");
  679.     }
  680.     superInter = (Interface *) inter->myHeader->packageMapping->find (namedType->id);
  681.     if (superInter == NULL) {
  682.       error (typeArg, "This interface could not be located");
  683.     } else if (superInter->op != INTERFACE) {
  684.       error (typeArg, "Interfaces may only extend other interfaces; this is not an interface");
  685.     } else {
  686.       namedType->myDef = superInter;
  687.       topoProcessOneInterface (superInter);
  688.     }
  689.   }
  690.  
  691.   // Set mark to "done"...
  692.   inter->mark = 2;
  693.  
  694.   // Put this one on the tempInterList...
  695.   inter->tempNext = tempInterList;
  696.   tempInterList = inter;
  697.  
  698. }
  699.  
  700.  
  701.  
  702. // topoProcessClasses (hdr)
  703. //
  704. // Run through all classes in this package.  Reorder the class
  705. // list so that all classes come after their superclass.  Also set
  706. // the myDef fields in the superclass and implements "namedType"s encountered.
  707. //
  708. void topoProcessClasses (Header * hdr) {
  709.   ClassDef * cl, * next;
  710.  
  711.   // printf ("Here is the class list before topoProcessClasses:\n");
  712.   // for (cl = hdr->classes; cl; cl = cl->next) {
  713.   //   printf ("  %s\n", cl->id->chars);
  714.   // }
  715.  
  716.   // Run through all classes and set their "myHeader" field.
  717.   for (cl = hdr->classes; cl; cl = cl->next) {
  718.     cl->myHeader = hdr;
  719.   }
  720.  
  721.   // Run through all classes in this hdr and call topoProcessOneClass on each.
  722.   tempClassList = NULL;
  723.   for (cl = hdr->classes; cl; cl = cl->next) {
  724.     topoProcessOneClass (cl);
  725.   }
  726.  
  727.   // The tempClassList now contains all the classes, in order.  Go through it.
  728.   // For each class, if it is in this header, put it on our "classes" list.
  729.   // The order will be reversed.
  730.   // printf ("\n\nGoing though tempClassList...\n");
  731.   hdr->classes = NULL;
  732.   for (cl = tempClassList; cl; cl = next) {
  733.     // printf ("  Looking at %s\n", cl->id->chars);
  734.     next = cl->tempNext;
  735.     cl->tempNext = NULL;
  736.     if (cl->myHeader == hdr) {
  737.       // printf ("      Adding it to hdr->classes\n");
  738.       cl->next = hdr->classes;
  739.       hdr->classes = cl;
  740.     }
  741.   }
  742.  
  743.   // printf ("Here is the class list after topoProcessClasses:\n");
  744.   // for (cl = hdr->classes; cl != NULL; cl = cl->next) {
  745.   //   printf ("  %s\n", cl->id->chars);
  746.   // }
  747.  
  748. }
  749.  
  750.  
  751.  
  752. // topoProcessOneClass (cl)
  753. //
  754. // Mark this class as "in process".  Then call self recursively to process
  755. // the super-class.  Finally mark this class as "done" and add it to
  756. // the growing list of classes.  Also check for cycles.
  757. //
  758. void topoProcessOneClass (ClassDef * cl) {
  759.   ClassDef * superclass;
  760.   Interface * superInter;
  761.   TypeArg * typeArg;
  762.   NamedType * namedType;
  763.  
  764.   // printf ("=====  topoProcessOneClass called on ");
  765.   // printString (stdout, cl->id);
  766.   // printf ("  (mark-in = %d)  =====\n", cl->mark);
  767.  
  768.   // This class may have been done earlier in the topoProcessing...
  769.   if (cl->mark == 2) return;
  770.  
  771.   // Check for circularity...
  772.   if (cl->mark == 1) {
  773.     error (cl, "Circularity in superclass hierarchy (this class appears to be a subclass of itself, possibly indirectly)");
  774.     return;
  775.   }
  776.  
  777.   // Set mark to "processing"...
  778.   cl->mark = 1;
  779.  
  780.   // Process the superclass first...
  781.   // printf ("  Looking at superclass = ");
  782.   // pretty (cl->superclass);
  783.   if (cl->superclass != NULL) {
  784.     superclass = (ClassDef *) cl->myHeader->packageMapping->find (cl->superclass->id);
  785.     if (superclass == NULL) {
  786.       error (cl->superclass, "This superclass could not be located");
  787.     } else if (superclass->op != CLASS_DEF) {
  788.       error (cl->superclass, "The thing listed in the superclass clause names something other than a class");
  789.     } else {
  790.       cl->superclass->myDef = superclass;
  791.       topoProcessOneClass (superclass);
  792.     }
  793.   }
  794.  
  795.   // Run through all the interfaces this class implements and set "myDef"...
  796.   for (typeArg = cl->implements; typeArg; typeArg = typeArg->next) {
  797.     namedType = (NamedType *) typeArg->type;
  798.     // printf ("  Looking at namedType = ");
  799.     // pretty (namedType);
  800.     if ((namedType == NULL) || (namedType->op != NAMED_TYPE)) {
  801.       programLogicError ("ParseClass calls parseNamedType for implements clause");
  802.     }
  803.     superInter = (Interface *) cl->myHeader->packageMapping->find (namedType->id);
  804.     if (superInter == NULL) {
  805.       error (typeArg, "This interface could not be located");
  806.     } else if (superInter->op != INTERFACE) {
  807.       error (typeArg, "Classes may only implement interfaces; this is not an interface");
  808.     } else {
  809.       namedType->myDef = superInter;
  810.     }
  811.   }
  812.  
  813.   // Set mark to "done"...
  814.   cl->mark = 2;
  815.  
  816.   // Put this one on the tempClassList...
  817.   cl->tempNext = tempClassList;
  818.   tempClassList = cl;
  819.  
  820. }
  821.  
  822.  
  823.  
  824. // bindTypeNames (node, typeMapping)
  825. //
  826. // This routine walks the entire Abstract Syntax Tree, visiting every node.
  827. // It looks for every "NamedType" node and fills in its "myDef", which can
  828. // point to either a ClassDef, Interface, TypeDef, or TypeParm.
  829. //
  830. // The "typeMapping" is a Mapping in which to look up type names.
  831. // It will be NULL only for Headers.
  832. //
  833. void bindTypeNames (AstNode * node,
  834.                     Mapping <String, AstNode> * typeMapping) {
  835.   Header * header;
  836.   Uses * uses;
  837.   Renaming * renaming;
  838.   Interface * interface;
  839.   ClassDef * cl;
  840.   Behavior * behavior;
  841.   TypeDef * typeDef;
  842.   ConstDecl * constDecl;
  843.   ErrorDecl * errorDecl;
  844.   FunctionProto * functionProto;
  845.   Function * fun;
  846.   MethodProto * methodProto;
  847.   Method * meth;
  848.   TypeParm * typeParm;
  849.   TypeArg * typeArg;
  850.   PtrType * pType;
  851.   ArrayType * aType;
  852.   RecordType * rType;
  853.   FunctionType * fType;
  854.   NamedType * nType;
  855.   IfStmt * ifStmt;
  856.   AssignStmt * assignStmt;
  857.   CallStmt * callStmt;
  858.   SendStmt * sendStmt;
  859.   WhileStmt * whileStmt;
  860.   DoStmt * doStmt;
  861.   BreakStmt * breakStmt;
  862.   ContinueStmt * continueStmt;
  863.   ReturnStmt * returnStmt;
  864.   ForStmt * forStmt;
  865.   SwitchStmt * switchStmt;
  866.   TryStmt * tryStmt;
  867.   ThrowStmt * throwStmt;
  868.   FreeStmt * freeStmt;
  869.   DebugStmt * debugStmt;
  870.   Case * cas;
  871.   Catch * cat;
  872.   Global * global;
  873.   Local * local;
  874.   Parameter * parm;
  875.   ClassField * classField;
  876.   RecordField * recordField;
  877.   CallExpr * callExpr;
  878.   SendExpr * sendExpr;
  879.   FieldAccess * fieldAccess;
  880.   ArrayAccess * arrayAccess;
  881.   Constructor * constructor;
  882.   ClosureExpr * closureExpr;
  883.   AsPtrToExpr * asPtrToExpr;
  884.   AsIntegerExpr * asIntegerExpr;
  885.   ArraySizeExpr * arraySizeExpr;
  886.   IsInstanceOfExpr * isInstanceOfExpr;
  887.   IsKindOfExpr * isKindOfExpr;
  888.   SizeOfExpr * sizeOfExpr;
  889.   Argument * arg;
  890.   CountValue * countValue;
  891.   FieldInit * fieldInit;
  892.   AstNode * def;
  893.   Mapping <String, AstNode> * newMap;
  894.   Type * t1, * t2;
  895.   // Mapping <TypeParm, Type> * testingMap;
  896.  
  897.   if (node == NULL) return;
  898.  
  899.   // printf ("Binding types in %s...\n", symbolName (node->op));
  900.  
  901.   switch (node->op) {
  902.  
  903.     case HEADER:
  904.       header = (Header *) node;
  905.       // printf ("  %s\n", header->packageName->chars);
  906.       // printf ("  Point 0... header = %08x\n", header);
  907.       if (header->packageMapping == NULL) return;
  908.       bindTypeNames (header->uses, header->packageMapping);
  909.       bindTypeNames (header->consts, header->packageMapping);
  910.       bindTypeNames (header->errors, header->packageMapping);
  911.       bindTypeNames (header->globals, header->packageMapping);
  912.       bindTypeNames (header->typeDefs, header->packageMapping);
  913.       bindTypeNames (header->functionProtos, header->packageMapping);
  914.       bindTypeNames (header->functions, header->packageMapping);
  915.       bindTypeNames (header->interfaces, header->packageMapping);
  916.       bindTypeNames (header->classes, header->packageMapping);
  917.       // bindTypeNames (header->next, typeMapping);
  918.       return;
  919.  
  920.     case CODE:
  921.       // code = (Code *) node;
  922.       // We have added all this stuff to the header, so skip doing it a second time.
  923.       // bindTypeNames (code->consts, typeMapping);
  924.       // bindTypeNames (code->globals, typeMapping);
  925.       // bindTypeNames (code->typeDefs, typeMapping);
  926.       // bindTypeNames (code->functions, typeMapping);
  927.       // bindTypeNames (code->interfaces, typeMapping);
  928.       // bindTypeNames (code->classes, typeMapping);
  929.       // bindTypeNames (code->behaviors, typeMapping);
  930.       return;
  931.  
  932.     case USES:
  933.       uses = (Uses *) node;
  934.       // printf ("  %s\n", uses->id->chars);
  935.       bindTypeNames (uses->renamings, typeMapping);
  936.       bindTypeNames (uses->next, typeMapping);
  937.       return;
  938.  
  939.     case RENAMING:
  940.       renaming = (Renaming *) node;
  941.       bindTypeNames (renaming->next, typeMapping);
  942.       return;
  943.  
  944.     case INTERFACE:
  945.       interface = (Interface *) node;
  946.       // printf ("  %s\n", interface->id->chars);
  947.       // Run through our type parms and add them to the mapping...
  948.       if (interface->typeParms) {
  949.         newMap = new Mapping <String, AstNode> (5, typeMapping);
  950.         for (typeParm = interface->typeParms; typeParm; typeParm = typeParm->next) {
  951.           def = newMap->find (typeParm->id);
  952.           if (def) {
  953.             error (typeParm, "The name for this type parameter is already in use"); 
  954.             error2 (def, "Here is something else with the same name");
  955.           } else {
  956.             newMap->enter (typeParm->id, typeParm);
  957.             if (typeParm->id->primitiveSymbol) {
  958.               error (typeParm, "This item happens to have the same name as that of a built-in primitive function; please select a different name");
  959.             }
  960.           }
  961.         }
  962.       } else {
  963.         newMap = typeMapping;
  964.       }
  965.       bindTypeNames (interface->typeParms, typeMapping);
  966.       bindTypeNames (interface->extends, newMap);
  967.       bindTypeNames (interface->methodProtos, newMap);
  968.       bindTypeNames (interface->next, typeMapping);
  969.       return;
  970.  
  971.     case CLASS_DEF:
  972.       cl = (ClassDef *) node;
  973.       // printf ("==========  Processing class %s  ==========\n", cl->id->chars);
  974.       // printf ("  %s\n", cl->id->chars);
  975.       // Run through our type parms and add them to the mapping...
  976.       if (cl->typeParms) {
  977.         newMap = new Mapping <String, AstNode> (5, typeMapping);
  978.  
  979. // testing:
  980. //        testingMap = new Mapping <TypeParm, Type> (5, NULL);
  981.  
  982.         for (typeParm = cl->typeParms; typeParm; typeParm = typeParm->next) {
  983.           def = newMap->find (typeParm->id);
  984.           if (def) {
  985.             error (typeParm, "The name for this type parameter is already in use"); 
  986.             error2 (def, "Here is something else with the same name");
  987.           } else {
  988.             newMap->enter (typeParm->id, typeParm);
  989.             if (typeParm->id->primitiveSymbol) {
  990.               error (typeParm, "This item happens to have the same name as that of a built-in primitive function; please select a different name");
  991.             }
  992.  
  993. // testing:
  994. //          testingMap->enter (typeParm, typeParm->type);
  995.  
  996.           }
  997.         }
  998.       } else {
  999.         newMap = typeMapping;
  1000.       }
  1001.       bindTypeNames (cl->typeParms, typeMapping);
  1002.       bindTypeNames (cl->implements, newMap);  // class "C[T:O] implements D[T]" is OK
  1003.       bindTypeNames (cl->superclass, newMap);  // class "C[T:O] superclass D[T]" is OK
  1004.       bindTypeNames (cl->fields, newMap);
  1005.       bindTypeNames (cl->methodProtos, newMap);
  1006.       bindTypeNames (cl->methods, newMap);
  1007.       bindTypeNames (cl->next, typeMapping);
  1008.       // printf ("==========  End class %s  ==========\n", cl->id->chars);
  1009.  
  1010. //---------- This is for testing only ------------------
  1011. //
  1012. //  To use this code, use something like this:
  1013. //           class C [T1: int, T2: double]
  1014. //             superclass Object
  1015. //             fields
  1016. //               x: ptr to T2
  1017. //           endClass
  1018. //
  1019. //      if (cl->id == lookupAndAdd ("C", ID)) {
  1020. //        if (cl->fields) {
  1021. //          t1 = cl->fields->type;
  1022. //          t2 = copyTypeWithSubst (t1, testingMap);
  1023. //          printf ("==========  Before  ==========\n");
  1024. //          printAst (6, t1);
  1025. //          printf ("==========  After  ===========\n");
  1026. //          printAst (6, t2);
  1027. //          printf ("==============================\n");
  1028. //        }
  1029. //      }
  1030. //--------------------------------------------------------
  1031.  
  1032.       return;
  1033.  
  1034.     case BEHAVIOR:
  1035.       behavior = (Behavior *) node;
  1036.       // printf ("  %s\n", behavior->id->chars);
  1037.       bindTypeNames (behavior->methods, typeMapping);
  1038.       bindTypeNames (behavior->next, typeMapping);
  1039.       return;
  1040.  
  1041.     case TYPE_DEF:
  1042.       typeDef = (TypeDef *) node;
  1043.       // printf ("  %s\n", typeDef->id->chars);
  1044.       bindTypeNames (typeDef->type, typeMapping);
  1045.       bindTypeNames (typeDef->next, typeMapping);
  1046.       return;
  1047.  
  1048.     case CONST_DECL:
  1049.       constDecl = (ConstDecl *) node;
  1050.       // printf ("  %s\n", constDecl->id->chars);
  1051.       bindTypeNames (constDecl->expr, typeMapping);
  1052.       bindTypeNames (constDecl->next, typeMapping);
  1053.       return;
  1054.  
  1055.     case ERROR_DECL:
  1056.       errorDecl = (ErrorDecl *) node;
  1057.       // printf ("  %s\n", errorDecl->id->chars);
  1058.       bindTypeNames (errorDecl->parmList, typeMapping);
  1059.       bindTypeNames (errorDecl->next, typeMapping);
  1060.       return;
  1061.  
  1062.     case FUNCTION_PROTO:
  1063.       functionProto = (FunctionProto *) node;
  1064.       // printf ("  %s\n", functionProto->id->chars);
  1065.       bindTypeNames (functionProto->parmList, typeMapping);
  1066.       bindTypeNames (functionProto->retType, typeMapping);
  1067.       bindTypeNames (functionProto->next, typeMapping);
  1068.       return;
  1069.  
  1070.     case FUNCTION:
  1071.       fun = (Function *) node;
  1072.       // if (fun->id) {
  1073.       //   printf ("    Within function %s\n", fun->id->chars);
  1074.       // } else {
  1075.       //   printf ("    Within closure\n");
  1076.       // }
  1077.       bindTypeNames (fun->parmList, typeMapping);
  1078.       bindTypeNames (fun->retType, typeMapping);
  1079.       bindTypeNames (fun->locals, typeMapping);
  1080.       bindTypeNames (fun->stmts, typeMapping);
  1081.       bindTypeNames (fun->next, typeMapping);
  1082.       return;
  1083.  
  1084.     case METHOD_PROTO:
  1085.       methodProto = (MethodProto *) node;
  1086.       // printf ("  %s\n", methodProto->selector->chars);
  1087.       bindTypeNames (methodProto->parmList, typeMapping);
  1088.       bindTypeNames (methodProto->retType, typeMapping);
  1089.       bindTypeNames (methodProto->next, typeMapping);
  1090.       return;
  1091.  
  1092.     case METHOD:
  1093.       meth = (Method *) node;
  1094.       // printf ("  %s\n", meth->selector->chars);
  1095.       bindTypeNames (meth->parmList, typeMapping);
  1096.       bindTypeNames (meth->retType, typeMapping);
  1097.       bindTypeNames (meth->locals, typeMapping);
  1098.       bindTypeNames (meth->stmts, typeMapping);
  1099.       bindTypeNames (meth->next, typeMapping);
  1100.       return;
  1101.  
  1102.     case TYPE_PARM:
  1103.       typeParm = (TypeParm *) node;
  1104.       bindTypeNames (typeParm->type, typeMapping);
  1105.       bindTypeNames (typeParm->next, typeMapping);
  1106.       return;
  1107.  
  1108.     case TYPE_ARG:
  1109.       typeArg = (TypeArg *) node;
  1110.       bindTypeNames (typeArg->type, typeMapping);
  1111.       bindTypeNames (typeArg->next, typeMapping);
  1112.       return;
  1113.  
  1114.     case CHAR_TYPE:
  1115.       return;
  1116.  
  1117.     case INT_TYPE:
  1118.       return;
  1119.  
  1120.     case DOUBLE_TYPE:
  1121.       return;
  1122.  
  1123.     case BOOL_TYPE:
  1124.       return;
  1125.  
  1126.     case VOID_TYPE:
  1127.       return;
  1128.  
  1129.     case TYPE_OF_NULL_TYPE:
  1130.       return;
  1131.  
  1132.     case ANY_TYPE:
  1133.       return;
  1134.  
  1135.     case PTR_TYPE:
  1136.       pType = (PtrType *) node;
  1137.       bindTypeNames (pType->baseType, typeMapping);
  1138.       return;
  1139.  
  1140.     case ARRAY_TYPE:
  1141.       aType = (ArrayType *) node;
  1142.       bindTypeNames (aType->sizeExpr, typeMapping);
  1143.       bindTypeNames (aType->baseType, typeMapping);
  1144.       return;
  1145.  
  1146.     case RECORD_TYPE:
  1147.       rType = (RecordType *) node;
  1148.       bindTypeNames (rType->fields, typeMapping);
  1149.       return;
  1150.  
  1151.     case FUNCTION_TYPE:
  1152.       fType = (FunctionType *) node;
  1153.       bindTypeNames (fType->parmTypes, typeMapping);
  1154.       bindTypeNames (fType->retType, typeMapping);
  1155.       return;
  1156.  
  1157.     case NAMED_TYPE:
  1158.       nType = (NamedType *) node;
  1159.       // printf ("  %s\n", nType->id->chars);
  1160.       def = typeMapping->find (nType->id);
  1161.       if (def == NULL) {
  1162.         error (nType, "This type name is undefined");
  1163.       } else {
  1164.         if ((def->op == CLASS_DEF) ||
  1165.             (def->op == INTERFACE) ||
  1166.             (def->op == TYPE_DEF) ||
  1167.             (def->op == TYPE_PARM)) {
  1168.           if (nType->myDef) {
  1169.             if (nType->myDef != def) {
  1170.               programLogicError ("myDef already filled in with something different");
  1171.             }
  1172.           } else {
  1173.             // We'll check for this error in checkTypes, so don't do it here...
  1174.             // if ((def->op == TYPE_DEF) ||
  1175.             //     (def->op == TYPE_PARM)) {
  1176.             //   if (nType->typeArgs != NULL) {
  1177.             //     error (nType, "Parameters are not expected after this type name");
  1178.             //   }
  1179.             // }
  1180.             nType->myDef = def;
  1181.           }
  1182.         } else {
  1183.           error (nType, "This type names something that is not a class, interface, typeDef, or type parameter");
  1184.           error2 (def, "Here is the item being named");
  1185.         }
  1186.       }
  1187.       bindTypeNames (nType->typeArgs, typeMapping);
  1188.       return;
  1189.  
  1190.     case IF_STMT:
  1191.       ifStmt = (IfStmt *) node;
  1192.       bindTypeNames (ifStmt->expr, typeMapping);
  1193.       bindTypeNames (ifStmt->thenStmts, typeMapping);
  1194.       bindTypeNames (ifStmt->elseStmts, typeMapping);
  1195.       bindTypeNames (ifStmt->next, typeMapping);
  1196.       return;
  1197.  
  1198.     case ASSIGN_STMT:
  1199.       assignStmt = (AssignStmt *) node;
  1200.       bindTypeNames (assignStmt->lvalue, typeMapping);
  1201.       bindTypeNames (assignStmt->expr, typeMapping);
  1202.       bindTypeNames (assignStmt->next, typeMapping);
  1203.       return;
  1204.  
  1205.     case CALL_STMT:
  1206.       callStmt = (CallStmt *) node;
  1207.       bindTypeNames (callStmt->expr, typeMapping);
  1208.       bindTypeNames (callStmt->next, typeMapping);
  1209.       return;
  1210.  
  1211.     case SEND_STMT:
  1212.       sendStmt = (SendStmt *) node;
  1213.       bindTypeNames (sendStmt->expr, typeMapping);
  1214.       bindTypeNames (sendStmt->next, typeMapping);
  1215.       return;
  1216.  
  1217.     case WHILE_STMT:
  1218.       whileStmt = (WhileStmt *) node;
  1219.       bindTypeNames (whileStmt->expr, typeMapping);
  1220.       bindTypeNames (whileStmt->stmts, typeMapping);
  1221.       bindTypeNames (whileStmt->next, typeMapping);
  1222.       return;
  1223.  
  1224.     case DO_STMT:
  1225.       doStmt = (DoStmt *) node;
  1226.       bindTypeNames (doStmt->stmts, typeMapping);
  1227.       bindTypeNames (doStmt->expr, typeMapping);
  1228.       bindTypeNames (doStmt->next, typeMapping);
  1229.       return;
  1230.  
  1231.     case BREAK_STMT:
  1232.       breakStmt = (BreakStmt *) node;
  1233.       bindTypeNames (breakStmt->next, typeMapping);
  1234.       return;
  1235.  
  1236.     case CONTINUE_STMT:
  1237.       continueStmt = (ContinueStmt *) node;
  1238.       bindTypeNames (continueStmt->next, typeMapping);
  1239.       return;
  1240.  
  1241.     case RETURN_STMT:
  1242.       returnStmt = (ReturnStmt *) node;
  1243.       bindTypeNames (returnStmt->expr, typeMapping);
  1244.       bindTypeNames (returnStmt->next, typeMapping);
  1245.       return;
  1246.  
  1247.     case FOR_STMT:
  1248.       forStmt = (ForStmt *) node;
  1249.       bindTypeNames (forStmt->lvalue, typeMapping);
  1250.       bindTypeNames (forStmt->expr1, typeMapping);
  1251.       bindTypeNames (forStmt->expr2, typeMapping);
  1252.       bindTypeNames (forStmt->expr3, typeMapping);
  1253.       bindTypeNames (forStmt->stmts, typeMapping);
  1254.       bindTypeNames (forStmt->next, typeMapping);
  1255.       return;
  1256.  
  1257.     case SWITCH_STMT:
  1258.       switchStmt = (SwitchStmt *) node;
  1259.       bindTypeNames (switchStmt->expr, typeMapping);
  1260.       bindTypeNames (switchStmt->caseList, typeMapping);
  1261.       bindTypeNames (switchStmt->defaultStmts, typeMapping);
  1262.       bindTypeNames (switchStmt->next, typeMapping);
  1263.       return;
  1264.  
  1265.     case TRY_STMT:
  1266.       tryStmt = (TryStmt *) node;
  1267.       bindTypeNames (tryStmt->stmts, typeMapping);
  1268.       bindTypeNames (tryStmt->catchList, typeMapping);
  1269.       bindTypeNames (tryStmt->next, typeMapping);
  1270.       return;
  1271.  
  1272.     case THROW_STMT:
  1273.       throwStmt = (ThrowStmt *) node;
  1274.       errorDecl = currentHeader->errorMapping->find (throwStmt->id);
  1275.       if (errorDecl == NULL) {
  1276.         error (throwStmt, "There is no declaration for the error named in this TRY statement");
  1277.       } else if (errorDecl->op != ERROR_DECL) {
  1278.         programLogicError ("We only store ErrorDecls in this mapping");
  1279.       }
  1280.       throwStmt->myDef = errorDecl;
  1281.       bindTypeNames (throwStmt->argList, typeMapping);
  1282.       bindTypeNames (throwStmt->next, typeMapping);
  1283.       return;
  1284.  
  1285.     case FREE_STMT:
  1286.       freeStmt = (FreeStmt *) node;
  1287.       bindTypeNames (freeStmt->expr, typeMapping);
  1288.       bindTypeNames (freeStmt->next, typeMapping);
  1289.       return;
  1290.  
  1291.     case DEBUG_STMT:
  1292.       debugStmt = (DebugStmt *) node;
  1293.       bindTypeNames (debugStmt->next, typeMapping);
  1294.       return;
  1295.  
  1296.     case CASE:
  1297.       cas = (Case *) node;
  1298.       bindTypeNames (cas->expr, typeMapping);
  1299.       bindTypeNames (cas->stmts, typeMapping);
  1300.       bindTypeNames (cas->next, typeMapping);
  1301.       return;
  1302.  
  1303.     case CATCH:
  1304.       cat = (Catch *) node;
  1305.       errorDecl = currentHeader->errorMapping->find (cat->id);
  1306.       if (errorDecl == NULL) {
  1307.         error (cat, "There is no declaration for the error named in this CATCH clause");
  1308.       } else if (errorDecl->op != ERROR_DECL) {
  1309.         programLogicError ("We only store ErrorDecls in this mapping");
  1310.       }
  1311.       cat->myDef = errorDecl;
  1312.       bindTypeNames (cat->parmList, typeMapping);
  1313.       bindTypeNames (cat->stmts, typeMapping);
  1314.       bindTypeNames (cat->next, typeMapping);
  1315.       return;
  1316.  
  1317.     case GLOBAL:
  1318.       global = (Global *) node;
  1319.       bindTypeNames (global->type, typeMapping);
  1320.       bindTypeNames (global->initExpr, typeMapping);
  1321.       bindTypeNames (global->next, typeMapping);
  1322.       return;
  1323.  
  1324.     case LOCAL:
  1325.       local = (Local *) node;
  1326.       bindTypeNames (local->type, typeMapping);
  1327.       bindTypeNames (local->initExpr, typeMapping);
  1328.       bindTypeNames (local->next, typeMapping);
  1329.       return;
  1330.  
  1331.     case PARAMETER:
  1332.       parm = (Parameter *) node;
  1333.       bindTypeNames (parm->type, typeMapping);
  1334.       bindTypeNames (parm->next, typeMapping);
  1335.       return;
  1336.  
  1337.     case CLASS_FIELD:
  1338.       classField = (ClassField *) node;
  1339.       bindTypeNames (classField->type, typeMapping);
  1340.       bindTypeNames (classField->next, typeMapping);
  1341.       return;
  1342.  
  1343.     case RECORD_FIELD:
  1344.       recordField = (RecordField *) node;
  1345.       bindTypeNames (recordField->type, typeMapping);
  1346.       bindTypeNames (recordField->next, typeMapping);
  1347.       return;
  1348.  
  1349.     case INT_CONST:
  1350.       return;
  1351.  
  1352.     case DOUBLE_CONST:
  1353.       return;
  1354.  
  1355.     case CHAR_CONST:
  1356.       return;
  1357.  
  1358.     case STRING_CONST:
  1359.       return;
  1360.  
  1361.     case BOOL_CONST:
  1362.       return;
  1363.  
  1364.     case NULL_CONST:
  1365.       return;
  1366.  
  1367.     case CALL_EXPR:
  1368.       callExpr = (CallExpr *) node;
  1369.       bindTypeNames (callExpr->argList, typeMapping);
  1370.       return;
  1371.  
  1372.     case SEND_EXPR:
  1373.       sendExpr = (SendExpr *) node;
  1374.       bindTypeNames (sendExpr->receiver, typeMapping);
  1375.       bindTypeNames (sendExpr->argList, typeMapping);
  1376.       return;
  1377.  
  1378.     case SELF_EXPR:
  1379.       return;
  1380.  
  1381.     case SUPER_EXPR:
  1382.       return;
  1383.  
  1384.     case FIELD_ACCESS:
  1385.       fieldAccess = (FieldAccess *) node;
  1386.       bindTypeNames (fieldAccess->expr, typeMapping);
  1387.       return;
  1388.  
  1389.     case ARRAY_ACCESS:
  1390.       arrayAccess = (ArrayAccess *) node;
  1391.       bindTypeNames (arrayAccess->arrayExpr, typeMapping);
  1392.       bindTypeNames (arrayAccess->indexExpr, typeMapping);
  1393.       return;
  1394.  
  1395.     case CONSTRUCTOR:
  1396.       constructor = (Constructor *) node;
  1397.       bindTypeNames (constructor->type, typeMapping);
  1398.       bindTypeNames (constructor->countValueList, typeMapping);
  1399.       bindTypeNames (constructor->fieldInits, typeMapping);
  1400.       return;
  1401.  
  1402.     case CLOSURE_EXPR:
  1403.       closureExpr = (ClosureExpr *) node;
  1404.       bindTypeNames (closureExpr->function, typeMapping);
  1405.       // Add this closure to the list of closures...
  1406.       if (mainHeader == NULL) {
  1407.         programLogicError ("mainHeader should not be NULL");
  1408.       }
  1409.       if (closureExpr->function == NULL) {
  1410.         programLogicError ("We should have a function here");
  1411.       }
  1412.       if (closureExpr->function->next) {
  1413.         programLogicError ("closureExpr->function->next should be NULL");
  1414.       }
  1415.       closureExpr->function->next = mainHeader->closures;
  1416.       mainHeader->closures = closureExpr->function;
  1417.       return;
  1418.  
  1419.     case VARIABLE_EXPR:
  1420.       return;
  1421.  
  1422.     case AS_PTR_TO_EXPR:
  1423.       asPtrToExpr = (AsPtrToExpr *) node;
  1424.       bindTypeNames (asPtrToExpr->expr, typeMapping);
  1425.       bindTypeNames (asPtrToExpr->type, typeMapping);
  1426.       return;
  1427.  
  1428.     case AS_INTEGER_EXPR:
  1429.       asIntegerExpr = (AsIntegerExpr *) node;
  1430.       bindTypeNames (asIntegerExpr->expr, typeMapping);
  1431.       return;
  1432.  
  1433.     case ARRAY_SIZE_EXPR:
  1434.       arraySizeExpr = (ArraySizeExpr *) node;
  1435.       bindTypeNames (arraySizeExpr->expr, typeMapping);
  1436.       return;
  1437.  
  1438.     case IS_INSTANCE_OF_EXPR:
  1439.       isInstanceOfExpr = (IsInstanceOfExpr *) node;
  1440.       bindTypeNames (isInstanceOfExpr->expr, typeMapping);
  1441.       bindTypeNames (isInstanceOfExpr->type, typeMapping);
  1442.       return;
  1443.  
  1444.     case IS_KIND_OF_EXPR:
  1445.       isKindOfExpr = (IsKindOfExpr *) node;
  1446.       bindTypeNames (isKindOfExpr->expr, typeMapping);
  1447.       bindTypeNames (isKindOfExpr->type, typeMapping);
  1448.       return;
  1449.  
  1450.     case SIZE_OF_EXPR:
  1451.       sizeOfExpr = (SizeOfExpr *) node;
  1452.       bindTypeNames (sizeOfExpr->type, typeMapping);
  1453.       return;
  1454.  
  1455.     case ARGUMENT:
  1456.       arg = (Argument *) node;
  1457.       bindTypeNames (arg->expr, typeMapping);
  1458.       bindTypeNames (arg->next, typeMapping);
  1459.       return;
  1460.  
  1461.     case COUNT_VALUE:
  1462.       countValue = (CountValue *) node;
  1463.       bindTypeNames (countValue->count, typeMapping);
  1464.       bindTypeNames (countValue->value, typeMapping);
  1465.       bindTypeNames (countValue->next, typeMapping);
  1466.       return;
  1467.  
  1468.     case FIELD_INIT:
  1469.       fieldInit = (FieldInit *) node;
  1470.       bindTypeNames (fieldInit->expr, typeMapping);
  1471.       bindTypeNames (fieldInit->next, typeMapping);
  1472.       return;
  1473.  
  1474.     default:
  1475.       printf ("\nnode->op = %s\n", symbolName (node->op));
  1476.       programLogicError ("Unkown op in bindTypeNames");
  1477.   }
  1478. }
  1479.  
  1480.  
  1481.  
  1482. // checkTypeDefCircularity (hdr)
  1483. //
  1484. // This routine checks that for the following sort of error:
  1485. //     type S = T
  1486. //          T = U
  1487. //          U = S
  1488. // Also, in cases like this:
  1489. //     type T = S
  1490. //          S = record...
  1491. // it redirects the typedef for T to point straight to the underlying type.
  1492. //
  1493. // Note that it does nothing for typedefs like this:
  1494. //     type T = S[U,V]
  1495. //
  1496. void checkTypeDefCircularity (Header * hdr) {
  1497.   TypeDef * typeDef;
  1498.   // Run through all typedefs...
  1499.   for (typeDef = hdr->typeDefs; typeDef; typeDef = typeDef->next) {
  1500.     typeDef->type = findCoreType (typeDef->type);
  1501.   }
  1502. }
  1503.  
  1504.  
  1505.  
  1506. // findCoreType (typ)
  1507. //
  1508. // This routine is passed a type.  If there are indirections (due to aliasing)
  1509. // it returns the underlying type.  If there are problems due to cirularity,
  1510. // it returns VoidType.
  1511. //
  1512. Type * findCoreType (Type * typ) {
  1513.   NamedType * nType;
  1514.   Type * t;
  1515.   TypeDef * typeDef;
  1516.   AstNode * def;
  1517.  
  1518.   if (typ == NULL) {
  1519.     programLogicError ("In findCoreType, 'typ' should never be NULL");
  1520.   }
  1521.   switch (typ->op) {
  1522.     case CHAR_TYPE:
  1523.     case INT_TYPE:
  1524.     case DOUBLE_TYPE:
  1525.     case BOOL_TYPE:
  1526.     case VOID_TYPE:
  1527.     case TYPE_OF_NULL_TYPE:
  1528.     case ANY_TYPE:
  1529.     case PTR_TYPE:
  1530.     case ARRAY_TYPE:
  1531.     case RECORD_TYPE:
  1532.     case FUNCTION_TYPE:
  1533.       return typ;
  1534.     case NAMED_TYPE:
  1535.       nType = (NamedType *) typ;
  1536.       if (nType->typeArgs) {
  1537.         return typ;
  1538.       }
  1539.       def = nType->myDef;
  1540.       if (def != NULL) {
  1541.         if (def->op == TYPE_DEF) {
  1542.           typeDef = (TypeDef *) def;
  1543.           if (typeDef->mark != 0) {
  1544.             error (typeDef, "This type definition is involved in a circular definition");
  1545.           } else {
  1546.             typeDef->mark = 1;
  1547.             typeDef->type = findCoreType (typeDef->type);
  1548.             typeDef->mark = 0;
  1549.             return typeDef->type;
  1550.           }
  1551.         } else {  // it is CLASS, INTERFACE, TYPE_PARM
  1552.           return typ;
  1553.         }
  1554.       }
  1555.       t = new VoidType ();
  1556.       t->positionAt (typ);
  1557.       return t;
  1558.   }
  1559. }
  1560.  
  1561.  
  1562.  
  1563. // copyTypeWithSubst (type, subst)
  1564. //
  1565. // This routine is passed a Type and a substitution.  A substitution is
  1566. // a mapping from type parameters names to types.  This routine constructs
  1567. // and returns a new type, after performing the substitution.
  1568. //
  1569. // This routine tries to share as much of the source structure as possible,
  1570. // so pieces of types may be shared.  Types are DAGS, not trees.
  1571. //
  1572. // Note: In the case of ArrayTypes which get copied, we will always share
  1573. // the 'sizeExpr'.  This expression may contain type parameters, as in:
  1574. //      array [4 * sizeOf T] of int
  1575. // These type parameters will not get substituted.  The motivation for not
  1576. // coying is that copied types are only used in type checking, and never
  1577. // in code generation.  The sizeExpr is never used in type checking.
  1578. //
  1579. // To test this code, consult the disabled testing code in the routine
  1580. // "bindTypeNames()", in the CLASS_DEF case.
  1581. //
  1582. // Tested.
  1583. //
  1584. Type * copyTypeWithSubst (Type * type, Mapping <TypeParm, Type> * subst) {
  1585.   PtrType * pType, * newPType;
  1586.   ArrayType * aType, *newAType;
  1587.   NamedType * nType, * newNType;
  1588.   RecordType * rType, * newRType;
  1589.   FunctionType * fType, * newFType;
  1590.   RecordField * newFieldList;
  1591.   Type * newBase, * newType, * newRetType;
  1592.   TypeArg * newArgList;
  1593.  
  1594.   if (type == NULL) return NULL;
  1595.  
  1596.   // printf ("Entering copyTypeWithSubst.  type = ");
  1597.   // pretty (type);
  1598.  
  1599.   if (subst == NULL) return type;
  1600.  
  1601.   if (type->op == NAMED_TYPE) {
  1602.     nType = (NamedType * ) type;
  1603.     if (nType->myDef == NULL) return type;    // If prev. errors...
  1604.     if ((nType->myDef)->op == TYPE_PARM) {
  1605.       newType = subst->find ((TypeParm *) (nType->myDef));
  1606.       if (newType == NULL) {
  1607.         // printf ("Returning.  This is a TYPE_PARM without a value.  Returning ");
  1608.         // pretty (type); 
  1609.         return type;
  1610.       }
  1611.       // printf ("Returning.  This is a TYPE_PARM with a value.  Returning ");
  1612.       // pretty (newType); 
  1613.       return newType;
  1614.     } else {
  1615.       // Build a new arglist, performing the substitution.
  1616.       newArgList = copyArgListWithSubst (nType->typeArgs, subst);
  1617.  
  1618.       // If the new type will look the same, then return the old type.
  1619.       if (newArgList == nType->typeArgs) {
  1620.         // printf ("Returning.  The type is unchanged... ");
  1621.         // pretty (type);
  1622.         return type;
  1623.       }
  1624.  
  1625.       // Build a new NamedType object and return it.
  1626.       // printf ("Returning.  Building new NamedType for... ");
  1627.       // pretty (type);
  1628.       newNType = new NamedType ();
  1629.       newNType->positionAt (nType);
  1630.       newNType->id = nType->id;
  1631.       newNType->myDef = nType->myDef;
  1632.       newNType->typeArgs = newArgList;
  1633.       // printf ("            Here it is the new thing...   ");
  1634.       // pretty (newNType);
  1635.       return newNType;
  1636.     }
  1637.   } else if (type->op == RECORD_TYPE) {
  1638.     rType = (RecordType * ) type;
  1639.     // Build a new Fieldlist, performing the substitution.
  1640.     newFieldList = copyRecordFieldsWithSubst (rType->fields, subst);
  1641.  
  1642.     // If the new type will look the same, then return the old type.
  1643.     if (newFieldList == rType->fields) {
  1644.       // printf ("Returning.  The type is unchanged... ");
  1645.       // pretty (type);
  1646.       return type;
  1647.     }
  1648.  
  1649.     // Build a new RecordType object and return it.
  1650.     // printf ("Returning.  Building new RecordType for... ");
  1651.     // pretty (type);
  1652.     newRType = new RecordType ();
  1653.     newRType->positionAt (rType);
  1654.     newRType->fields = newFieldList;
  1655.     // printf ("            Here it is the new thing...   ");
  1656.     // pretty (newRType);
  1657.     return newRType;
  1658.   } else if (type->op == PTR_TYPE) {
  1659.     pType = (PtrType *) type;
  1660.     newBase = copyTypeWithSubst (pType->baseType, subst);
  1661.     // If the new type will look the same, then return the old type.
  1662.     if (newBase == pType->baseType) {
  1663.       // printf ("Returning.  The type is unchanged... ");
  1664.       // pretty (type);
  1665.       return type;
  1666.     }
  1667.     // printf ("Returning.  Building new PtrType for... ");
  1668.     // pretty (type);
  1669.     newPType = new PtrType ();
  1670.     newPType->positionAt (pType);
  1671.     newPType->baseType = newBase;
  1672.     // printf ("            Here it is the new thing...   ");
  1673.     // pretty (newPType);
  1674.     return newPType;
  1675.   } else if (type->op == ARRAY_TYPE) {
  1676.     aType = (ArrayType *) type;
  1677.     newBase = copyTypeWithSubst (aType->baseType, subst);
  1678.     // If the new type will look the same, then return the old type.
  1679.     if (newBase == aType->baseType) {
  1680.       // printf ("Returning.  The type is unchanged... ");
  1681.       // pretty (type);
  1682.       return type;
  1683.     }
  1684.     // Build a new ArrayType object and return it.
  1685.     // printf ("Returning.  Building new ArrayType for... ");
  1686.     // pretty (type);
  1687.     newAType = new ArrayType ();
  1688.     newAType->positionAt (aType);
  1689.     // We will not copy the sizeExpr, although it could (in theory) contain
  1690.     // instances of type variables....  Perhaps it should be copied, too...
  1691.     newAType->sizeExpr = aType->sizeExpr;
  1692.     // These two lines added to fix bug...
  1693.     newAType->sizeOfElements = aType->sizeOfElements;
  1694.     newAType->sizeInBytes = aType->sizeInBytes;
  1695.     newAType->baseType = newBase;
  1696.     // printf ("            Here it is the new thing...   ");
  1697.     // pretty (newAType);
  1698.     return newAType;
  1699.   } else if (type->op == FUNCTION_TYPE) {
  1700.     fType = (FunctionType * ) type;
  1701.     // Build a new Arglist, performing the substitution.
  1702.     newArgList = copyArgListWithSubst (fType->parmTypes, subst);
  1703.     // Build a new Return type, performing the substitution.
  1704.     newRetType = copyTypeWithSubst (fType->retType, subst);
  1705.  
  1706.     // If the new type will look the same, then return the old type.
  1707.     if ((newArgList == fType->parmTypes) && (newRetType == fType->retType)) {
  1708.       // printf ("Returning.  The type is unchanged... ");
  1709.       // pretty (type);
  1710.       return type;
  1711.     }
  1712.  
  1713.     // Build a new FunctionType object and return it.
  1714.     // printf ("Returning.  Building new FunctionType for... ");
  1715.     // pretty (type);
  1716.     newFType = new FunctionType ();
  1717.     newFType->positionAt (fType);
  1718.     newFType->parmTypes = newArgList;
  1719.     newFType->retType = newRetType;
  1720.     // printf ("            Here it is the new thing...   ");
  1721.     // pretty (newFType);
  1722.     return newFType;
  1723.   } else {   // It must be CHAR_TYPE, INT_TYPE, DOUBLE_TYPE, BOOL_TYPE,
  1724.              //            VOID_TYPE, TYPE_OF_NULL, or ANY_TYPE...
  1725.     // printf ("Returning.  Default case returning: ");
  1726.     // pretty (type);
  1727.     return type;
  1728.   }
  1729. }
  1730.  
  1731.  
  1732.  
  1733. // copyArgListWithSubst (argList, subst)
  1734. //
  1735. // Build a new arg list by copying the old list, performing the
  1736. // substitution.  Try to share parts of the old list, if there is
  1737. // no change.
  1738. //
  1739. // Tested.
  1740. //
  1741. TypeArg * copyArgListWithSubst (TypeArg * argList,
  1742.                                 Mapping <TypeParm, Type> * subst) {
  1743.   TypeArg * newTail, * newTypeArg;
  1744.   Type * newType;
  1745.  
  1746.   if (argList == NULL) return NULL;
  1747.  
  1748.   // printf ("    --- copyArgListWithSubst entered with argList = ");
  1749.   // pretty (argList);
  1750.  
  1751.   newTail = copyArgListWithSubst (argList->next, subst);
  1752.   newType = copyTypeWithSubst (argList->type, subst);
  1753.  
  1754.   // If the new TypeArg would be the same, just return the old TypeArg object. 
  1755.   if ((newType == argList->type) && (newTail == argList->next)) {
  1756.     // printf ("    --- Returning without creating anything new = ");
  1757.     // pretty (argList);
  1758.     return argList;
  1759.   }
  1760.  
  1761.   // Else, build a new TypeArg object.
  1762.   newTypeArg = new TypeArg ();
  1763.   newTypeArg->positionAt (argList);
  1764.   newTypeArg->type = newType;
  1765.   newTypeArg->next = newTail;
  1766.  
  1767.   // printf ("    --- Returning; Building newTypeArg = ");
  1768.   // pretty (newTypeArg);
  1769.  
  1770.   return newTypeArg;
  1771. }
  1772.  
  1773.  
  1774.  
  1775. // copyRecordFieldsWithSubst (argList, subst)
  1776. //
  1777. // Build a new field list by copying the old list, performing the
  1778. // substitution.  Try to share parts of the old list, if there is
  1779. // no change.
  1780. //
  1781. // Tested.
  1782. //
  1783. RecordField * copyRecordFieldsWithSubst (RecordField * fieldList,
  1784.                                          Mapping <TypeParm, Type> * subst) {
  1785.   RecordField * newTail, * newRecordField;
  1786.   Type * newType;
  1787.  
  1788.   if (fieldList == NULL) return NULL;
  1789.  
  1790.   // printf ("    --- copyRecordFieldsWithSubst entered with fieldList = ");
  1791.   // pretty (fieldList);
  1792.  
  1793.   newTail = copyRecordFieldsWithSubst ((RecordField *) (fieldList->next), subst);
  1794.   newType = copyTypeWithSubst (fieldList->type, subst);
  1795.  
  1796.   // If the new RecordField would be the same, just return the old RecordField object. 
  1797.   if ((newType == fieldList->type) && (newTail == fieldList->next)) {
  1798.     // printf ("    --- Returning without creating anything new = ");
  1799.     // pretty (fieldList);
  1800.     return fieldList;
  1801.   }
  1802.  
  1803.   // Else, build a new RecordField object.
  1804.   newRecordField = new RecordField ();
  1805.   newRecordField->positionAt (fieldList);
  1806.   newRecordField->id = fieldList->id;
  1807.   newRecordField->type = newType;
  1808.   newRecordField->next = newTail;
  1809.  
  1810.   // printf ("    --- Returning; Building newRecordField = ");
  1811.   // pretty (newRecordField);
  1812.  
  1813.   return newRecordField;
  1814. }
  1815.  
  1816.  
  1817.  
  1818. // inheritFields (hdr)
  1819. //
  1820. // This routine builds the "classMapping" for each ClassDef.  It also re-builds the
  1821. // list of fields.  First, copies of the inherited fields are created.  Then the
  1822. // inherited fields are placed at the beginning of the list "fields".  Then the
  1823. // new fields of this class are added at the end.
  1824. //
  1825. // When inherited ClassFields are copied, their types are copied with a possible
  1826. // substitution.  Here is an example showing why this might be necessary:
  1827. //
  1828. //      class Super [T:anyType]
  1829. //        fields
  1830. //          f: ptr to T
  1831. //      ...
  1832. //      class Sub [S:Number]
  1833. //        superclass Super [S]
  1834. //
  1835. // In "Sub", the field will become:
  1836. //          f : ptr to S
  1837. //
  1838. // This routine also fills in the "superclassDef" field in each ClassDef.
  1839. //
  1840. void inheritFields (Header * hdr) {
  1841.   ClassDef * cl;
  1842.   NamedType * nType;
  1843.   TypeArg * typeArg;
  1844.   ClassDef * super;
  1845.   TypeParm * typeParm;
  1846.   ClassField * newFields, * newFieldsLast, * f, * oldField;
  1847.   AstNode * def;
  1848.  
  1849.   for (cl = hdr->classes; cl; cl = cl->next) {
  1850.  
  1851.     // Create the classMapping...
  1852.     cl->classMapping = new Mapping <String, AstNode> (10, hdr->packageMapping);
  1853.  
  1854.     // Create the superclassMapping...
  1855.     super = NULL;
  1856.     if (cl->superclass) {
  1857.       nType = (NamedType *) cl->superclass;
  1858.       typeArg = nType->typeArgs;
  1859.       super = (ClassDef *) (nType->myDef);
  1860.       if (super) {   // else previous errors...
  1861.         if (super->op != CLASS_DEF) {   // if previous errors...
  1862.           super = NULL;
  1863.         } else {
  1864.           typeParm = super->typeParms;
  1865.           while (1) {
  1866.             if ((typeParm == NULL) && (typeArg == NULL)) break;
  1867.             if ((typeParm == NULL) || (typeArg == NULL)) {
  1868.               error (cl->superclass, "The number of type arguments here does not match the number of type parameters in the superclass definition");
  1869.               break;
  1870.             }
  1871.             if (cl->superclassMapping == NULL) {
  1872.               cl->superclassMapping = new Mapping <TypeParm, Type> (3, NULL);
  1873.             }
  1874.             cl->superclassMapping->enter (typeParm, typeArg->type);
  1875.             typeParm = typeParm->next;
  1876.             typeArg = typeArg->next;
  1877.           }
  1878.         }
  1879.       }
  1880.     }
  1881.     cl->superclassDef = super;
  1882.  
  1883.     // Build the new field list.
  1884.     newFields = NULL;
  1885.     newFieldsLast = NULL;
  1886.  
  1887.     // Run through the superclass's fields.  For each, copy the field
  1888.     // and place it onto the newField list.
  1889.     if (super) {
  1890.       for (oldField = super->fields; oldField; oldField = (ClassField *) oldField->next) {
  1891.         f = new ClassField ();
  1892.         f->positionAt (oldField);
  1893.         f->id = oldField->id;
  1894.         f->type = copyTypeWithSubst (oldField->type, cl-> superclassMapping);
  1895.         if (newFields) {
  1896.           newFieldsLast->next = f;
  1897.         } else {
  1898.           newFields = f;
  1899.         }
  1900.         newFieldsLast = f;
  1901.         cl->classMapping->enter (f->id, f);
  1902.       }
  1903.     }
  1904.  
  1905.     // Add all fields new to this class to the classMapping...
  1906.     for (f = cl->fields; f; f = (ClassField * ) f->next) {
  1907.       def = cl->classMapping->findInTopScope (f->id);
  1908.       if (def) {
  1909.         error (f, "A field with this name already exists in this class");
  1910.         error2 (def, "Here is the other field");
  1911.       } else {
  1912.         cl->classMapping->enter (f->id, f);
  1913.         if (f->id->primitiveSymbol) {
  1914.           error (f, "This field happens to have the same name as that of a built-in primitive function; please select a different name");
  1915.         }
  1916.       }
  1917.     }
  1918.  
  1919.     // Put the fields in this class at the end of the new field list...
  1920.     if (newFields) {
  1921.       newFieldsLast->next = cl->fields;
  1922.     } else {
  1923.       newFields = cl->fields;
  1924.     }
  1925.  
  1926.     // Make this field list the class's field list...
  1927.     cl->fields = newFields;
  1928.  
  1929.   }
  1930. }
  1931.  
  1932.  
  1933.  
  1934. // inheritMethodProtos (hdr)
  1935. //
  1936. // For each ClassDef, this routine builds the "selectorMapping", which maps selectors
  1937. // (like "foo" or "at:put:") to MethodProtos.  First, the MethodProtos of this class
  1938. // are placed in the mapping.  Then, we run through all the MethodProtos in the
  1939. // superclass.  For each, we make a copy and add that to the mapping.
  1940. // We also add the copy to the list "methodProtos" in this class.
  1941. //
  1942. // When inherited MethodProtos are copied, their types are copied with a possible
  1943. // substitution.  Here is an example showing why this might be necessary:
  1944. //
  1945. //      class Super [T:anyType]
  1946. //        methods
  1947. //          foo (x:T) returns ptr to T
  1948. //      ...
  1949. //      class Sub [S:Number]
  1950. //        superclass Super [S]
  1951. //      ...
  1952. // In "Sub", the MethodProto will become:
  1953. //          foo (x:S) returns ptr to S
  1954. //
  1955. // When methods are overridden, then the copy of the MethodProto will have the
  1956. // selector prefixed with "_super_".
  1957. //
  1958. // This routine checks that there are no duplicate Methods or duplicate MethodProtos.
  1959. // It checks that for every MethodProto there is a Method, and it checks that for every
  1960. // Method there is a MethodProto.  (Only if this class is in the MainHeader.)
  1961. //
  1962. // This routine makes each Method point back to the MethodProto in its class.  It also
  1963. // makes each MethodProto point to the Method that will implement it.  Whenever Methods
  1964. // are inherited, the newly created MethodProto in the subclass will be made to point
  1965. // to the Method in the superclass.
  1966. //
  1967. // It is possible that the class will have two Methods with the same operator, if one
  1968. // is infix and the other is prefix.  For example:
  1969. //
  1970. //      class C
  1971. //        methods
  1972. //          prefix + () returns int
  1973. //          infix + (x: int) returns int
  1974. //
  1975. // In the case of a prefix operator, we will enter it into the selector mapping
  1976. // using a key made by adding "_prefix_" to it.  In this example, the mapping key will
  1977. // be "_prefix_+".  An infix method will be entered using the selector ("+") as is.
  1978. // The selector in the method, however, will not be changed.
  1979. //
  1980. // When a prefix operator is inherited and overridden in the subclass, the newly
  1981. // created MethodProto will have a selector like "_super__prefix_+".  It will be
  1982. // entered in the selector mapping with the same selector.
  1983. //
  1984. void inheritMethodProtos (Header * hdr) {
  1985.   ClassDef * cl;
  1986.   MethodProto * proto, * newProto, * nextProto;
  1987.   AstNode * def, * def2;
  1988.   Method * meth;
  1989.   String * newSelector, * strKey, * strVal;
  1990.  
  1991.   TypeArg * typeArg;
  1992.  
  1993.   for (cl = hdr->classes; cl; cl = cl->next) {
  1994.  
  1995.     // printf ("    Processing class %s\n", cl->id->chars);
  1996.  
  1997.     // Create the "localMethodMapping".  This is a mapping from selectors
  1998.     // to the Methods that are actually in this class; it does not include
  1999.     // any inherited methods.  The "_prefix_" string will be added to the
  2000.     // selector for the keys of prefix methods...
  2001.     cl->localMethodMapping = new Mapping <String, Method> (10, NULL);
  2002.  
  2003.     // Run thru the methods and add them to "localMethodMapping".
  2004.     // Check to make sure each method has a different selctor...
  2005.     for (meth=cl->methods; meth; meth = meth->next) {
  2006.       newSelector = meth->selector;
  2007.       // printf ("newSelector = %s\n", newSelector->chars);
  2008.       def = cl->localMethodMapping->findInTopScope (newSelector);
  2009.       if (def) {
  2010.         error (meth, "Another method with the same selector already exists in this class");
  2011.         error2 (def, "Here is the other method");
  2012.       } else {
  2013.         cl->localMethodMapping->enter (newSelector, meth);
  2014.       }
  2015.     }
  2016.  
  2017.     // Create the "selectorMapping"...
  2018.     cl->selectorMapping = new Mapping <String, MethodProto> (10, NULL);
  2019.  
  2020.     // Add all MethodProtos in this class to the "selectorMapping".
  2021.     // Make sure all MethodProtos have different selectors.
  2022.     // For classes in the mainHeader, also make sure that there is
  2023.     // a Method for each MethodProto...
  2024.     for (proto = cl->methodProtos; proto; proto = proto->next) {
  2025.       newSelector = proto->selector;
  2026.       def = cl->selectorMapping->findInTopScope (newSelector);
  2027.       if (def) {
  2028.         error (proto, "A method prototype with this selector already exists in this class");
  2029.         error2 (def, "Here is the other method prototype");
  2030.       } else {
  2031.         cl->selectorMapping->enter (newSelector, proto);
  2032.         if (hdr == mainHeader) {
  2033.           // Make sure there is a method for this MethodProto...
  2034.           meth = (Method *) cl->localMethodMapping->find (newSelector);
  2035.           if (meth == NULL) {
  2036.             error (proto, "There is no method for this method prototype");
  2037.           } else {
  2038.             // Link the method and its prototype
  2039.             meth->myMethodProto = proto;
  2040.             proto->myMethod = meth;
  2041.           }
  2042.         }
  2043.       }
  2044.     }
  2045.  
  2046.     // Run through the list of Methods in this class and make sure
  2047.     // there is a MethodProto for each...
  2048.     for (meth=cl->methods; meth; meth = meth->next) {
  2049.       newSelector = meth->selector;
  2050.       def = cl->selectorMapping->findInTopScope (newSelector);
  2051.       if (def == NULL) {
  2052.         error (meth, "There is no method prototype for this method");
  2053.       }
  2054.     }
  2055.  
  2056.     // Run through the superclass's MethodProtos and make copies of them...
  2057.     if (cl->superclassDef) {
  2058.  
  2059.       // printf ("  Processing superclass %s\n", cl->superclassDef->id->chars);
  2060.  
  2061.       for (proto = cl->superclassDef->methodProtos; proto; proto=proto->next) {
  2062.  
  2063.         //    printf ("    Looking at = %s\n", proto->selector->chars);
  2064.         newSelector = proto->selector;
  2065.  
  2066.         // See if this methodProto is being overridden by a method in this class,
  2067.         // and keep adding "_super_" until not...
  2068.         while (cl->selectorMapping->findInTopScope (newSelector)) {
  2069.           newSelector = addSuperTo (newSelector);
  2070.           //    printf ("      Overriding detected, newSelector = %s\n",
  2071.           //            newSelector->chars);
  2072.         }
  2073.  
  2074.         // Create a new MethodProto and add it to this class...
  2075.         //    printf ("      Creating new MethodProto...\n");
  2076.         newProto = new MethodProto ();
  2077.         newProto->positionAt (proto);
  2078.         newProto->kind = proto->kind;
  2079.         newProto->selector = newSelector;
  2080.         newProto->parmList =
  2081.               copyParmListWithSubst (proto->parmList, cl->superclassMapping);
  2082.         newProto->retType =
  2083.               copyTypeWithSubst (proto->retType, cl->superclassMapping);
  2084.         cl->selectorMapping->enter (newSelector, newProto);
  2085.         newProto->myMethod = proto->myMethod;
  2086.         newProto->next = cl->methodProtos;
  2087.         cl->methodProtos = newProto;
  2088.       }
  2089.     }
  2090.  
  2091.   }
  2092. }
  2093.  
  2094.  
  2095.  
  2096. // addSuperTo (str)
  2097. //
  2098. // This routine creates a new string by prepending the characters "_super_".
  2099. // It returns the new string.
  2100. //
  2101. String * addSuperTo (String * str) {
  2102.   char * newChars;
  2103.   newChars = appendStrings ("_super_", str->chars, "");
  2104.   return lookupAndAdd (newChars, str->type);
  2105. }
  2106.  
  2107.  
  2108.  
  2109. // inheritMessages (hdr)
  2110. //
  2111. // This routine builds the "selectorMapping" for each Interface by placing the
  2112. // local MethodProtos into it.  This is done to check for duplicate messages in this
  2113. // interface.  Then, we go through each super-interface and make a copy of each
  2114. // inherited method.  We do not place these in the selectorMapping yet since,
  2115. // because of the semantics of message inheritance, there may be duplicates.
  2116. // Instead, we accumulate them into a list for use later.
  2117. //
  2118. // When inherited MethodProtos are copied, their types are copied with a possible
  2119. // substitution.  Here is an example showing why this might be necessary:
  2120. //
  2121. //      interface Super [T:anyType]
  2122. //        messages
  2123. //          foo (x:T) returns ptr to T
  2124. //      ...
  2125. //      interface Sub [S:Number]
  2126. //        extends Super [S]
  2127. //      ...
  2128. //
  2129. // In "Sub", the MethodProto will become:
  2130. //          foo (x:S) returns ptr to S
  2131. //
  2132. void inheritMessages (Header * hdr) {
  2133.   Interface * inter, * superInter;
  2134.   MethodProto * proto, * newProto;
  2135.   AstNode * def;
  2136.   TypeArg * typeArg, * superTypeArg;
  2137.   TypeParm * typeParm;
  2138.   Mapping <TypeParm, Type> * subst;
  2139.   NamedType * nType;
  2140.  
  2141.   // Run through all interfaces...
  2142.   for (inter = hdr->interfaces; inter; inter = inter->next) {
  2143.  
  2144.     // Create the "selectorMapping"...
  2145.     inter->selectorMapping = new Mapping <String, MethodProto> (10, NULL);
  2146.  
  2147.     // Add all methodProtos in this interface to the "selectorMapping"...
  2148.     for (proto = inter->methodProtos; proto; proto = proto->next) {
  2149.       def = inter->selectorMapping->findInTopScope (proto->selector);
  2150.       if (def) {
  2151.         error (proto, "A message with this selector already exists in this interface");
  2152.         error2 (def, "Here is the other message");
  2153.       } else {
  2154.         inter->selectorMapping->enter (proto->selector, proto);
  2155.       }
  2156.     }
  2157.  
  2158.     // Run through each of the interfaces that we extend...
  2159.     for (superTypeArg = inter->extends; superTypeArg; superTypeArg = superTypeArg->next) {
  2160.       nType = (NamedType *) superTypeArg->type;
  2161.       superInter = (Interface *) (nType->myDef);
  2162.       // If no previous errors...
  2163.       if (superInter) {
  2164.         if (superInter->op == INTERFACE) {
  2165.  
  2166.           // Build a substitution for the TypeParms...
  2167.           subst = NULL;
  2168.           typeParm = superInter->typeParms;
  2169.           typeArg = nType->typeArgs;
  2170.           while (1) {
  2171.             if ((typeParm == NULL) && (typeArg == NULL)) break;
  2172.             if ((typeParm == NULL) || (typeArg == NULL)) {
  2173.               error (superTypeArg, "The number of type arguments here does not match the number of type parameters in the interface definition");
  2174.               break;
  2175.             }
  2176.             if (subst == NULL) {
  2177.               subst = new Mapping <TypeParm, Type> (3, NULL);
  2178.             }
  2179.             subst->enter (typeParm, typeArg->type);
  2180.             typeParm = typeParm->next;
  2181.             typeArg = typeArg->next;
  2182.           }
  2183.  
  2184.           // printf ("subst = \n");
  2185.           // if (subst) {
  2186.           //   subst->print (6);
  2187.           // } else {
  2188.           //   printf ("NULL\n");
  2189.           // }
  2190.  
  2191.           // Run through the superInterfaces's methodProtos and make copies of them...
  2192.           for (proto = superInter->methodProtos; proto; proto=proto->next) {
  2193.             newProto = new MethodProto ();
  2194.             newProto->positionAt (proto);
  2195.             newProto->kind = proto->kind;
  2196.             newProto->selector = proto->selector;
  2197.             newProto->parmList =
  2198.                   copyParmListWithSubst (proto->parmList, subst);
  2199.             newProto->retType =
  2200.                   copyTypeWithSubst (proto->retType, subst);
  2201.             // Add to the list of inherited messages...
  2202.             newProto->next = inter->inheritedMethodProtos;
  2203.             inter->inheritedMethodProtos = newProto;
  2204.           }
  2205.  
  2206.           // Go through the superInterface's inherited messages (inheritedMethodProtos)
  2207.           // and make copies of them, too...
  2208.           for (proto = superInter->inheritedMethodProtos; proto; proto=proto->next) {
  2209.             newProto = new MethodProto ();
  2210.             newProto->positionAt (proto);
  2211.             newProto->kind = proto->kind;
  2212.             newProto->selector = proto->selector;
  2213.             newProto->parmList =
  2214.                   copyParmListWithSubst (proto->parmList, subst);
  2215.             newProto->retType =
  2216.                   copyTypeWithSubst (proto->retType, subst);
  2217.             // Add to the list of inherited messages...
  2218.             newProto->next = inter->inheritedMethodProtos;
  2219.             inter->inheritedMethodProtos = newProto;
  2220.           }
  2221.  
  2222.  
  2223.         }
  2224.       }
  2225.     }
  2226.  
  2227.   }
  2228. }
  2229.  
  2230.  
  2231. /***************  OBSOLETE ROUTINE  ***************
  2232.  
  2233. // setHetero (methodProto)
  2234. //
  2235. // See if this MethodProto uses TypeParms for the types of arguments or
  2236. // returned type.  Set the "covarianceRequired" or "contravarianceRequired"
  2237. // fields in the TypeParms, as necessary.
  2238. //
  2239. void setHetero (MethodProto * proto) {
  2240.   TypeParm * typeParm;
  2241.   Parameter * parm;
  2242.   NamedType * nType;
  2243.  
  2244.   for (parm = proto->parmList; parm; parm = (Parameter *) parm->next) {
  2245.     if ((parm->type) && (parm->type->op == NAMED_TYPE)) {
  2246.       nType = (NamedType *) parm->type;
  2247.       if ((nType->myDef) && (nType->myDef->op == TYPE_PARM)) {
  2248.         typeParm = (TypeParm *) nType->myDef;
  2249.         typeParm->contravarianceRequired = 1;
  2250.       }
  2251.     }
  2252.   }
  2253.   if ((proto->retType) && (proto->retType->op == NAMED_TYPE)) {
  2254.     nType = (NamedType *) proto->retType;
  2255.     if ((nType->myDef) && (nType->myDef->op == TYPE_PARM)) {
  2256.       typeParm = (TypeParm *) nType->myDef;
  2257.       typeParm->covarianceRequired = 1;
  2258.     }
  2259.   }
  2260. }
  2261.  
  2262. ********************************************************/
  2263.  
  2264.  
  2265.  
  2266. // copyParmListWithSubst (parmList, subst)
  2267. //
  2268. // Build a new Parameter list by copying the old Parameter list, performing the
  2269. // substitution.  Try to share parts of the old list, if there is no change.
  2270. //
  2271. Parameter * copyParmListWithSubst (Parameter * parmList,
  2272.                                    Mapping<TypeParm,Type> * subst) {
  2273.   Parameter * newTail, * newParm;
  2274.   Type * newType;
  2275.  
  2276.   if (parmList == NULL) return NULL;
  2277.  
  2278.   // printf ("==========  copyParmListWithSubst entered, parmList = ");
  2279.   // pretty (parmList); 
  2280.   // printAst (6, parmList); 
  2281.  
  2282.   newTail = copyParmListWithSubst ((Parameter *) parmList->next, subst);
  2283.   newType = copyTypeWithSubst (parmList->type, subst);
  2284.  
  2285.   // If the new Parm would be the same, just return the old Parm object. 
  2286.   if ((newType == parmList->type) && (newTail == parmList->next)) {
  2287.     // printf ("==========    No change, returning parmList = ");
  2288.     // pretty (parmList); 
  2289.     // printAst (6, parmList); 
  2290.     return parmList;
  2291.   }
  2292.  
  2293.   // Else, build a new Parameter object.
  2294.   newParm = new Parameter ();
  2295.   newParm->positionAt (parmList);
  2296.   newParm->id = parmList->id;
  2297.   newParm->type = newType;
  2298.   newParm->next = newTail;
  2299.   // printf ("==========    ... Building new Parameter, newParm = ");
  2300.   // pretty (newParm); 
  2301.   // printAst (6, newParm); 
  2302.   return newParm;
  2303. }
  2304.  
  2305.  
  2306.  
  2307. // bindVarNames (node, varMapping)
  2308. //
  2309. // This routine walks the entire Abstract Syntax Tree, visiting every node.
  2310. // It looks for every "Variable" node and fills in its "myDef", which will
  2311. // point to one of the following:
  2312. //    Local
  2313. //    Global
  2314. //    Parameter
  2315. //    ClassField
  2316. //    FunctionProto
  2317. //    ConstDecl
  2318. //
  2319. // It catches the following errors:
  2320. //         Undefined variable name
  2321. //         This name already in use in this scope
  2322. //         This variable names something that is not global, local, parm, etc.
  2323. //         This variable was never used in this Function / Method
  2324. //         Attempt to invoke something that is not a function (or variable)
  2325. //
  2326. // This routine also fills in the "myDef" field in CallExprs.
  2327. //
  2328. // This routine sets "fourByteRestricted" whenever a TypeParm is used as the
  2329. // type of a local, parameter, record field, or class field.
  2330. //
  2331. // The "varMapping" is a Mapping in which to look up variable names.
  2332. // It will be NULL only for Headers.
  2333. //
  2334. void bindVarNames (AstNode * node,
  2335.                    Mapping <String, AstNode> * varMapping) {
  2336.   Header * header;
  2337.   Code * code;
  2338.   Uses * uses;
  2339.   Renaming * renaming;
  2340.   Interface * interface;
  2341.   ClassDef * cl;
  2342.   TypeDef * typeDef;
  2343.   ConstDecl * constDecl;
  2344.   ErrorDecl * errorDecl;
  2345.   FunctionProto * functionProto;
  2346.   Function * fun;
  2347.   MethodProto * methodProto;
  2348.   Method * meth;
  2349.   TypeParm * typeParm;
  2350.   TypeArg * typeArg;
  2351.   PtrType * pType;
  2352.   ArrayType * aType;
  2353.   RecordType * rType;
  2354.   FunctionType * fType;
  2355.   NamedType * nType;
  2356.   IfStmt * ifStmt;
  2357.   AssignStmt * assignStmt;
  2358.   CallStmt * callStmt;
  2359.   SendStmt * sendStmt;
  2360.   WhileStmt * whileStmt;
  2361.   DoStmt * doStmt;
  2362.   BreakStmt * breakStmt;
  2363.   ContinueStmt * continueStmt;
  2364.   ReturnStmt * returnStmt;
  2365.   ForStmt * forStmt;
  2366.   SwitchStmt * switchStmt;
  2367.   TryStmt * tryStmt;
  2368.   ThrowStmt * throwStmt;
  2369.   FreeStmt * freeStmt;
  2370.   DebugStmt * debugStmt;
  2371.   Case * cas;
  2372.   Catch * cat;
  2373.   Global * global;
  2374.   Local * local;
  2375.   Parameter * parm, * protoParm, * funParm;
  2376.   ClassField * classField;
  2377.   RecordField * recordField;
  2378.   CallExpr * callExpr;
  2379.   SendExpr * sendExpr;
  2380.   FieldAccess * fieldAccess;
  2381.   ArrayAccess * arrayAccess;
  2382.   Constructor * constructor;
  2383.   ClosureExpr * closureExpr;
  2384.   VariableExpr * var;
  2385.   AsPtrToExpr * asPtrToExpr;
  2386.   AsIntegerExpr * asIntegerExpr;
  2387.   ArraySizeExpr * arraySizeExpr;
  2388.   IsInstanceOfExpr * isInstanceOfExpr;
  2389.   IsKindOfExpr * isKindOfExpr;
  2390.   SizeOfExpr * sizeOfExpr;
  2391.   Argument * arg;
  2392.   CountValue * countValue;
  2393.   FieldInit * fieldInit;
  2394.   AstNode * def;
  2395.   Mapping <String, AstNode> * newMap;
  2396.   Type * t1, * t2;
  2397.  
  2398.   if (node == NULL) return;
  2399.  
  2400.   // printf ("%s...\n", symbolName (node->op));
  2401.  
  2402.   switch (node->op) {
  2403.  
  2404.     case HEADER:
  2405.       header = (Header *) node;
  2406.       if (header->packageMapping == NULL) return;
  2407.       bindVarNames (header->uses, header->packageMapping);
  2408.       bindVarNames (header->consts, header->packageMapping);
  2409.       bindVarNames (header->errors, header->packageMapping);
  2410.       bindVarNames (header->globals, header->packageMapping);
  2411.       bindVarNames (header->typeDefs, header->packageMapping);
  2412.       bindVarNames (header->functionProtos, header->packageMapping);
  2413.       bindVarNames (header->functions, header->packageMapping);
  2414.       bindVarNames (header->closures, header->packageMapping);
  2415.       bindVarNames (header->interfaces, header->packageMapping);
  2416.       bindVarNames (header->classes, header->packageMapping);
  2417.       // bindVarNames (header->next, varMapping);
  2418.       return;
  2419.  
  2420.     case CODE:
  2421.       code = (Code *) node;
  2422.       // All this stuff has been moved into the main header, and we'll do it there.
  2423.       // bindVarNames (code->consts, varMapping);
  2424.       // bindVarNames (code->globals, varMapping);
  2425.       // bindVarNames (code->typeDefs, varMapping);
  2426.       // bindVarNames (code->functions, varMapping);
  2427.       // bindVarNames (code->interfaces, varMapping);
  2428.       // bindVarNames (code->classes, varMapping);
  2429.       // bindVarNames (code->behaviors, varMapping);
  2430.       return;
  2431.  
  2432.     case USES:
  2433.       uses = (Uses *) node;
  2434.       // printf ("  %s\n", uses->id->chars);
  2435.       bindVarNames (uses->renamings, varMapping);
  2436.       bindVarNames (uses->next, varMapping);
  2437.       return;
  2438.  
  2439.     case RENAMING:
  2440.       renaming = (Renaming *) node;
  2441.       bindVarNames (renaming->next, varMapping);
  2442.       return;
  2443.  
  2444.     case INTERFACE:
  2445.       interface = (Interface *) node;
  2446.       // printf ("  %s\n", interface->id->chars);
  2447.       bindVarNames (interface->typeParms, varMapping);
  2448.       bindVarNames (interface->extends, varMapping);
  2449.       bindVarNames (interface->methodProtos, varMapping);
  2450.       bindVarNames (interface->next, varMapping);
  2451.       return;
  2452.  
  2453.     case CLASS_DEF:
  2454.       cl = (ClassDef *) node;
  2455.       // printf ("==========  Processing class %s  ==========\n", cl->id->chars);
  2456.       // Run through our parameters and add them to the mapping...
  2457.       newMap = new Mapping <String, AstNode> (5, varMapping);
  2458.       for (classField = cl->fields;
  2459.            classField;
  2460.            classField = (ClassField * ) classField->next) {
  2461.         def = newMap->find (classField->id);
  2462.         if (def) {
  2463.           error (classField, "The name you have chosen for this field is already in use at this point; please choose a different name"); 
  2464.           error2 (def, "Here is something else with the same name");
  2465.         } else {
  2466.           newMap->enter (classField->id, classField);
  2467.         }
  2468.       }
  2469.       bindVarNames (cl->typeParms, varMapping);
  2470.       bindVarNames (cl->implements, varMapping);
  2471.       bindVarNames (cl->superclass, varMapping);
  2472.       bindVarNames (cl->fields, varMapping);
  2473.       bindVarNames (cl->methodProtos, newMap);
  2474.       bindVarNames (cl->methods, newMap);
  2475.       // Okay to delete newMap here, but don't waste the time.
  2476.       bindVarNames (cl->next, varMapping);
  2477.       // printf ("==========  End class %s  ==========\n", cl->id->chars);
  2478.       return;
  2479.  
  2480.     case BEHAVIOR:
  2481.       // behavior = (Behavior *) node;
  2482.       // The methods have been moved into their classes and we'll do them there.
  2483.       // bindVarNames (behavior->methods, varMapping);
  2484.       // bindVarNames (behavior->next, varMapping);
  2485.       return;
  2486.  
  2487.     case TYPE_DEF:
  2488.       typeDef = (TypeDef *) node;
  2489.       // printf ("  %s\n", typeDef->id->chars);
  2490.       bindVarNames (typeDef->type, varMapping);
  2491.       bindVarNames (typeDef->next, varMapping);
  2492.       return;
  2493.  
  2494.     case CONST_DECL:
  2495.       constDecl = (ConstDecl *) node;
  2496.       // printf ("  %s\n", constDecl->id->chars);
  2497.       bindVarNames (constDecl->expr, varMapping);
  2498.       bindVarNames (constDecl->next, varMapping);
  2499.       return;
  2500.  
  2501.     case ERROR_DECL:
  2502.       errorDecl = (ErrorDecl *) node;
  2503.       // printf ("  %s\n", errorDecl->id->chars);
  2504.       // Make sure that each parm has a distinct name...
  2505.       newMap = new Mapping <String, AstNode> (5, varMapping);
  2506.       for (parm = errorDecl->parmList; parm; parm = (Parameter * ) parm->next) {
  2507.         def = newMap->find (parm->id);
  2508.         if (def) {
  2509.           error (parm, "The name you have chosen for this parameter is already in use at this point; please choose a different name"); 
  2510.           error2 (def, "Here is something else with the same name");
  2511.         } else {
  2512.           newMap->enter (parm->id, parm);
  2513.         }
  2514.       }
  2515.       // Okay to delete newMap here, but don't waste the time.
  2516.       bindVarNames (errorDecl->parmList, varMapping);
  2517.       bindVarNames (errorDecl->next, varMapping);
  2518.       return;
  2519.  
  2520.     case FUNCTION_PROTO:
  2521.       functionProto = (FunctionProto *) node;
  2522.       // printf ("  %s\n", functionProto->id->chars);
  2523.  
  2524.       // Make sure that each parm has a distinct name...
  2525.       newMap = new Mapping <String, AstNode> (5, varMapping);
  2526.       for (parm = functionProto->parmList; parm; parm = (Parameter * ) parm->next) {
  2527.         def = newMap->find (parm->id);
  2528.         if (def) {
  2529.           error (parm, "The name you have chosen for this parameter is already in use at this point; please choose a different name"); 
  2530.           error2 (def, "Here is something else with the same name");
  2531.         } else {
  2532.           newMap->enter (parm->id, parm);
  2533.           if (parm->id->primitiveSymbol) {
  2534.             error (parm, "This happens to be the name of a built-in primitive function; please select a different name");
  2535.           }
  2536.         }
  2537.       }
  2538.       // Okay to delete newMap here, but don't waste the time.
  2539.       bindVarNames (functionProto->parmList, varMapping);
  2540.       bindVarNames (functionProto->retType, varMapping);
  2541.       bindVarNames (functionProto->next, varMapping);
  2542.       return;
  2543.  
  2544.     case FUNCTION:
  2545.       fun = (Function *) node;
  2546.       // if (fun->id) {
  2547.       //   printf ("  Looking at function %s...\n", fun->id->chars);
  2548.       //   printf ("     proto = %08x\n", fun->myProto);
  2549.       // } else {
  2550.       //   printf ("  Looking at some closure (id = NULL)...\n");
  2551.       // }
  2552.  
  2553.       // Run through our parameters and add them to the mapping...
  2554.       newMap = new Mapping <String, AstNode> (5, varMapping);
  2555.       for (parm = fun->parmList; parm; parm = (Parameter * ) parm->next) {
  2556.         def = newMap->find (parm->id);
  2557.         if (def) {
  2558.           error (parm, "The name you have chosen for this parameter is already in use at this point; please choose a different name"); 
  2559.           error2 (def, "Here is something else with the same name");
  2560.         } else {
  2561.           newMap->enter (parm->id, parm);
  2562.           if (parm->id->primitiveSymbol) {
  2563.             error (parm, "This happens to be the name of a built-in primitive function; please select a different name");
  2564.           }
  2565.         }
  2566.       }
  2567.  
  2568.       // Now walk the sub-trees...
  2569.       bindVarNames (fun->parmList, varMapping);
  2570.       bindVarNames (fun->retType, varMapping);
  2571.       bindVarNames (fun->locals, newMap);
  2572.       bindVarNames (fun->stmts, newMap);
  2573.  
  2574.       // Okay to delete newMap here, but don't waste the time.
  2575.  
  2576.       // Run through the locals and make sure each got used...
  2577.       for (local = fun->locals; local; local = (Local *) local->next) {
  2578.         if (! local->wasUsed) {
  2579.           error (local, "This variable was never used in this function; please eliminate it or comment it out");
  2580.          }
  2581.       }
  2582.       bindVarNames (fun->next, varMapping);
  2583.       return;
  2584.  
  2585.     case METHOD_PROTO:
  2586.       methodProto = (MethodProto *) node;
  2587.       // printf ("  %s\n", methodProto->selector->chars);
  2588.  
  2589.       // Run through our parameters and add them to the mapping...
  2590.       newMap = new Mapping <String, AstNode> (5, varMapping);
  2591.       for (parm = methodProto->parmList; parm; parm = (Parameter * ) parm->next) {
  2592.         def = newMap->find (parm->id);
  2593.         if (def) {
  2594.           error (parm, "The name you have chosen for this parameter is already in use at this point; please choose a different name"); 
  2595.           error2 (def, "Here is something else with the same name");
  2596.         } else {
  2597.           newMap->enter (parm->id, parm);
  2598.           if (parm->id->primitiveSymbol) {
  2599.             error (parm, "This happens to be the name of a built-in primitive function; please select a different name");
  2600.           }
  2601.         }
  2602.       }
  2603.       // Okay to delete newMap here, but don't waste the time.
  2604.  
  2605.       // The locals will be added as they are encountered...
  2606.  
  2607.       bindVarNames (methodProto->parmList, varMapping);
  2608.       bindVarNames (methodProto->retType, varMapping);
  2609.       bindVarNames (methodProto->next, varMapping);
  2610.       return;
  2611.  
  2612.     case METHOD:
  2613.       meth = (Method *) node;
  2614.       // if (meth->selector) {
  2615.       //   printf ("  Looking at method %s\n", meth->selector->chars);
  2616.       // }
  2617.       // Run through our parameters and add them to the mapping...
  2618.       newMap = new Mapping <String, AstNode> (5, varMapping);
  2619.       for (parm = meth->parmList; parm; parm = (Parameter * ) parm->next) {
  2620.         def = newMap->find (parm->id);
  2621.         if (def) {
  2622.           error (parm, "The name you have chosen for this parameter is already in use at this point; please choose a different name"); 
  2623.           error2 (def, "Here is something else with the same name");
  2624.         } else {
  2625.           newMap->enter (parm->id, parm);
  2626.           if (parm->id->primitiveSymbol) {
  2627.             error (parm, "This happens to be the name of a built-in primitive function; please select a different name");
  2628.           }
  2629.         }
  2630.       }
  2631.       bindVarNames (meth->parmList, varMapping);
  2632.       bindVarNames (meth->retType, varMapping);
  2633.       bindVarNames (meth->locals, newMap);
  2634.       bindVarNames (meth->stmts, newMap);
  2635.  
  2636.       // Okay to delete newMap here, but don't waste the time.
  2637.  
  2638.       // Run through the locals and make sure each got used...
  2639.       for (local = meth->locals; local; local = (Local *) local->next) {
  2640.         if (! local->wasUsed) {
  2641.           error (local, "This variable was never used in this method; please eliminate it or comment it out");
  2642.          }
  2643.       }
  2644.       bindVarNames (meth->next, varMapping);
  2645.       return;
  2646.  
  2647.     case TYPE_PARM:
  2648.       typeParm = (TypeParm *) node;
  2649.       bindVarNames (typeParm->type, varMapping);
  2650.       bindVarNames (typeParm->next, varMapping);
  2651.       return;
  2652.  
  2653.     case TYPE_ARG:
  2654.       typeArg = (TypeArg *) node;
  2655.       bindVarNames (typeArg->type, varMapping);
  2656.       bindVarNames (typeArg->next, varMapping);
  2657.       return;
  2658.  
  2659.     case CHAR_TYPE:
  2660.       return;
  2661.  
  2662.     case INT_TYPE:
  2663.       return;
  2664.  
  2665.     case DOUBLE_TYPE:
  2666.       return;
  2667.  
  2668.     case BOOL_TYPE:
  2669.       return;
  2670.  
  2671.     case VOID_TYPE:
  2672.       return;
  2673.  
  2674.     case TYPE_OF_NULL_TYPE:
  2675.       return;
  2676.  
  2677.     case ANY_TYPE:
  2678.       return;
  2679.  
  2680.     case PTR_TYPE:
  2681.       pType = (PtrType *) node;
  2682.       bindVarNames (pType->baseType, varMapping);
  2683.       return;
  2684.  
  2685.     case ARRAY_TYPE:
  2686.       aType = (ArrayType *) node;
  2687.       bindVarNames (aType->sizeExpr, varMapping);
  2688.       bindVarNames (aType->baseType, varMapping);
  2689.  
  2690.       // If the baseType is a TypeParm, then set 'fourByteRestricted'...
  2691.       setFourByteRestricted (aType->baseType);
  2692.       return;
  2693.  
  2694.     case RECORD_TYPE:
  2695.       rType = (RecordType *) node;
  2696.       bindVarNames (rType->fields, varMapping);
  2697.       return;
  2698.  
  2699.     case FUNCTION_TYPE:
  2700.       fType = (FunctionType *) node;
  2701.       bindVarNames (fType->parmTypes, varMapping);
  2702.       bindVarNames (fType->retType, varMapping);
  2703.       return;
  2704.  
  2705.     case NAMED_TYPE:
  2706.       nType = (NamedType *) node;
  2707.       // printf ("  %s\n", nType->id->chars);
  2708.       bindVarNames (nType->typeArgs, varMapping);
  2709.       return;
  2710.  
  2711.     case IF_STMT:
  2712.       ifStmt = (IfStmt *) node;
  2713.       bindVarNames (ifStmt->expr, varMapping);
  2714.       bindVarNames (ifStmt->thenStmts, varMapping);
  2715.       bindVarNames (ifStmt->elseStmts, varMapping);
  2716.       bindVarNames (ifStmt->next, varMapping);
  2717.       return;
  2718.  
  2719.     case ASSIGN_STMT:
  2720.       assignStmt = (AssignStmt *) node;
  2721.       bindVarNames (assignStmt->lvalue, varMapping);
  2722.       bindVarNames (assignStmt->expr, varMapping);
  2723.       bindVarNames (assignStmt->next, varMapping);
  2724.       return;
  2725.  
  2726.     case CALL_STMT:
  2727.       callStmt = (CallStmt *) node;
  2728.       bindVarNames (callStmt->expr, varMapping);
  2729.       bindVarNames (callStmt->next, varMapping);
  2730.       return;
  2731.  
  2732.     case SEND_STMT:
  2733.       sendStmt = (SendStmt *) node;
  2734.       bindVarNames (sendStmt->expr, varMapping);
  2735.       bindVarNames (sendStmt->next, varMapping);
  2736.       return;
  2737.  
  2738.     case WHILE_STMT:
  2739.       whileStmt = (WhileStmt *) node;
  2740.       bindVarNames (whileStmt->expr, varMapping);
  2741.       bindVarNames (whileStmt->stmts, varMapping);
  2742.       bindVarNames (whileStmt->next, varMapping);
  2743.       return;
  2744.  
  2745.     case DO_STMT:
  2746.       doStmt = (DoStmt *) node;
  2747.       bindVarNames (doStmt->stmts, varMapping);
  2748.       bindVarNames (doStmt->expr, varMapping);
  2749.       bindVarNames (doStmt->next, varMapping);
  2750.       return;
  2751.  
  2752.     case BREAK_STMT:
  2753.       breakStmt = (BreakStmt *) node;
  2754.       bindVarNames (breakStmt->next, varMapping);
  2755.       return;
  2756.  
  2757.     case CONTINUE_STMT:
  2758.       continueStmt = (ContinueStmt *) node;
  2759.       bindVarNames (continueStmt->next, varMapping);
  2760.       return;
  2761.  
  2762.     case RETURN_STMT:
  2763.       returnStmt = (ReturnStmt *) node;
  2764.       bindVarNames (returnStmt->expr, varMapping);
  2765.       bindVarNames (returnStmt->next, varMapping);
  2766.       // Testing...
  2767.       // printf ("=====  varMapping  =====\n");
  2768.       // if (varMapping) {
  2769.       //   varMapping->print (6);
  2770.       // } else {
  2771.       //   printf ("    NULL\n");
  2772.       // }
  2773.       // printf ("========================\n");
  2774.       return;
  2775.  
  2776.     case FOR_STMT:
  2777.       forStmt = (ForStmt *) node;
  2778.       bindVarNames (forStmt->lvalue, varMapping);
  2779.       bindVarNames (forStmt->expr1, varMapping);
  2780.       bindVarNames (forStmt->expr2, varMapping);
  2781.       bindVarNames (forStmt->expr3, varMapping);
  2782.       bindVarNames (forStmt->stmts, varMapping);
  2783.       bindVarNames (forStmt->next, varMapping);
  2784.       return;
  2785.  
  2786.     case SWITCH_STMT:
  2787.       switchStmt = (SwitchStmt *) node;
  2788.       bindVarNames (switchStmt->expr, varMapping);
  2789.       bindVarNames (switchStmt->caseList, varMapping);
  2790.       bindVarNames (switchStmt->defaultStmts, varMapping);
  2791.       bindVarNames (switchStmt->next, varMapping);
  2792.       return;
  2793.  
  2794.     case TRY_STMT:
  2795.       tryStmt = (TryStmt *) node;
  2796.       bindVarNames (tryStmt->stmts, varMapping);
  2797.       bindVarNames (tryStmt->catchList, varMapping);
  2798.       bindVarNames (tryStmt->next, varMapping);
  2799.       return;
  2800.  
  2801.     case THROW_STMT:
  2802.       throwStmt = (ThrowStmt *) node;
  2803.       bindVarNames (throwStmt->argList, varMapping);
  2804.       bindVarNames (throwStmt->next, varMapping);
  2805.       return;
  2806.  
  2807.     case FREE_STMT:
  2808.       freeStmt = (FreeStmt *) node;
  2809.       bindVarNames (freeStmt->expr, varMapping);
  2810.       bindVarNames (freeStmt->next, varMapping);
  2811.       return;
  2812.  
  2813.     case DEBUG_STMT:
  2814.       debugStmt = (DebugStmt *) node;
  2815.       bindVarNames (debugStmt->next, varMapping);
  2816.       return;
  2817.  
  2818.     case CASE:
  2819.       cas = (Case *) node;
  2820.       bindVarNames (cas->expr, varMapping);
  2821.       bindVarNames (cas->stmts, varMapping);
  2822.       bindVarNames (cas->next, varMapping);
  2823.       return;
  2824.  
  2825.     case CATCH:
  2826.       cat = (Catch *) node;
  2827.       // printf ("  Looking at catch %s\n", cat->id->chars);
  2828.       // Run through our parameters and add them to the mapping...
  2829.       newMap = new Mapping <String, AstNode> (5, varMapping);
  2830.       for (parm = cat->parmList; parm; parm = (Parameter * ) parm->next) {
  2831.         def = newMap->find (parm->id);
  2832.         if (def) {
  2833.           error (parm, "The name you have chosen for this parameter is already in use at this point; please choose a different name"); 
  2834.           error2 (def, "Here is something else with the same name");
  2835.         } else {
  2836.           newMap->enter (parm->id, parm);
  2837.           if (parm->id->primitiveSymbol) {
  2838.             error (parm, "This happens to be the name of a built-in primitive function; please select a different name");
  2839.           }
  2840.         }
  2841.       }
  2842.       bindVarNames (cat->parmList, varMapping);
  2843.       bindVarNames (cat->stmts, newMap);
  2844.       // Okay to delete newMap here, but don't waste the time.
  2845.       bindVarNames (cat->next, varMapping);
  2846.       return;
  2847.  
  2848.     case GLOBAL:
  2849.       global = (Global *) node;
  2850.       bindVarNames (global->type, varMapping);
  2851.       bindVarNames (global->initExpr, varMapping);
  2852.       bindVarNames (global->next, varMapping);
  2853.       return;
  2854.  
  2855.     case LOCAL:
  2856.       local = (Local *) node;
  2857.       bindVarNames (local->type, varMapping);
  2858.       // If the type is a TypeParm, then set 'fourByteRestricted'...
  2859.       setFourByteRestricted (local->type);
  2860.  
  2861.       // Look at the initializing expression first, since it must not contain
  2862.       // any uses of the variable being defined...
  2863.       bindVarNames (local->initExpr, varMapping);
  2864.  
  2865.       // Now add this variable to the mapping...
  2866.       def = varMapping->find (local->id);
  2867.       if (def) {
  2868.         error (local, "The name you have chosen for this variable is already in use at this point; please choose a different name"); 
  2869.         error2 (def, "Here is something else with the same name");
  2870.       } else {
  2871.         varMapping->enter (local->id, local);
  2872.         if (local->id->primitiveSymbol) {
  2873.           error (local, "This happens to be the name of a built-in primitive function; please select a different name");
  2874.         }
  2875.       }
  2876.       bindVarNames (local->next, varMapping);
  2877.       return;
  2878.  
  2879.     case PARAMETER:
  2880.       parm = (Parameter *) node;
  2881.       bindVarNames (parm->type, varMapping);
  2882.  
  2883.       // If the type is a TypeParm, then set 'fourByteRestricted'...
  2884.       setFourByteRestricted (parm->type);
  2885.       bindVarNames (parm->next, varMapping);
  2886.       return;
  2887.  
  2888.     case CLASS_FIELD:
  2889.       classField = (ClassField *) node;
  2890.       bindVarNames (classField->type, varMapping);
  2891.  
  2892.       // If the type is a TypeParm, then set 'fourByteRestricted'...
  2893.       setFourByteRestricted (classField->type);
  2894.       bindVarNames (classField->next, varMapping);
  2895.       return;
  2896.  
  2897.     case RECORD_FIELD:
  2898.       recordField = (RecordField *) node;
  2899.       bindVarNames (recordField->type, varMapping);
  2900.  
  2901.       // If the type is a TypeParm, then set 'fourByteRestricted'...
  2902.       setFourByteRestricted (recordField->type);
  2903.       bindVarNames (recordField->next, varMapping);
  2904.       return;
  2905.  
  2906.     case INT_CONST:
  2907.       return;
  2908.  
  2909.     case DOUBLE_CONST:
  2910.       return;
  2911.  
  2912.     case CHAR_CONST:
  2913.       return;
  2914.  
  2915.     case STRING_CONST:
  2916.       return;
  2917.  
  2918.     case BOOL_CONST:
  2919.       return;
  2920.  
  2921.     case NULL_CONST:
  2922.       return;
  2923.  
  2924.     case CALL_EXPR:
  2925.       callExpr = (CallExpr *) node;
  2926.       bindVarNames (callExpr->argList, varMapping);
  2927.  
  2928.       // In "foo(...)" find the definition of "foo" and set "myDef" to it...
  2929.       def = varMapping->find (callExpr->id);
  2930.       if (def == NULL) {
  2931.         // Ignore "undefined name" error here, since it could be a primitive...
  2932.         // error (callExpr, "There is no function with this name (nor is there a variable with this name known at this point)");
  2933.       } else {
  2934.         if ((def->op == LOCAL) ||
  2935.             (def->op == GLOBAL) ||
  2936.             (def->op == PARAMETER) ||
  2937.             (def->op == CLASS_FIELD) ||
  2938.             (def->op == FUNCTION_PROTO)) {
  2939.           callExpr->myDef = def;
  2940.           if (def->op == LOCAL) {
  2941.             ((Local *) def)->wasUsed = 1;
  2942.           }
  2943.         } else {
  2944.           error (callExpr, "You are attempting to invoke something that is not a function (or local, global, parameter, or class field)");
  2945.           error2 (def, "Here is the definition of the item you are trying to invoke");
  2946.         }
  2947.       }
  2948.       return;
  2949.  
  2950.     case SEND_EXPR:
  2951.       sendExpr = (SendExpr *) node;
  2952.       bindVarNames (sendExpr->receiver, varMapping);
  2953.       bindVarNames (sendExpr->argList, varMapping);
  2954.       return;
  2955.  
  2956.     case SELF_EXPR:
  2957.       return;
  2958.  
  2959.     case SUPER_EXPR:
  2960.       return;
  2961.  
  2962.     case FIELD_ACCESS:
  2963.       fieldAccess = (FieldAccess *) node;
  2964.       bindVarNames (fieldAccess->expr, varMapping);
  2965.       return;
  2966.  
  2967.     case ARRAY_ACCESS:
  2968.       arrayAccess = (ArrayAccess *) node;
  2969.       bindVarNames (arrayAccess->arrayExpr, varMapping);
  2970.       bindVarNames (arrayAccess->indexExpr, varMapping);
  2971.       return;
  2972.  
  2973.     case CONSTRUCTOR:
  2974.       constructor = (Constructor *) node;
  2975.       bindVarNames (constructor->type, varMapping);
  2976.       bindVarNames (constructor->countValueList, varMapping);
  2977.       bindVarNames (constructor->fieldInits, varMapping);
  2978.       return;
  2979.  
  2980.     case CLOSURE_EXPR:
  2981.       closureExpr = (ClosureExpr *) node;
  2982.       // Skip this, since we'll walk the function when we do header->closures...
  2983.       // bindVarNames (closureExpr->function, varMapping);
  2984.       return;
  2985.  
  2986.     case VARIABLE_EXPR:
  2987.       var = (VariableExpr *) node;
  2988.       // printf ("  Binding \"%s\"...\n", var->id->chars);
  2989.  
  2990.       // Look this variable up and set its "myDef" to point to the definition...
  2991.       def = varMapping->find (var->id);
  2992.       if (def == NULL) {
  2993.         error (var, "This variable name is undefined at this point");
  2994.       } else {
  2995.         if ((def->op == LOCAL) ||
  2996.             (def->op == GLOBAL) ||
  2997.             (def->op == PARAMETER) ||
  2998.             (def->op == CLASS_FIELD) ||
  2999.             (def->op == FUNCTION_PROTO) ||
  3000.             (def->op == CONST_DECL)) {
  3001.           var->myDef = def;
  3002.           if (def->op == LOCAL) {
  3003.             ((Local *) def)->wasUsed = 1;
  3004.           }
  3005.         } else {
  3006.           error (var, "This variable names something that is not a local, global, parameter, class field, function, or constant");
  3007.           error2 (def, "Here is the item being named");
  3008.         }
  3009.       }
  3010.       return;
  3011.  
  3012.     case AS_PTR_TO_EXPR:
  3013.       asPtrToExpr = (AsPtrToExpr *) node;
  3014.       bindVarNames (asPtrToExpr->expr, varMapping);
  3015.       bindVarNames (asPtrToExpr->type, varMapping);
  3016.       return;
  3017.  
  3018.     case AS_INTEGER_EXPR:
  3019.       asIntegerExpr = (AsIntegerExpr *) node;
  3020.       bindVarNames (asIntegerExpr->expr, varMapping);
  3021.       return;
  3022.  
  3023.     case ARRAY_SIZE_EXPR:
  3024.       arraySizeExpr = (ArraySizeExpr *) node;
  3025.       bindVarNames (arraySizeExpr->expr, varMapping);
  3026.       return;
  3027.  
  3028.     case IS_INSTANCE_OF_EXPR:
  3029.       isInstanceOfExpr = (IsInstanceOfExpr *) node;
  3030.       bindVarNames (isInstanceOfExpr->expr, varMapping);
  3031.       bindVarNames (isInstanceOfExpr->type, varMapping);
  3032.       return;
  3033.  
  3034.     case IS_KIND_OF_EXPR:
  3035.       isKindOfExpr = (IsKindOfExpr *) node;
  3036.       bindVarNames (isKindOfExpr->expr, varMapping);
  3037.       bindVarNames (isKindOfExpr->type, varMapping);
  3038.       return;
  3039.  
  3040.     case SIZE_OF_EXPR:
  3041.       sizeOfExpr = (SizeOfExpr *) node;
  3042.       bindVarNames (sizeOfExpr->type, varMapping);
  3043.       return;
  3044.  
  3045.     case ARGUMENT:
  3046.       arg = (Argument *) node;
  3047.       bindVarNames (arg->expr, varMapping);
  3048.       bindVarNames (arg->next, varMapping);
  3049.       return;
  3050.  
  3051.     case COUNT_VALUE:
  3052.       countValue = (CountValue *) node;
  3053.       bindVarNames (countValue->count, varMapping);
  3054.       bindVarNames (countValue->value, varMapping);
  3055.       bindVarNames (countValue->next, varMapping);
  3056.       return;
  3057.  
  3058.     case FIELD_INIT:
  3059.       fieldInit = (FieldInit *) node;
  3060.       bindVarNames (fieldInit->expr, varMapping);
  3061.       bindVarNames (fieldInit->next, varMapping);
  3062.       return;
  3063.  
  3064.     default:
  3065.       printf ("\nnode->op = %s\n", symbolName (node->op));
  3066.       programLogicError ("Unkown op in bindVarNames");
  3067.   }
  3068. }
  3069.  
  3070.  
  3071.  
  3072. // setFourByteRestricted (type)
  3073. //
  3074. // This routine is passed a type.  If that type is a type parameter,
  3075. // it will set the "fourByteRestricted" field in the type parameter.
  3076. //
  3077. void setFourByteRestricted (Type * t) {
  3078.   TypeParm * typeParm;
  3079.   NamedType * nType = (NamedType *) t;
  3080.  
  3081.   if (nType->op == NAMED_TYPE) {
  3082.     typeParm = (TypeParm *) nType->myDef;
  3083.     if (typeParm && typeParm->op == TYPE_PARM) {
  3084.       typeParm->fourByteRestricted = 1;
  3085.     }
  3086.   }
  3087. }
  3088.  
  3089.  
  3090.  
  3091. // assignOffsetsAndEvalExprs (hdr)
  3092. //
  3093. // This routine runs through all classes and assigns offsets
  3094. // to each class and record field and computes the size of each class object.
  3095. //
  3096. // This routine also evaluates all static expressions.
  3097. //
  3098. // This routine catches...
  3099. //    Errors related to problems evaluating static expressions (eg, 4/0)
  3100. //    Errors in determining the size of fields, locals, and parms
  3101. //    Errors in assigning offsets to fields, locals, and parms
  3102. //    Errors in determining the size of classes or records
  3103. //
  3104. // NOTE: We have a chicken-and-egg problem.  Sizes of types can depend on expressions
  3105. // and expressions can depend on the sizes of types.  Here is an example:
  3106. //        const MAX = 1000
  3107. //        type T1 = array [MAX+1] of char
  3108. //        const SIZ = (sizeOf T1) - 4
  3109. //        type T2 = array [SIZ] of int
  3110. // Therefore, we use an iterative approach, which keeps processing until there are
  3111. // no further changes.  Then, in a final pass, it prints errors.
  3112. //
  3113. void assignOffsetsAndEvalExprs (Header * hdr) {
  3114.  
  3115.   // Keep making passes until we are not making any progress.
  3116.   changed = 1;
  3117.   while (changed) {
  3118.     changed = 0;
  3119.     // printf ("\n---MAKING NEXT PASS---\n\n");
  3120.     assignOffsets2 (hdr, 0);      // wantPrinting = false
  3121.     evalExprsIn (hdr);
  3122.   }
  3123.  
  3124.   // printf ("\n---MAKING FINAL PASS---\n\n");
  3125.  
  3126.   // Make one more pass to print any errors.
  3127.   assignOffsets2 (hdr, 1);        // wantPrinting = true
  3128. }
  3129.  
  3130.  
  3131.  
  3132. // assignOffsets2 (node, wantPrinting)
  3133. //
  3134. // This routine visits all nodes.
  3135. //
  3136. // For each class, it attempts to assign offsets to each field and to compute the
  3137. // size of each class object.
  3138. //
  3139. // For each record, it attempts to assign offsets to each field and to compute the
  3140. // size of each record object.
  3141. //
  3142. // It also attempts to assign offsets to parameters and local variables.
  3143. //
  3144. // This routine is passed "wantPrinting".  If true, any errors are reported.
  3145. // If false, errors are not printed.
  3146. //
  3147. // This routine sets 'changed' if anything was changed.
  3148. //
  3149. void assignOffsets2 (AstNode * node, int wantPrinting) {
  3150.     Header * header;
  3151.     Code * code;
  3152.     Uses * uses;
  3153.     Renaming * renaming;
  3154.     Interface * interface;
  3155.     ClassDef * cl;
  3156.     Behavior * behavior;
  3157.     TypeDef * typeDef;
  3158.     ConstDecl * constDecl;
  3159.     ErrorDecl * errorDecl;
  3160.     FunctionProto * functionProto;
  3161.     Function * fun;
  3162.     MethodProto * methodProto;
  3163.     Method * meth;
  3164.     TypeParm * typeParm;
  3165.     TypeArg * typeArg;
  3166.     PtrType * pType;
  3167.     ArrayType * aType;
  3168.     RecordType * rType;
  3169.     FunctionType * fType;
  3170.     NamedType * nType;
  3171.     IfStmt * ifStmt;
  3172.     AssignStmt * assignStmt;
  3173.     CallStmt * callStmt;
  3174.     SendStmt * sendStmt;
  3175.     WhileStmt * whileStmt;
  3176.     DoStmt * doStmt;
  3177.     BreakStmt * breakStmt;
  3178.     ContinueStmt * continueStmt;
  3179.     ReturnStmt * returnStmt;
  3180.     ForStmt * forStmt;
  3181.     SwitchStmt * switchStmt;
  3182.     TryStmt * tryStmt;
  3183.     ThrowStmt * throwStmt;
  3184.     FreeStmt * freeStmt;
  3185.     DebugStmt * debugStmt;
  3186.     Case * cas;
  3187.     Catch * cat;
  3188.     Global * global;
  3189.     Local * local;
  3190.     Parameter * parm;
  3191.     ClassField * classField;
  3192.     RecordField * recordField;
  3193.     CallExpr * callExpr;
  3194.     SendExpr * sendExpr;
  3195.     SelfExpr * selfExpr;
  3196.     SuperExpr * superExpr;
  3197.     FieldAccess * fieldAccess;
  3198.     ArrayAccess * arrayAccess;
  3199.     Constructor * constructor;
  3200.     ClosureExpr * closureExpr;
  3201.     AsPtrToExpr * asPtrToExpr;
  3202.     AsIntegerExpr * asIntegerExpr;
  3203.     ArraySizeExpr * arraySizeExpr;
  3204.     IsInstanceOfExpr * isInstanceOfExpr;
  3205.     IsKindOfExpr * isKindOfExpr;
  3206.     SizeOfExpr * sizeOfExpr;
  3207.     Argument * arg;
  3208.     CountValue * countValue;
  3209.     FieldInit * fieldInit;
  3210.     int junk;
  3211.  
  3212.   if (node == NULL) return;
  3213.  
  3214.   // printf ("AssignOffsets in %s...\n", symbolName (node->op));
  3215.  
  3216.   switch (node->op) {
  3217.  
  3218.     case HEADER:
  3219.       header = (Header *) node;
  3220.       // printf ("  %s\n", header->packageName->chars);
  3221.       assignOffsets2 (header->uses, wantPrinting);
  3222.       assignOffsets2 (header->consts, wantPrinting);
  3223.       assignOffsets2 (header->errors, wantPrinting);
  3224.       assignOffsets2 (header->globals, wantPrinting);
  3225.       for (global = header->globals; global; global = (Global *) global->next) {
  3226.         global->sizeInBytes = sizeInBytesOfWhole (global->type, global, wantPrinting);
  3227.       }
  3228.       assignOffsets2 (header->typeDefs, wantPrinting);
  3229.       assignOffsets2 (header->functionProtos, wantPrinting);
  3230.       assignOffsets2 (header->functions, wantPrinting);
  3231.       assignOffsets2 (header->closures, wantPrinting);
  3232.       assignOffsets2 (header->interfaces, wantPrinting);
  3233.       assignOffsets2 (header->classes, wantPrinting);
  3234.       // assignOffsets2 (header->next, wantPrinting);
  3235.       return;
  3236.  
  3237. //    case CODE:
  3238. //      code = (Code *) node;
  3239. //      assignOffsets2 (code->consts, wantPrinting);
  3240. //      assignOffsets2 (code->globals, wantPrinting);
  3241. //      assignOffsets2 (code->typeDefs, wantPrinting);
  3242. //      assignOffsets2 (code->functions, wantPrinting);
  3243. //      assignOffsets2 (code->interfaces, wantPrinting);
  3244. //      assignOffsets2 (code->classes, wantPrinting);
  3245. //      assignOffsets2 (code->behaviors, wantPrinting);
  3246. //      return;
  3247.  
  3248.     case USES:
  3249.       uses = (Uses *) node;
  3250.       assignOffsets2 (uses->renamings, wantPrinting);
  3251.       assignOffsets2 (uses->next, wantPrinting);
  3252.       return;
  3253.  
  3254.     case RENAMING:
  3255.       renaming = (Renaming *) node;
  3256.       assignOffsets2 (renaming->next, wantPrinting);
  3257.       return;
  3258.  
  3259.     case INTERFACE:
  3260.       interface = (Interface *) node;
  3261.       // printf ("  %s\n", interface->id->chars);
  3262.       assignOffsets2 (interface->typeParms, wantPrinting);
  3263.       assignOffsets2 (interface->extends, wantPrinting);
  3264.       assignOffsets2 (interface->methodProtos, wantPrinting);
  3265.       assignOffsets2 (interface->next, wantPrinting);
  3266.       return;
  3267.  
  3268.     case CLASS_DEF:
  3269.       cl = (ClassDef *) node;
  3270.       // printf ("  %s\n", cl->id->chars);
  3271.  
  3272.       // Assign offsets to the fields...
  3273.       assignOffsetsInClass (cl, wantPrinting);
  3274.  
  3275.       assignOffsets2 (cl->typeParms, wantPrinting);
  3276.       assignOffsets2 (cl->implements, wantPrinting);
  3277.       assignOffsets2 (cl->superclass, wantPrinting);
  3278. //      assignOffsets2 (cl->renamings, wantPrinting);
  3279.       assignOffsets2 (cl->fields, wantPrinting);
  3280.       assignOffsets2 (cl->methodProtos, wantPrinting);
  3281.       assignOffsets2 (cl->methods, wantPrinting);
  3282.       assignOffsets2 (cl->next, wantPrinting);
  3283.       return;
  3284.  
  3285. //    case BEHAVIOR:
  3286. //      behavior = (Behavior *) node;
  3287. //      printf ("  %s\n", behavior->id->chars);
  3288. //      assignOffsets2 (behavior->methods, wantPrinting);
  3289. //      assignOffsets2 (behavior->next, wantPrinting);
  3290. //      return;
  3291.  
  3292.     case TYPE_DEF:
  3293.       typeDef = (TypeDef *) node;
  3294.       // printf ("  %s\n", typeDef->id->chars);
  3295.       assignOffsets2 (typeDef->type, wantPrinting);
  3296.       assignOffsets2 (typeDef->next, wantPrinting);
  3297.       return;
  3298.  
  3299.     case CONST_DECL:
  3300.       constDecl = (ConstDecl *) node;
  3301.       // printf ("  %s\n", constDecl->id->chars);
  3302.       assignOffsets2 (constDecl->expr, wantPrinting);
  3303.       assignOffsets2 (constDecl->next, wantPrinting);
  3304.       return;
  3305.  
  3306.     case ERROR_DECL:
  3307.       errorDecl = (ErrorDecl *) node;
  3308.       // printf ("  ASSIGNING OFFSETS IN ERROR_DECL %s\n", errorDecl->id->chars);
  3309.       // printf ("    wantPrinting = %d\n", wantPrinting);
  3310.       assignOffsets2 (errorDecl->parmList, wantPrinting);
  3311.       assignOffsets2 (errorDecl->next, wantPrinting);
  3312.       // Assign offsets to the parameters...
  3313.       errorDecl->totalParmSize =
  3314.             assignOffsetsInParmList (errorDecl->parmList,wantPrinting, 8);
  3315.                                                   // starting offset = 8
  3316.  
  3317.       return;
  3318.  
  3319.     case FUNCTION_PROTO:
  3320.       functionProto = (FunctionProto *) node;
  3321.       // printf ("  Function Proto %s\n", functionProto->id->chars);
  3322.       assignOffsets2 (functionProto->parmList, wantPrinting);
  3323.       // Assign offsets to the parameters...
  3324.       functionProto->totalParmSize =
  3325.              assignOffsetsInParmList (functionProto->parmList, wantPrinting, 8);
  3326.                                                         // starting offset = 8
  3327.       assignOffsets2 (functionProto->retType, wantPrinting);
  3328.       assignOffsets2 (functionProto->next, wantPrinting);
  3329.       return;
  3330.  
  3331.     case FUNCTION:
  3332.       fun = (Function *) node;
  3333.       // if (fun->id) {
  3334.       //   printf ("  Function %s\n", fun->id->chars);
  3335.       // } else {
  3336.       //   printf ("  Closure\n");
  3337.       // }
  3338.       assignOffsets2 (fun->parmList, wantPrinting);
  3339.  
  3340.       // Assign offsets to the parameters...
  3341.       fun->totalParmSize =
  3342.              assignOffsetsInParmList (fun->parmList, wantPrinting, 8);
  3343.                                               // starting offset = 8
  3344.  
  3345.       assignOffsets2 (fun->retType, wantPrinting);
  3346.       assignOffsets2 (fun->locals, wantPrinting);
  3347.       // Offsets for locals will be assigned later, since tems may get added later...
  3348.       assignOffsets2 (fun->stmts, wantPrinting);
  3349.       assignOffsets2 (fun->next, wantPrinting);
  3350.       return;
  3351.  
  3352.     case METHOD_PROTO:
  3353.       methodProto = (MethodProto *) node;
  3354.       // printf ("  %s\n", methodProto->selector->chars);
  3355.       assignOffsets2 (methodProto->parmList, wantPrinting);
  3356.  
  3357.       // Assign offsets to the parameters...
  3358.       methodProto->totalParmSize = 4 +                // Space for receiver
  3359.              assignOffsetsInParmList (methodProto->parmList, wantPrinting, 12);
  3360.                                                       // starting offset = 12
  3361.       assignOffsets2 (methodProto->retType, wantPrinting);
  3362.       assignOffsets2 (methodProto->next, wantPrinting);
  3363.       return;
  3364.  
  3365.     case METHOD:
  3366.       meth = (Method *) node;
  3367.       // printf ("  %s\n", meth->selector->chars);
  3368.       assignOffsets2 (meth->parmList, wantPrinting);
  3369.  
  3370.       // Assign offsets to the parameters...
  3371.       meth->totalParmSize = 4 +                // Space for receiver
  3372.              assignOffsetsInParmList (meth->parmList, wantPrinting, 12);
  3373.                                                // starting offset = 12
  3374.  
  3375.       assignOffsets2 (meth->retType, wantPrinting);
  3376.       assignOffsets2 (meth->locals, wantPrinting);
  3377.       // Offsets will be assigned to the locals, since temps may get added later...
  3378.       assignOffsets2 (meth->stmts, wantPrinting);
  3379.       assignOffsets2 (meth->next, wantPrinting);
  3380.       return;
  3381.  
  3382.     case TYPE_PARM:
  3383.       typeParm = (TypeParm *) node;
  3384.       assignOffsets2 (typeParm->type, wantPrinting);
  3385.       assignOffsets2 (typeParm->next, wantPrinting);
  3386.       return;
  3387.  
  3388.     case TYPE_ARG:
  3389.       typeArg = (TypeArg *) node;
  3390.       assignOffsets2 (typeArg->type, wantPrinting);
  3391.       assignOffsets2 (typeArg->next, wantPrinting);
  3392.       return;
  3393.  
  3394.     case CHAR_TYPE:
  3395.       return;
  3396.  
  3397.     case INT_TYPE:
  3398.       return;
  3399.  
  3400.     case DOUBLE_TYPE:
  3401.       return;
  3402.  
  3403.     case BOOL_TYPE:
  3404.       return;
  3405.  
  3406.     case VOID_TYPE:
  3407.       return;
  3408.  
  3409.     case TYPE_OF_NULL_TYPE:
  3410.       return;
  3411.  
  3412.     case ANY_TYPE:
  3413.       return;
  3414.  
  3415.     case PTR_TYPE:
  3416.       pType = (PtrType *) node;
  3417.       assignOffsets2 (pType->baseType, wantPrinting);
  3418.       return;
  3419.  
  3420.     case ARRAY_TYPE:
  3421.       aType = (ArrayType *) node;
  3422.       assignOffsets2 (aType->sizeExpr, wantPrinting);
  3423.       assignOffsets2 (aType->baseType, wantPrinting);
  3424.       // Compute the size of the array, if we can.  If not, no problem...
  3425.       if (aType->sizeInBytes < 0) {
  3426.         aType->sizeInBytes = sizeInBytesOfWhole (aType, node, 0);   // wantPrinting = 0
  3427.         aType->sizeOfElements = sizeInBytesOfWhole (aType->baseType, node, 0);
  3428.                                                                     // wantPrinting = 0
  3429.       }
  3430.       junk = sizeInBytesOfWhole (aType->baseType, aType->baseType, wantPrinting);
  3431.       return;
  3432.  
  3433.     case RECORD_TYPE:
  3434.       rType = (RecordType *) node;
  3435.       // printf ("  ASSIGNING OFFSETS IN RECORD...\n");
  3436.  
  3437.       // Assign offsets to the fields...
  3438.       assignOffsetsInRecord (rType, wantPrinting);
  3439.  
  3440.       assignOffsets2 (rType->fields, wantPrinting);
  3441.       return;
  3442.  
  3443.     case FUNCTION_TYPE:
  3444.       fType = (FunctionType *) node;
  3445.       assignOffsets2 (fType->parmTypes, wantPrinting);
  3446.       assignOffsets2 (fType->retType, wantPrinting);
  3447.       return;
  3448.  
  3449.     case NAMED_TYPE:
  3450.       nType = (NamedType *) node;
  3451.       assignOffsets2 (nType->typeArgs, wantPrinting);
  3452.       return;
  3453.  
  3454.     case IF_STMT:
  3455.       ifStmt = (IfStmt *) node;
  3456.       assignOffsets2 (ifStmt->expr, wantPrinting);
  3457.       assignOffsets2 (ifStmt->thenStmts, wantPrinting);
  3458.       assignOffsets2 (ifStmt->elseStmts, wantPrinting);
  3459.       assignOffsets2 (ifStmt->next, wantPrinting);
  3460.       return;
  3461.  
  3462.     case ASSIGN_STMT:
  3463.       assignStmt = (AssignStmt *) node;
  3464.       assignOffsets2 (assignStmt->lvalue, wantPrinting);
  3465.       assignOffsets2 (assignStmt->expr, wantPrinting);
  3466.       assignOffsets2 (assignStmt->next, wantPrinting);
  3467.       return;
  3468.  
  3469.     case CALL_STMT:
  3470.       callStmt = (CallStmt *) node;
  3471.       assignOffsets2 (callStmt->expr, wantPrinting);
  3472.       assignOffsets2 (callStmt->next, wantPrinting);
  3473.       return;
  3474.  
  3475.     case SEND_STMT:
  3476.       sendStmt = (SendStmt *) node;
  3477.       assignOffsets2 (sendStmt->expr, wantPrinting);
  3478.       assignOffsets2 (sendStmt->next, wantPrinting);
  3479.       return;
  3480.  
  3481.     case WHILE_STMT:
  3482.       whileStmt = (WhileStmt *) node;
  3483.       assignOffsets2 (whileStmt->expr, wantPrinting);
  3484.       assignOffsets2 (whileStmt->stmts, wantPrinting);
  3485.       assignOffsets2 (whileStmt->next, wantPrinting);
  3486.       return;
  3487.  
  3488.     case DO_STMT:
  3489.       doStmt = (DoStmt *) node;
  3490.       assignOffsets2 (doStmt->stmts, wantPrinting);
  3491.       assignOffsets2 (doStmt->expr, wantPrinting);
  3492.       assignOffsets2 (doStmt->next, wantPrinting);
  3493.       return;
  3494.  
  3495.     case BREAK_STMT:
  3496.       breakStmt = (BreakStmt *) node;
  3497.       assignOffsets2 (breakStmt->next, wantPrinting);
  3498.       return;
  3499.  
  3500.     case CONTINUE_STMT:
  3501.       continueStmt = (ContinueStmt *) node;
  3502.       assignOffsets2 (continueStmt->next, wantPrinting);
  3503.       return;
  3504.  
  3505.     case RETURN_STMT:
  3506.       returnStmt = (ReturnStmt *) node;
  3507.       assignOffsets2 (returnStmt->expr, wantPrinting);
  3508.       assignOffsets2 (returnStmt->next, wantPrinting);
  3509.       return;
  3510.  
  3511.     case FOR_STMT:
  3512.       forStmt = (ForStmt *) node;
  3513.       assignOffsets2 (forStmt->lvalue, wantPrinting);
  3514.       assignOffsets2 (forStmt->expr1, wantPrinting);
  3515.       assignOffsets2 (forStmt->expr2, wantPrinting);
  3516.       assignOffsets2 (forStmt->expr3, wantPrinting);
  3517.       assignOffsets2 (forStmt->stmts, wantPrinting);
  3518.       assignOffsets2 (forStmt->next, wantPrinting);
  3519.       return;
  3520.  
  3521.     case SWITCH_STMT:
  3522.       switchStmt = (SwitchStmt *) node;
  3523.       assignOffsets2 (switchStmt->expr, wantPrinting);
  3524.       assignOffsets2 (switchStmt->caseList, wantPrinting);
  3525.       assignOffsets2 (switchStmt->defaultStmts, wantPrinting);
  3526.       assignOffsets2 (switchStmt->next, wantPrinting);
  3527.       return;
  3528.  
  3529.     case TRY_STMT:
  3530.       tryStmt = (TryStmt *) node;
  3531.       assignOffsets2 (tryStmt->stmts, wantPrinting);
  3532.       assignOffsets2 (tryStmt->catchList, wantPrinting);
  3533.       assignOffsets2 (tryStmt->next, wantPrinting);
  3534.       return;
  3535.  
  3536.     case THROW_STMT:
  3537.       throwStmt = (ThrowStmt *) node;
  3538.       assignOffsets2 (throwStmt->argList, wantPrinting);
  3539.       assignOffsets2 (throwStmt->next, wantPrinting);
  3540.       return;
  3541.  
  3542.     case FREE_STMT:
  3543.       freeStmt = (FreeStmt *) node;
  3544.       assignOffsets2 (freeStmt->expr, wantPrinting);
  3545.       assignOffsets2 (freeStmt->next, wantPrinting);
  3546.       return;
  3547.  
  3548.     case DEBUG_STMT:
  3549.       debugStmt = (DebugStmt *) node;
  3550.       assignOffsets2 (debugStmt->next, wantPrinting);
  3551.       return;
  3552.  
  3553.     case CASE:
  3554.       cas = (Case *) node;
  3555.       assignOffsets2 (cas->expr, wantPrinting);
  3556.       assignOffsets2 (cas->stmts, wantPrinting);
  3557.       assignOffsets2 (cas->next, wantPrinting);
  3558.       return;
  3559.  
  3560.     case CATCH:
  3561.       cat = (Catch *) node;
  3562.       assignOffsets2 (cat->parmList, wantPrinting);
  3563.  
  3564.       // Assign offsets to the parameters...
  3565.       //if (commandOptionS && wantPrinting) {
  3566.       //  if (cat->id) {
  3567.       //    printf ("==========  Parameter layout for catch \"");
  3568.       //    printString (stdout, cat->id);
  3569.       //    printf ("\" (%s, line %d)  ==========\n",
  3570.       //               extractFilename (cat->tokn),
  3571.       //               extractLineNumber (cat->tokn));
  3572.       //  }
  3573.       //}
  3574.       assignOffsetsInParmList (cat->parmList, wantPrinting, 0);   // starting offset = 0
  3575.  
  3576.       assignOffsets2 (cat->stmts, wantPrinting);
  3577.       assignOffsets2 (cat->next, wantPrinting);
  3578.       return;
  3579.  
  3580.     case GLOBAL:
  3581.       global = (Global *) node;
  3582.       assignOffsets2 (global->type, wantPrinting);
  3583.       assignOffsets2 (global->initExpr, wantPrinting);
  3584.       assignOffsets2 (global->next, wantPrinting);
  3585.       return;
  3586.  
  3587.     case LOCAL:
  3588.       local = (Local *) node;
  3589.       assignOffsets2 (local->type, wantPrinting);
  3590.       assignOffsets2 (local->initExpr, wantPrinting);
  3591.       assignOffsets2 (local->next, wantPrinting);
  3592.       return;
  3593.  
  3594.     case PARAMETER:
  3595.       parm = (Parameter *) node;
  3596.       assignOffsets2 (parm->type, wantPrinting);
  3597.       assignOffsets2 (parm->next, wantPrinting);
  3598.       return;
  3599.  
  3600.     case CLASS_FIELD:
  3601.       classField = (ClassField *) node;
  3602.       assignOffsets2 (classField->type, wantPrinting);
  3603.       assignOffsets2 (classField->next, wantPrinting);
  3604.       return;
  3605.  
  3606.     case RECORD_FIELD:
  3607.       recordField = (RecordField *) node;
  3608.       assignOffsets2 (recordField->type, wantPrinting);
  3609.       assignOffsets2 (recordField->next, wantPrinting);
  3610.       return;
  3611.  
  3612.     case INT_CONST:
  3613.       return;
  3614.  
  3615.     case DOUBLE_CONST:
  3616.       return;
  3617.  
  3618.     case CHAR_CONST:
  3619.       return;
  3620.  
  3621.     case STRING_CONST:
  3622.       return;
  3623.  
  3624.     case BOOL_CONST:
  3625.       return;
  3626.  
  3627.     case NULL_CONST:
  3628.       return;
  3629.  
  3630.     case CALL_EXPR:
  3631.       callExpr = (CallExpr *) node;
  3632.       assignOffsets2 (callExpr->argList, wantPrinting);
  3633.       return;
  3634.  
  3635.     case SEND_EXPR:
  3636.       sendExpr = (SendExpr *) node;
  3637.       assignOffsets2 (sendExpr->receiver, wantPrinting);
  3638.       assignOffsets2 (sendExpr->argList, wantPrinting);
  3639.       return;
  3640.  
  3641.     case SELF_EXPR:
  3642.       selfExpr = (SelfExpr *) node;
  3643.       return;
  3644.  
  3645.     case SUPER_EXPR:
  3646.       superExpr = (SuperExpr *) node;
  3647.       return;
  3648.  
  3649.     case FIELD_ACCESS:
  3650.       fieldAccess = (FieldAccess *) node;
  3651.       assignOffsets2 (fieldAccess->expr, wantPrinting);
  3652.       return;
  3653.  
  3654.     case ARRAY_ACCESS:
  3655.       arrayAccess = (ArrayAccess *) node;
  3656.       assignOffsets2 (arrayAccess->arrayExpr, wantPrinting);
  3657.       assignOffsets2 (arrayAccess->indexExpr, wantPrinting);
  3658.       return;
  3659.  
  3660.     case CONSTRUCTOR:
  3661.       constructor = (Constructor *) node;
  3662.       assignOffsets2 (constructor->type, wantPrinting);
  3663.       assignOffsets2 (constructor->countValueList, wantPrinting);
  3664.       assignOffsets2 (constructor->fieldInits, wantPrinting);
  3665.       return;
  3666.  
  3667.     case CLOSURE_EXPR:
  3668.       closureExpr = (ClosureExpr *) node;
  3669.       // Skip this, since we'll walk the function when we do header->closures...
  3670.       // assignOffsets2 (closureExpr->function, wantPrinting);
  3671.       return;
  3672.  
  3673.     case VARIABLE_EXPR:
  3674.       return;
  3675.  
  3676.     case AS_PTR_TO_EXPR:
  3677.       asPtrToExpr = (AsPtrToExpr *) node;
  3678.       assignOffsets2 (asPtrToExpr->expr, wantPrinting);
  3679.       assignOffsets2 (asPtrToExpr->type, wantPrinting);
  3680.       return;
  3681.  
  3682.     case AS_INTEGER_EXPR:
  3683.       asIntegerExpr = (AsIntegerExpr *) node;
  3684.       assignOffsets2 (asIntegerExpr->expr, wantPrinting);
  3685.       return;
  3686.  
  3687.     case ARRAY_SIZE_EXPR:
  3688.       arraySizeExpr = (ArraySizeExpr *) node;
  3689.       assignOffsets2 (arraySizeExpr->expr, wantPrinting);
  3690.       return;
  3691.  
  3692.     case IS_INSTANCE_OF_EXPR:
  3693.       isInstanceOfExpr = (IsInstanceOfExpr *) node;
  3694.       assignOffsets2 (isInstanceOfExpr->expr, wantPrinting);
  3695.       assignOffsets2 (isInstanceOfExpr->type, wantPrinting);
  3696.       return;
  3697.  
  3698.     case IS_KIND_OF_EXPR:
  3699.       isKindOfExpr = (IsKindOfExpr *) node;
  3700.       assignOffsets2 (isKindOfExpr->expr, wantPrinting);
  3701.       assignOffsets2 (isKindOfExpr->type, wantPrinting);
  3702.       return;
  3703.  
  3704.     case SIZE_OF_EXPR:
  3705.       sizeOfExpr = (SizeOfExpr *) node;
  3706.       assignOffsets2 (sizeOfExpr->type, wantPrinting);
  3707.       return;
  3708.  
  3709.     case ARGUMENT:
  3710.       arg = (Argument *) node;
  3711.       assignOffsets2 (arg->expr, wantPrinting);
  3712.       assignOffsets2 (arg->next, wantPrinting);
  3713.       return;
  3714.  
  3715.     case COUNT_VALUE:
  3716.       countValue = (CountValue *) node;
  3717.       assignOffsets2 (countValue->count, wantPrinting);
  3718.       assignOffsets2 (countValue->value, wantPrinting);
  3719.       assignOffsets2 (countValue->next, wantPrinting);
  3720.       return;
  3721.  
  3722.     case FIELD_INIT:
  3723.       fieldInit = (FieldInit *) node;
  3724.       assignOffsets2 (fieldInit->expr, wantPrinting);
  3725.       assignOffsets2 (fieldInit->next, wantPrinting);
  3726.       return;
  3727.  
  3728.     default:
  3729.       printf ("node->op = %s\n", symbolName (node->op));
  3730.       programLogicError ("Unkown op in assignOffsets2");
  3731.   }
  3732. }
  3733.  
  3734.  
  3735.  
  3736. // assignOffsetsInClass (cl, wantPrinting)
  3737. //
  3738. // This routine attempts to assign offsets in a class and sets 'changed' if
  3739. // anything was changed.
  3740. //
  3741. void assignOffsetsInClass (ClassDef * cl, int wantPrinting) {
  3742.   int nextOffset, padding, incr;
  3743.   ClassField * classField;
  3744.  
  3745. // We start numbering class fields at 4.  (The class ptr is at offset 0.)
  3746. #define STARTING_CLASS_OFFSET 4
  3747.  
  3748.   if (wantPrinting && (cl->sizeInBytes < 0)) {
  3749.     error (cl, "I am unable to determine the size of this class");
  3750.   }
  3751.  
  3752.   // Print the class layout, if desired...
  3753.   if (commandOptionS && wantPrinting) {
  3754.     printf ("==========  Class ");
  3755.     printString (stdout, cl->id);
  3756.     printf ("  ==========\n");
  3757.     printf ("    Fields:\n");
  3758.     printf ("        Offset 0:\t4\t<class ptr>\n");
  3759.     nextOffset = STARTING_CLASS_OFFSET;
  3760.     for (classField = cl->fields;
  3761.          classField != NULL;
  3762.          classField = (ClassField *) classField->next) {
  3763.       // Display padding bytes, if necessary...
  3764.       if (needsAlignment (classField->type)) {
  3765.         padding = (3 - ((nextOffset+3) % 4));
  3766.         if ((classField->offset >= 0) && (padding != 0)) {
  3767.           printf ("        Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  3768.           nextOffset += padding;
  3769.         }
  3770.       }
  3771.       printf ("        Offset %d:\t%d\t",
  3772.         classField->offset,
  3773.         sizeInBytesOfWhole (classField->type, classField, 0));
  3774.       printString (stdout, classField->id);
  3775.       // printf (": ");
  3776.       // pretty (classField->type);
  3777.       printf ("\n");
  3778.       incr = sizeInBytesOfWhole (classField->type, classField, 0);
  3779.       nextOffset = nextOffset + incr;
  3780.     }
  3781.     padding = (3 - ((nextOffset+3) % 4));
  3782.     if (padding != 0) {
  3783.       printf ("        Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  3784.     }
  3785.     printf ("            Total size of object = %d bytes\n", cl->sizeInBytes);
  3786.   }
  3787.  
  3788.   // If we have not already done this class...
  3789.   if (cl->sizeInBytes != -1) return;
  3790.  
  3791.   // printf ("==========  Assigning offsets to fields in class ");
  3792.   // printString (stdout, cl->id);
  3793.   // printf ("...  ==========\n");
  3794.  
  3795.   // Initialize "nextOffset"...
  3796.   nextOffset = STARTING_CLASS_OFFSET;
  3797.  
  3798.   // Look at each field...
  3799.   for (classField = cl->fields;
  3800.        classField != NULL;
  3801.        classField = (ClassField *) classField->next) {
  3802.  
  3803.     // Insert padding bytes, if necessary...
  3804.     if (needsAlignment (classField->type)) {
  3805.       padding = (3 - ((nextOffset+3) % 4));
  3806.       // if (padding != 0) {
  3807.       //   printf ("        Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  3808.       // }
  3809.       nextOffset += padding;
  3810.     }
  3811.  
  3812.     // Determine size, set "offset", and increment "nextOffset"...
  3813.     classField->offset = nextOffset;
  3814.     incr = sizeInBytesOfWhole (classField->type, classField, wantPrinting);
  3815.     classField->sizeInBytes = incr;
  3816.     if (incr < 0) {
  3817.       nextOffset = -1;
  3818.       break;
  3819.     }
  3820.     nextOffset = nextOffset + incr;
  3821.  
  3822.     // printf ("        Offset %d:\t%d\t", classField->offset, incr);
  3823.     // printString (stdout, classField->id);
  3824.     // printf ("\n");
  3825.     
  3826.   }
  3827.  
  3828.   // Fill in the size of this class...
  3829.   if (nextOffset >= 0) {
  3830.     padding = (3 - ((nextOffset+3) % 4));
  3831.     // if (padding != 0) {
  3832.     //   printf ("        Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  3833.     // }
  3834.     nextOffset += padding;
  3835.     // printf ("      Success - total size in bytes = %d\n", nextOffset);
  3836.     cl->sizeInBytes = nextOffset;
  3837.     changed = 1;
  3838.   } else {
  3839.     // printf ("      Failure!\n");
  3840.   }
  3841.  
  3842. }
  3843.  
  3844.  
  3845.  
  3846. // assignOffsetsInRecord (recordType, wantPrinting)
  3847. //
  3848. // This routine attempts to assign offsets in a record and sets 'changed' if
  3849. // anything was changed.
  3850. //
  3851. void assignOffsetsInRecord (RecordType * recordType, int wantPrinting) {
  3852.   int nextOffset, padding, incr;
  3853.   RecordField * recordField;
  3854.   AstNode * def;
  3855.  
  3856. // We start numbering record fields at 4.
  3857. #define STARTING_RECORD_OFFSET 0
  3858.  
  3859.   if (wantPrinting && (recordType->sizeInBytes < 0)) {
  3860.     error (recordType, "I am unable to determine the size of this record");
  3861.   }
  3862.  
  3863.   // Print the record layout, if desired...
  3864.   if (commandOptionS && wantPrinting) {
  3865.     printf ("==========  Record Type on line %d in file %s  ==========\n",
  3866.                      extractLineNumber (recordType->tokn),
  3867.                      extractFilename (recordType->tokn));
  3868.     printf ("    Fields:\n");
  3869.  
  3870.     nextOffset = STARTING_RECORD_OFFSET;
  3871.     for (recordField = recordType->fields;
  3872.          recordField != NULL;
  3873.          recordField = (RecordField *) recordField->next) {
  3874.  
  3875.       // Display padding bytes, if necessary...
  3876.       if (needsAlignment (recordField->type)) {
  3877.         padding = (3 - ((nextOffset+3) % 4));
  3878.         if ((recordField->offset >= 0) && (padding != 0)) {
  3879.           printf ("        Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  3880.           nextOffset += padding;
  3881.         }
  3882.       }
  3883.       printf ("        Offset %d:\t%d\t",
  3884.               recordField->offset,
  3885.               sizeInBytesOfWhole (recordField->type, recordField, 0));
  3886.       printString (stdout, recordField->id);
  3887.       // printf (": ");
  3888.       // pretty (recordField->type);
  3889.       printf ("\n");
  3890.       incr = sizeInBytesOfWhole (recordField->type, recordField, 0);
  3891.       nextOffset = nextOffset + incr;
  3892.     }
  3893.     padding = (3 - ((nextOffset+3) % 4));
  3894.     if (padding != 0) {
  3895.       printf ("        Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  3896.     }
  3897.     printf ("            Total size of record = %d bytes\n", recordType->sizeInBytes);
  3898.   }
  3899.  
  3900.   // If this is the last time through and we have not already created the field
  3901.   // mapping, then do so...
  3902.   if (wantPrinting && (recordType->fieldMapping == NULL)) {
  3903.     recordType->fieldMapping = new Mapping<String, RecordField> (5, NULL);
  3904.     for (recordField = recordType->fields;
  3905.          recordField != NULL;
  3906.          recordField = (RecordField *) recordField->next) {
  3907.       def = recordType->fieldMapping->find (recordField->id);
  3908.       if (def) {
  3909.         error (recordField, "Each field name must be different");
  3910.       } else {
  3911.         recordType->fieldMapping->enter (recordField->id, recordField);
  3912.       }
  3913.     }
  3914.   }
  3915.  
  3916.   // Initialize "nextOffset"...
  3917.   nextOffset = STARTING_RECORD_OFFSET;
  3918.  
  3919.   // If we have not already done this record...
  3920.   if (recordType->sizeInBytes != -1) return;
  3921.  
  3922.   // printf ("==========  Assigning offsets to fields in RecordType...  ==========\n");
  3923.  
  3924.   // Look at each field...
  3925.   for (recordField = recordType->fields;
  3926.        recordField != NULL;
  3927.        recordField = (RecordField *) recordField->next) {
  3928.  
  3929.     // Insert padding bytes, if necessary...
  3930.     if (needsAlignment (recordField->type)) {
  3931.       padding = (3 - ((nextOffset+3) % 4));
  3932.       // if (padding != 0) {
  3933.       //   printf ("        Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  3934.       // }
  3935.       nextOffset += padding;
  3936.     } else {
  3937.       padding = 0;
  3938.     }
  3939.  
  3940.     // Determine size, set "offset", and increment "nextOffset"...
  3941.     recordField->offset = nextOffset;
  3942.     incr = sizeInBytesOfWhole (recordField->type, recordField, wantPrinting);
  3943.     recordField->sizeInBytes = incr;
  3944.     if (incr < 0) {
  3945.       nextOffset = -1;
  3946.       break;
  3947.     }
  3948.     nextOffset = nextOffset + incr;
  3949.  
  3950.     // printf ("        Offset %d:\t%d\t%s\n", recordField->offset, incr,
  3951.     //                                     recordField->id->chars);
  3952.     
  3953.   }
  3954.  
  3955.   // Fill in the size of this record.
  3956.   if (nextOffset >= 0) {
  3957.     padding = (3 - ((nextOffset+3) % 4));
  3958.     // if (padding != 0) {
  3959.     //   printf ("        Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  3960.     // }
  3961.     nextOffset += padding;
  3962.     // printf ("      Success - total size in bytes = %d\n", nextOffset);
  3963.     recordType->sizeInBytes = nextOffset;
  3964.     changed = 1;
  3965.   } else {
  3966.     // printf ("      Failure!\n");
  3967.   }
  3968. }
  3969.  
  3970.  
  3971.  
  3972. // assignOffsetsInParmList (parmList, wantPrinting, startingOffset) --> int
  3973. //
  3974. // This routine attempts to assign offsets to the parameters in a list
  3975. // and sets 'changed' if anything was changed.
  3976. //
  3977. // It returns the total size of the parameters, including padding.
  3978. //
  3979. int assignOffsetsInParmList (Parameter * parmList,
  3980.                               int wantPrinting,
  3981.                               int startingOffset) {
  3982.   int nextOffset, padding, incr;
  3983.   Parameter * parm;
  3984.  
  3985.   // printf ("==========  Assigning offsets to parameters...  ==========\n");
  3986.  
  3987.   // We start numbering parameters at the 'startingOffset'...
  3988.   nextOffset = startingOffset;
  3989.  
  3990.   // Look at each field...
  3991.   for (parm = parmList;
  3992.        parm != NULL;
  3993.        parm = (Parameter *) parm->next) {
  3994.  
  3995.     // Insert padding bytes, if necessary...
  3996.     if (needsAlignment (parm->type)) {
  3997.       padding = (3 - ((nextOffset+3) % 4));
  3998.       // if (commandOptionS && wantPrinting && padding != 0) {
  3999.       //   printf ("    Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  4000.       // }
  4001.       nextOffset += padding;
  4002.     } else {
  4003.       padding = 0;
  4004.     }
  4005.  
  4006.     // Determine size, set "offset", and increment "nextOffset"...
  4007.     incr = sizeInBytesOfWhole (parm->type, parm, wantPrinting);
  4008.     if (parm->offset != nextOffset) {
  4009.       if (incr < 0) {
  4010.         if (wantPrinting) {   // Need this message for cyclic problems...
  4011.           error (parm, "Unable to determine the size of this parameter");
  4012.         }
  4013.         nextOffset = -1;
  4014.         break;
  4015.       }
  4016.       parm->offset = nextOffset;
  4017.       parm->sizeInBytes = incr;
  4018.       changed = 1;
  4019.     }
  4020.  
  4021.     // if (commandOptionS && wantPrinting) {
  4022.     //   printf ("    Offset %d:\t%d\t%s\n", parm->offset, incr,
  4023.     //                                       parm->id->chars);
  4024.     // }
  4025.     nextOffset = nextOffset + incr;
  4026.     
  4027.   }
  4028.  
  4029.   // Figure out the padding (if necessary)...
  4030.   if (nextOffset >= 0) {
  4031.     padding = (3 - ((nextOffset+3) % 4));
  4032.     // if (commandOptionS && wantPrinting && padding != 0) {
  4033.     //   printf ("    Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  4034.     // }
  4035.     nextOffset += padding;
  4036.     // if (commandOptionS && wantPrinting) {
  4037.     //   printf ("      Success - total size in bytes = %d\n", nextOffset);
  4038.     // }
  4039.     // parmList->sizeInBytes = nextOffset;
  4040.   } else {
  4041.     // printf ("      Failure!\n");
  4042.   }
  4043.   return nextOffset - startingOffset;
  4044. }
  4045.  
  4046.  
  4047.  
  4048. // setParmSizeInFunctionType (fType)
  4049. //
  4050. // This routine computes the total size of all of the parameters and the
  4051. // size of the return value.  It then fills in "totalParmSize" in the
  4052. // FunctionType with whichever is greater.  Later, this will become the
  4053. // amount of space needed to call this type of function.
  4054. //
  4055. // If problems arise, this routine will print errors.
  4056. //
  4057. void setParmSizeInFunctionType (FunctionType * fType) {
  4058.   TypeArg * parm;
  4059.   int nextOffset = 0;
  4060.   int padding, incr;
  4061.  
  4062. // We start numbering function parameters at offset 8.
  4063. #define STARTING_FUNCTION_OFFSET 8
  4064.  
  4065.   // If we have already done the work, return immediately...
  4066.   if (fType->totalParmSize >= 0) return;
  4067.  
  4068.   // printf ("==========  Setting totalParmSize in FunctionType: ");
  4069.   // pretty (fType);
  4070.  
  4071.   // Look at each parameter...
  4072.   for (parm = fType->parmTypes;
  4073.        parm != NULL;
  4074.        parm = parm->next) {
  4075.  
  4076.     // Insert padding bytes, if necessary...
  4077.     if (needsAlignment (parm->type)) {
  4078.       padding = (3 - ((nextOffset+3) % 4));
  4079.       // if (padding != 0) {
  4080.       //   printf ("    Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  4081.       // }
  4082.       nextOffset += padding;
  4083.     }
  4084.  
  4085.     // Determine the size of this parameter...
  4086.     incr = sizeInBytesOfWhole (parm->type, parm, 1);    // wantPrinting = 1
  4087.     if (incr < 0) {
  4088.       // printf ("    Unable to determine the size of next parameter!\n");
  4089.       return;
  4090.     }
  4091.     // printf ("    Offset %d:\t%d\t", nextOffset, incr);
  4092.     // pretty (parm->type);
  4093.  
  4094.     // Set the offset and sizeInBytes
  4095.     parm->offset = nextOffset + STARTING_FUNCTION_OFFSET;
  4096.     parm->sizeInBytes = incr;
  4097.  
  4098.     // Increment the running sum...
  4099.     nextOffset = nextOffset + incr;
  4100.     
  4101.   }
  4102.  
  4103.   // Figure out the padding (if necessary)...
  4104.   padding = (3 - ((nextOffset+3) % 4));
  4105.   // if (padding != 0) {
  4106.   //   printf ("    Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  4107.   // }
  4108.   nextOffset += padding;
  4109.  
  4110.   // printf ("      Success - total size in bytes = %d\n", nextOffset);
  4111.  
  4112.   // Figure out the size of the return value...
  4113.   if (isVoidType (fType->retType)) {
  4114.     incr = 0;
  4115.     fType->retSize = -1;
  4116.   } else {
  4117.     incr = sizeInBytesOfWhole (fType->retType, fType->retType, 1);    // wantPrinting = 1
  4118.     fType->retSize = incr;
  4119.     if (incr < 0) {
  4120.       // printf ("    Unable to determine the size of return value!\n");
  4121.       // printf ("              incr = %d\n", incr);
  4122.       incr = 0;
  4123.     } else {
  4124.       // printf ("    RetType: size = %d   type = ", incr);
  4125.       // pretty (fType->retType);
  4126.       if (incr < 4) {
  4127.         incr = 4;
  4128.       }
  4129.     }
  4130.   }
  4131.  
  4132.   // Set "totalParmSize" to whichever is greater...
  4133.   if (nextOffset > incr) {
  4134.     fType->totalParmSize = nextOffset;
  4135.   } else {
  4136.     fType->totalParmSize = incr;
  4137.   }
  4138.   // printf ("==========  TotalParmSize = %d\n", fType->totalParmSize);
  4139.  
  4140.   return;
  4141. }
  4142.  
  4143.  
  4144.  
  4145. // needsAlignment (type) --> boolean
  4146. //
  4147. // This routine returns true if variables of this type will need to
  4148. // be word aligned; and false otherwise.
  4149. //
  4150. int needsAlignment (Type * type) {
  4151.   AstNode * node;
  4152.   node = getTypeDef (type);
  4153.   if (node == NULL) return 0;
  4154.   switch (node->op) {
  4155.     case CHAR_TYPE:
  4156.       return 0;
  4157.     case INT_TYPE:
  4158.       return 1;
  4159.     case DOUBLE_TYPE:
  4160.       return 1;
  4161.     case BOOL_TYPE:
  4162.       return 0;
  4163.     case VOID_TYPE:
  4164.       return 0;
  4165.     case TYPE_OF_NULL_TYPE:
  4166.       return 1;
  4167.     case ANY_TYPE:
  4168.       return 1;
  4169.     case PTR_TYPE:
  4170.       return 1;
  4171.     case ARRAY_TYPE:
  4172.       return 1;
  4173.     case RECORD_TYPE:
  4174.       return 1;
  4175.     case FUNCTION_TYPE:
  4176.       return 1;
  4177.     case CLASS_DEF:
  4178.       return 1;
  4179.     case INTERFACE:
  4180.       return 1;
  4181.     case TYPE_PARM:
  4182.       return 1;
  4183.     default:
  4184.       printf ("node->op = %s\n", symbolName (node->op));
  4185.       programLogicError ("Unknown op in needsAlignment");
  4186.       return 0;
  4187.   }
  4188. }
  4189.  
  4190.  
  4191.  
  4192. // getTypeDef (type) --> node
  4193. //
  4194. // This routine handles cases where the type is a NamedType, which will name
  4195. //        TypeDef
  4196. //        ClassDef
  4197. //        Interface
  4198. //        TypeParm
  4199. // This routine returns a ptr to the underlying definition, i.e., to a...
  4200. //        xxxx_TYPE
  4201. //        CLASS_DEF
  4202. //        INTERFACE
  4203. //        TYPE_PARM
  4204. //
  4205. // If it names a TypeDef, e.g., "type T = ptr to int", we return the underlying type.
  4206. // If it names a ClassDef or Interface, we return a ptr to the definition.
  4207. // It it names a TypeParm; then we return a ptr to the TYPE_PARM node itself, not the
  4208. // constraint type.
  4209. //
  4210. // This routine returns NULL if problems occur.
  4211. //
  4212. AstNode * getTypeDef (Type * type) {
  4213.   AstNode * def;
  4214.  
  4215.   if (type == NULL) return NULL;
  4216.   if (type->op != NAMED_TYPE) return type;
  4217.   def = ((NamedType *) type)->myDef;
  4218.   if (def == NULL) return NULL;
  4219.  
  4220.   // printf ("getTypeDef called on: %s...\n", ((NamedType *) type)->id->chars);
  4221.   // if (((NamedType *) type)->id == lookupAndAdd ("SomeTypeName", ID)) {
  4222.   //   printf ("--------  GOT IT  ----------\n");
  4223.   // }
  4224.  
  4225.   switch (def->op) {
  4226.     case INTERFACE:
  4227.     case CLASS_DEF:
  4228.     case TYPE_PARM:
  4229.       return def;
  4230.     case TYPE_DEF:
  4231.       return getTypeDef (((TypeDef *) def)->type);
  4232.     default:
  4233.       printf ("\ndef->op = %s\n", symbolName (def->op));
  4234.       programLogicError ("Unexpected op in getTypeDef");
  4235.   }
  4236. }
  4237.  
  4238.  
  4239.  
  4240. // sizeInBytesOfWhole (type, errNode, wantPrinting) --> int
  4241. //
  4242. // This routine returns the size of objects of the given type.  It returns -1
  4243. // if there is a problem or the size cannot be determined.
  4244. //
  4245. // If "wantPrinting" is true, then we will also print an error message
  4246. // if we run into problems.
  4247. //
  4248. // When passed a NULL, it indicates that previous errors have occured; this
  4249. // routine will simply return -1 without printing anything.
  4250. //
  4251. // This routine sets 'changed' if anything was changed.
  4252. //
  4253. int sizeInBytesOfWhole (Type * type, AstNode * errNode, int wantPrinting) {
  4254.   AstNode * node;
  4255.   ArrayType * arrayType;
  4256.   int elementSize, size, padding;
  4257.   IntConst * intConst;
  4258.  
  4259.   // printf ("sizeInBytesOfWhole... ");
  4260.   // pretty (type);
  4261.  
  4262.   node = getTypeDef (type);
  4263.   if (node == NULL) return -1;
  4264.  
  4265.   switch (node->op) {
  4266.  
  4267.     case CHAR_TYPE:
  4268.       return 1;
  4269.  
  4270.     case INT_TYPE:
  4271.       return 4;
  4272.  
  4273.     case DOUBLE_TYPE:
  4274.       return 8;
  4275.  
  4276.     case BOOL_TYPE:
  4277.       return 1;
  4278.  
  4279.     case VOID_TYPE:
  4280.       if (wantPrinting) {
  4281.         error (errNode, "You may not have a variable with type 'void' since it has no specific size (Perhaps you can use a 'ptr to void'...)");
  4282.       }
  4283.       return -1;
  4284.  
  4285.     case TYPE_OF_NULL_TYPE:
  4286.       return 4;
  4287.  
  4288.     case ANY_TYPE:
  4289.       if (wantPrinting) {
  4290.         error (errNode, "You may not have a variable with type 'anyType' since it has no specific size (Perhaps you can use a 'ptr to anyType'...)");
  4291.       }
  4292.       return -1;
  4293.  
  4294.     case PTR_TYPE:
  4295.       return 4;
  4296.  
  4297.     case ARRAY_TYPE:
  4298.       arrayType = (ArrayType *) node;
  4299.       // printf ("sizeInBytesOfWhole/ARRAY_TYPE...\n");
  4300.       // See if we've already done the work...
  4301.       if (arrayType->sizeInBytes >= 0) {
  4302.         return arrayType->sizeInBytes;
  4303.       }
  4304.       if (recursionCounter++ > 100) {
  4305.         error (arrayType, "This type appears to be recursively defined");
  4306.         recursionCounter--;
  4307.         arrayType->sizeInBytes = 100;   // Save an arbitrary size to suppress other errors
  4308.         return -1;
  4309.       }
  4310.       elementSize = sizeInBytesOfWhole (arrayType->baseType, errNode, wantPrinting);
  4311.       recursionCounter--;
  4312.       if (elementSize < 0) {
  4313.         if (wantPrinting) {
  4314.           error (errNode, "I am unable to determine the size of this variable (since I am unable to determine the size of the array elements)");
  4315.         }
  4316.         return -1;
  4317.       }
  4318.       if (arrayType->sizeExpr == NULL) {
  4319.         if (wantPrinting) {
  4320.           error (errNode, "I am unable to determine the size of this variable since the number of array elements is unspecified; use something like 'array [100] of ...'");
  4321.         }
  4322.         return -1;
  4323.       }
  4324.       intConst = (IntConst *) arrayType->sizeExpr;
  4325.       if (intConst->op != INT_CONST) {
  4326.         if (wantPrinting) {
  4327.           error (errNode, "I am unable to determine the size of this variable since the number of array elements cannot be determined at compile time; try using a constant integer value");
  4328.         }
  4329.         return -1;
  4330.       }
  4331.       size = intConst->ivalue * elementSize + 4;   // 4 bytes for "number of elements"
  4332.       if (intConst->ivalue <= 0) {
  4333.         if (wantPrinting) {
  4334.           error (errNode, "The number of array elements must be greater than zero");
  4335.         }
  4336.         return -1;
  4337.       }
  4338.       if ((((double) (intConst->ivalue)) * ((double) elementSize)) + 4.0 > 2147483647.0) {
  4339.         if (wantPrinting) {
  4340.           error (errNode, "The size of this array exceeds 2147483647 bytes");
  4341.         }
  4342.         return -1;
  4343.       }
  4344.       // Pad to a multiple of 4...
  4345.       padding = (3 - ((size+3) % 4));
  4346.       size += padding;
  4347.       // printf ("  Array basicSize = %d, padding = %d, finalSize= %d\n",
  4348.       //           size-padding, padding, size);
  4349.       arrayType->sizeInBytes = size;
  4350.       arrayType->sizeOfElements = elementSize;
  4351.       changed = 1;
  4352.       return size;
  4353.  
  4354.     case RECORD_TYPE:
  4355.       if (wantPrinting && ((RecordType *) node)->sizeInBytes == -1) {
  4356.         error (errNode, "I am unable to determine the size of this variable (since I am unable to determine the size of its RecordType)");
  4357.       }
  4358.       return ((RecordType *) node)->sizeInBytes;
  4359.  
  4360.     case FUNCTION_TYPE:
  4361.       if (wantPrinting) {
  4362.         error (errNode, "You may not have a variable with type 'function' since it has no specific size (Perhaps you can use a 'ptr to function'...)");
  4363.       }
  4364.       return -1;
  4365.  
  4366.     case CLASS_DEF:
  4367.       if (wantPrinting && ((ClassDef *) node)->sizeInBytes == -1) {
  4368.         error (errNode, "I am unable to determine the size of this variable (since I am unable to determine the size of its Class type)");
  4369.       }
  4370.       return ((ClassDef *) node)->sizeInBytes;
  4371.  
  4372.     case INTERFACE:
  4373.       if (wantPrinting) {
  4374.         error (errNode, "You may not have a variable whose type is an interface since I cannot determine the size of the object (Perhaps you can use a ptr to it...)");
  4375.       }
  4376.       return -1;
  4377.  
  4378.     case TYPE_PARM:
  4379.       if (((TypeParm *) node)->fourByteRestricted) {
  4380.         return 4;
  4381.       } else {
  4382.         if (wantPrinting) {
  4383.           error (node, "This Type Parameter is used in way that requires its size to be known, but it cannot be known at compile-time");
  4384.           error2 (errNode, "Here is the place where the problem was noticed");
  4385.         }
  4386.         return -1;
  4387.       }
  4388.  
  4389.     default:
  4390.       printf ("node->op = %s\n", symbolName (node->op));
  4391.       programLogicError ("Unknown op in sizeInBytesOfWhole");
  4392.       return -1;
  4393.   }
  4394. }
  4395.  
  4396.  
  4397.  
  4398. // evalExprsIn (node) --> node
  4399. //
  4400. // This routine walks the entire program.  It evaluates several statically
  4401. // evaluable expressions, replacing some branches in the tree with
  4402. // new branches indicating the reduced, simplified values.  If any simplication
  4403. // is made, it sets "changed".
  4404. //
  4405. // When passed an expression, this routine returns the (possibly revised) expression
  4406. // subtree.  Otherwise, it returns the node itself.
  4407. //
  4408. // This routine performs the following expression evaluations:
  4409. //
  4410. //    bool == bool
  4411. //    bool != bool
  4412. //    bool & bool    - logical and
  4413. //    bool | bool    - logical or
  4414. //    bool ^ bool    - logical xor  (same as "bool != bool")
  4415. //    ! bool         - logical not
  4416. //
  4417. //    - int
  4418. //    int + int
  4419. //    int - int
  4420. //    int * int
  4421. //    int / int
  4422. //    int % int
  4423. //    int == int
  4424. //    int != int
  4425. //    int <  int
  4426. //    int <= int
  4427. //    int >  int
  4428. //    int >= int
  4429. //    int && int   - bitwise and
  4430. //    int || int   - bitwise or
  4431. //    int ^^ int   - bitwise xor
  4432. //    ! int        - bitwise negation
  4433. //    int << int   - shift left logical
  4434. //    int >> int   - shift right arithmetic
  4435. //    int >>> int  - shift right logical
  4436. //
  4437. //    0 == int    --> intIsZero (int)
  4438. //    0 != int    --> intNotZero (int)
  4439. //    int == 0    --> intIsZero (int)
  4440. //    int != 0    --> intNotZero (int)
  4441. //
  4442. //    -double
  4443. //    double+double
  4444. //    double-double
  4445. //    double*double
  4446. //    double/double
  4447. //
  4448. //    charToInt (char)
  4449. //    intToChar (int)
  4450. //    intToDouble (int)
  4451. //    doubleToInt (double)
  4452. //    negInf ()
  4453. //    posInf ()
  4454. //    negZero ()
  4455. //
  4456. //    sizeOf <TYPE>
  4457. //
  4458. // More compile-time evaluation may be added, if and when they become important.
  4459. //
  4460. // This routine also scans for uses of variables that have been declared as constants
  4461. // and substitutes their initializing expressions in place of the variable.
  4462. //
  4463. // Note that this routine will be called repeatedly.  It may print errors, but it
  4464. // should return a modified tree that will not result in further error messages when
  4465. // this routine again visits that same portion of the tree.
  4466. // 
  4467. AstNode * evalExprsIn (AstNode * node) {
  4468.     Header * header;
  4469.     Code * code;
  4470.     Uses * uses;
  4471.     Renaming * renaming;
  4472.     Interface * interface;
  4473.     ClassDef * cl;
  4474.     Behavior * behavior;
  4475.     TypeDef * typeDef;
  4476.     ConstDecl * constDecl;
  4477.     ErrorDecl * errorDecl;
  4478.     FunctionProto * functionProto;
  4479.     Function * fun;
  4480.     MethodProto * methodProto;
  4481.     Method * meth;
  4482.     TypeParm * typeParm;
  4483.     TypeArg * typeArg;
  4484.     CharType * charType;
  4485.     IntType * intType;
  4486.     DoubleType * doubleType;
  4487.     BoolType * boolType;
  4488.     VoidType * voidType;
  4489.     TypeOfNullType * typeOfNullType;
  4490.     AnyType * anyType;
  4491.     PtrType * pType;
  4492.     ArrayType * aType;
  4493.     RecordType * rType;
  4494.     FunctionType * fType;
  4495.     NamedType * nType;
  4496.     IfStmt * ifStmt;
  4497.     AssignStmt * assignStmt;
  4498.     CallStmt * callStmt;
  4499.     SendStmt * sendStmt;
  4500.     WhileStmt * whileStmt;
  4501.     DoStmt * doStmt;
  4502.     BreakStmt * breakStmt;
  4503.     ContinueStmt * continueStmt;
  4504.     ReturnStmt * returnStmt;
  4505.     ForStmt * forStmt;
  4506.     SwitchStmt * switchStmt;
  4507.     TryStmt * tryStmt;
  4508.     ThrowStmt * throwStmt;
  4509.     FreeStmt * freeStmt;
  4510.     DebugStmt * debugStmt;
  4511.     Case * cas;
  4512.     Catch * cat;
  4513.     Global * global;
  4514.     Local * local;
  4515.     Parameter * parm;
  4516.     ClassField * classField;
  4517.     RecordField * recordField;
  4518.     IntConst * intConst;
  4519.     DoubleConst * doubleConst;
  4520.     CharConst * charConst;
  4521.     StringConst * stringConst;
  4522.     BoolConst * boolConst;
  4523.     NullConst * nullConst;
  4524.     CallExpr * callExpr;
  4525.     SendExpr * sendExpr;
  4526.     SelfExpr * selfExpr;
  4527.     SuperExpr * superExpr;
  4528.     FieldAccess * fieldAccess;
  4529.     ArrayAccess * arrayAccess;
  4530.     Constructor * constructor;
  4531.     ClosureExpr * closureExpr;
  4532.     VariableExpr * var;
  4533.     AsPtrToExpr * asPtrToExpr;
  4534.     AsIntegerExpr * asIntegerExpr;
  4535.     ArraySizeExpr * arraySizeExpr;
  4536.     IsInstanceOfExpr * isInstanceOfExpr;
  4537.     IsKindOfExpr * isKindOfExpr;
  4538.     SizeOfExpr * sizeOfExpr;
  4539.     DynamicCheck * dynamicCheck;
  4540.     Argument * arg;
  4541.     CountValue * countValue;
  4542.     FieldInit * fieldInit;
  4543.     AstNode * x;
  4544.     int i, j, overflow;
  4545.     double r, d, d2;
  4546.  
  4547.   if (node == NULL) return node;
  4548.  
  4549.   // printf ("%s...\n", symbolName (node->op));
  4550.  
  4551.   switch (node->op) {
  4552.  
  4553.     case HEADER:
  4554.       header = (Header *) node;
  4555.       // printf ("  %s\n", header->packageName->chars);
  4556.       x = evalExprsIn (header->uses);
  4557.       x = evalExprsIn (header->consts);
  4558.       x = evalExprsIn (header->errors);
  4559.       x = evalExprsIn (header->globals);
  4560.       x = evalExprsIn (header->typeDefs);
  4561.       x = evalExprsIn (header->functionProtos);
  4562.       x = evalExprsIn (header->functions);
  4563.       x = evalExprsIn (header->closures);
  4564.       x = evalExprsIn (header->interfaces);
  4565.       x = evalExprsIn (header->classes);
  4566.       // x = evalExprsIn (header->next);
  4567.       return node;
  4568.  
  4569. //    case CODE:
  4570. //      code = (Code *) node;
  4571. //      x = evalExprsIn (code->consts);
  4572. //      x = evalExprsIn (code->globals);
  4573. //      x = evalExprsIn (code->typeDefs);
  4574. //      x = evalExprsIn (code->functions);
  4575. //      x = evalExprsIn (code->interfaces);
  4576. //      x = evalExprsIn (code->classes);
  4577. //      x = evalExprsIn (code->behaviors);
  4578. //      return node;
  4579.  
  4580.     case USES:
  4581.       uses = (Uses *) node;
  4582.       x = evalExprsIn (uses->renamings);
  4583.       x = evalExprsIn (uses->next);
  4584.       return node;
  4585.  
  4586.     case RENAMING:
  4587.       renaming = (Renaming *) node;
  4588.       x = evalExprsIn (renaming->next);
  4589.       return node;
  4590.  
  4591.     case INTERFACE:
  4592.       interface = (Interface *) node;
  4593.       // printf ("  %s\n", interface->id->chars);
  4594.       x = evalExprsIn (interface->typeParms);
  4595.       x = evalExprsIn (interface->extends);
  4596.       x = evalExprsIn (interface->methodProtos);
  4597.       x = evalExprsIn (interface->next);
  4598.       return node;
  4599.  
  4600.     case CLASS_DEF:
  4601.       cl = (ClassDef *) node;
  4602.       // printf ("  %s\n", cl->id->chars);
  4603.       x = evalExprsIn (cl->typeParms);
  4604.       x = evalExprsIn (cl->implements);
  4605.       x = evalExprsIn (cl->superclass);
  4606.       x = evalExprsIn (cl->fields);
  4607.       x = evalExprsIn (cl->methodProtos);
  4608.       x = evalExprsIn (cl->methods);
  4609.       x = evalExprsIn (cl->next);
  4610.       return node;
  4611.  
  4612. //    case BEHAVIOR:
  4613. //      behavior = (Behavior *) node;
  4614. //      printf ("  %s\n", behavior->id->chars);
  4615. //      x = evalExprsIn (behavior->methods);
  4616. //      x = evalExprsIn (behavior->next);
  4617. //      return node;
  4618.  
  4619.     case TYPE_DEF:
  4620.       typeDef = (TypeDef *) node;
  4621.       // printf ("  %s\n", typeDef->id->chars);
  4622.       x = evalExprsIn (typeDef->type);
  4623.       x = evalExprsIn (typeDef->next);
  4624.       return node;
  4625.  
  4626.     case CONST_DECL:
  4627.       constDecl = (ConstDecl *) node;
  4628.       // printf ("  %s\n", constDecl->id->chars);
  4629.       constDecl->expr = (Expression *) evalExprsIn (constDecl->expr);
  4630.       x = evalExprsIn (constDecl->next);
  4631.       return node;
  4632.  
  4633.     case ERROR_DECL:
  4634.       errorDecl = (ErrorDecl *) node;
  4635.       // printf ("  %s\n", errorDecl->id->chars);
  4636.       x = evalExprsIn (errorDecl->parmList);
  4637.       x = evalExprsIn (errorDecl->next);
  4638.       return node;
  4639.  
  4640.     case FUNCTION_PROTO:
  4641.       functionProto = (FunctionProto *) node;
  4642.       // printf ("  %s\n", functionProto->id->chars);
  4643.       x = evalExprsIn (functionProto->parmList);
  4644.       x = evalExprsIn (functionProto->retType);
  4645.       x = evalExprsIn (functionProto->next);
  4646.       return node;
  4647.  
  4648.     case FUNCTION:
  4649.       fun = (Function *) node;
  4650.       // printf ("  %s\n", fun->id->chars);
  4651.       x = evalExprsIn (fun->parmList);
  4652.       x = evalExprsIn (fun->retType);
  4653.       x = evalExprsIn (fun->locals);
  4654.       x = evalExprsIn (fun->stmts);
  4655.       x = evalExprsIn (fun->next);
  4656.       return node;
  4657.  
  4658.     case METHOD_PROTO:
  4659.       methodProto = (MethodProto *) node;
  4660.       // printf ("  %s\n", methodProto->selector->chars);
  4661.       x = evalExprsIn (methodProto->parmList);
  4662.       x = evalExprsIn (methodProto->retType);
  4663.       x = evalExprsIn (methodProto->next);
  4664.       return node;
  4665.  
  4666.     case METHOD:
  4667.       meth = (Method *) node;
  4668.       // printf ("  %s\n", meth->selector->chars);
  4669.       x = evalExprsIn (meth->parmList);
  4670.       x = evalExprsIn (meth->retType);
  4671.       x = evalExprsIn (meth->locals);
  4672.       x = evalExprsIn (meth->stmts);
  4673.       x = evalExprsIn (meth->next);
  4674.       return node;
  4675.  
  4676.     case TYPE_PARM:
  4677.       typeParm = (TypeParm *) node;
  4678.       x = evalExprsIn (typeParm->type);
  4679.       x = evalExprsIn (typeParm->next);
  4680.       return node;
  4681.  
  4682.     case TYPE_ARG:
  4683.       typeArg = (TypeArg *) node;
  4684.       x = evalExprsIn (typeArg->type);
  4685.       x = evalExprsIn (typeArg->next);
  4686.       return node;
  4687.  
  4688.     case CHAR_TYPE:
  4689.       charType = (CharType *) node;
  4690.       return node;
  4691.  
  4692.     case INT_TYPE:
  4693.       intType = (IntType *) node;
  4694.       return node;
  4695.  
  4696.     case DOUBLE_TYPE:
  4697.       doubleType = (DoubleType *) node;
  4698.       return node;
  4699.  
  4700.     case BOOL_TYPE:
  4701.       boolType = (BoolType *) node;
  4702.       return node;
  4703.  
  4704.     case VOID_TYPE:
  4705.       voidType = (VoidType *) node;
  4706.       return node;
  4707.  
  4708.     case TYPE_OF_NULL_TYPE:
  4709.       typeOfNullType = (TypeOfNullType *) node;
  4710.       return node;
  4711.  
  4712.     case ANY_TYPE:
  4713.       anyType = (AnyType *) node;
  4714.       return node;
  4715.  
  4716.     case PTR_TYPE:
  4717.       pType = (PtrType *) node;
  4718.       x = evalExprsIn (pType->baseType);
  4719.       return node;
  4720.  
  4721.     case ARRAY_TYPE:
  4722.       aType = (ArrayType *) node;
  4723.       aType->sizeExpr = (Expression *) evalExprsIn (aType->sizeExpr);
  4724.       x = evalExprsIn (aType->baseType);
  4725.       return node;
  4726.  
  4727.     case RECORD_TYPE:
  4728.       rType = (RecordType *) node;
  4729.       x = evalExprsIn (rType->fields);
  4730.       return node;
  4731.  
  4732.     case FUNCTION_TYPE:
  4733.       fType = (FunctionType *) node;
  4734.       x = evalExprsIn (fType->parmTypes);
  4735.       x = evalExprsIn (fType->retType);
  4736.       return node;
  4737.  
  4738.     case NAMED_TYPE:
  4739.       nType = (NamedType *) node;
  4740.       x = evalExprsIn (nType->typeArgs);
  4741.       return node;
  4742.  
  4743.     case IF_STMT:
  4744.       ifStmt = (IfStmt *) node;
  4745.       ifStmt->expr = (Expression *) evalExprsIn (ifStmt->expr);
  4746.       x = evalExprsIn (ifStmt->thenStmts);
  4747.       x = evalExprsIn (ifStmt->elseStmts);
  4748.       x = evalExprsIn (ifStmt->next);
  4749.       return node;
  4750.  
  4751.     case ASSIGN_STMT:
  4752.       assignStmt = (AssignStmt *) node;
  4753.       assignStmt->lvalue = (Expression *) evalExprsIn (assignStmt->lvalue);
  4754.       assignStmt->expr = (Expression *) evalExprsIn (assignStmt->expr);
  4755.       x = evalExprsIn (assignStmt->next);
  4756.       return node;
  4757.  
  4758.     case CALL_STMT:
  4759.       callStmt = (CallStmt *) node;
  4760.       callStmt->expr = (CallExpr *) evalExprsIn (callStmt->expr);
  4761.       if (callStmt->expr && (callStmt->expr->op != CALL_EXPR)) {
  4762.         error (node, "This built-in function returns a value; it may not be used as a statement");
  4763.         callStmt->expr = NULL;
  4764.       }
  4765.       x = evalExprsIn (callStmt->next);
  4766.       return node;
  4767.  
  4768.     case SEND_STMT:
  4769.       sendStmt = (SendStmt *) node;
  4770.       sendStmt->expr = (SendExpr *) evalExprsIn (sendStmt->expr);
  4771.       // This next test is theoretically unnecessary, since evalExprs will only
  4772.       // modify infix and prefix messages (unless others primitive methods are added
  4773.       // later).  Since infix and prefix messages cannot appears at the statement
  4774.       // level (else syntax error), the call to evalExprs should never modify
  4775.       // the sendStmt node.  Nevertheless, the test is left in since we may later
  4776.       // add primitive methods which would get simplified in evalExpr...
  4777.       if (sendStmt->expr && (sendStmt->expr->op != SEND_EXPR)) {
  4778.         error (node, "This built-in method returns a value; it may not be used as a statement");
  4779.         sendStmt->expr = NULL;
  4780.       }
  4781.       x = evalExprsIn (sendStmt->next);
  4782.       return node;
  4783.  
  4784.     case WHILE_STMT:
  4785.       whileStmt = (WhileStmt *) node;
  4786.       whileStmt->expr = (Expression *) evalExprsIn (whileStmt->expr);
  4787.       x = evalExprsIn (whileStmt->stmts);
  4788.       x = evalExprsIn (whileStmt->next);
  4789.       return node;
  4790.  
  4791.     case DO_STMT:
  4792.       doStmt = (DoStmt *) node;
  4793.       x = evalExprsIn (doStmt->stmts);
  4794.       doStmt->expr = (Expression *) evalExprsIn (doStmt->expr);
  4795.       x = evalExprsIn (doStmt->next);
  4796.       return node;
  4797.  
  4798.     case BREAK_STMT:
  4799.       breakStmt = (BreakStmt *) node;
  4800.       x = evalExprsIn (breakStmt->next);
  4801.       return node;
  4802.  
  4803.     case CONTINUE_STMT:
  4804.       continueStmt = (ContinueStmt *) node;
  4805.       x = evalExprsIn (continueStmt->next);
  4806.       return node;
  4807.  
  4808.     case RETURN_STMT:
  4809.       returnStmt = (ReturnStmt *) node;
  4810.       returnStmt->expr = (Expression *) evalExprsIn (returnStmt->expr);
  4811.       x = evalExprsIn (returnStmt->next);
  4812.       return node;
  4813.  
  4814.     case FOR_STMT:
  4815.       forStmt = (ForStmt *) node;
  4816.       forStmt->lvalue = (Expression *) evalExprsIn (forStmt->lvalue);
  4817.       forStmt->expr1 = (Expression *) evalExprsIn (forStmt->expr1);
  4818.       forStmt->expr2 = (Expression *) evalExprsIn (forStmt->expr2);
  4819.       forStmt->expr3 = (Expression *) evalExprsIn (forStmt->expr3);
  4820.       x = evalExprsIn (forStmt->stmts);
  4821.       x = evalExprsIn (forStmt->next);
  4822.       return node;
  4823.  
  4824.     case SWITCH_STMT:
  4825.       switchStmt = (SwitchStmt *) node;
  4826.       switchStmt->expr = (Expression *) evalExprsIn (switchStmt->expr);
  4827.       x = evalExprsIn (switchStmt->caseList);
  4828.       x = evalExprsIn (switchStmt->defaultStmts);
  4829.       x = evalExprsIn (switchStmt->next);
  4830.       return node;
  4831.  
  4832.     case TRY_STMT:
  4833.       tryStmt = (TryStmt *) node;
  4834.       x = evalExprsIn (tryStmt->stmts);
  4835.       x = evalExprsIn (tryStmt->catchList);
  4836.       x = evalExprsIn (tryStmt->next);
  4837.       return node;
  4838.  
  4839.     case THROW_STMT:
  4840.       throwStmt = (ThrowStmt *) node;
  4841.       x = evalExprsIn (throwStmt->argList);
  4842.       x = evalExprsIn (throwStmt->next);
  4843.       return node;
  4844.  
  4845.     case FREE_STMT:
  4846.       freeStmt = (FreeStmt *) node;
  4847.       freeStmt->expr = (Expression *) evalExprsIn (freeStmt->expr);
  4848.       x = evalExprsIn (freeStmt->next);
  4849.       return node;
  4850.  
  4851.     case DEBUG_STMT:
  4852.       debugStmt = (DebugStmt *) node;
  4853.       x = evalExprsIn (debugStmt->next);
  4854.       return node;
  4855.  
  4856.     case CASE:
  4857.       cas = (Case *) node;
  4858.       cas->expr = (Expression *) evalExprsIn (cas->expr);
  4859.       x = evalExprsIn (cas->stmts);
  4860.       x = evalExprsIn (cas->next);
  4861.       return node;
  4862.  
  4863.     case CATCH:
  4864.       cat = (Catch *) node;
  4865.       x = evalExprsIn (cat->parmList);
  4866.       x = evalExprsIn (cat->stmts);
  4867.       x = evalExprsIn (cat->next);
  4868.       return node;
  4869.  
  4870.     case GLOBAL:
  4871.       global = (Global *) node;
  4872.       x = evalExprsIn (global->type);
  4873.       global->initExpr = (Expression *) evalExprsIn (global->initExpr);
  4874.       x = evalExprsIn (global->next);
  4875.       return node;
  4876.  
  4877.     case LOCAL:
  4878.       local = (Local *) node;
  4879.       x = evalExprsIn (local->type);
  4880.       local->initExpr = (Expression *) evalExprsIn (local->initExpr);
  4881.       x = evalExprsIn (local->next);
  4882.       return node;
  4883.  
  4884.     case PARAMETER:
  4885.       parm = (Parameter *) node;
  4886.       x = evalExprsIn (parm->type);
  4887.       x = evalExprsIn (parm->next);
  4888.       return node;
  4889.  
  4890.     case CLASS_FIELD:
  4891.       classField = (ClassField *) node;
  4892.       x = evalExprsIn (classField->type);
  4893.       x = evalExprsIn (classField->next);
  4894.       return node;
  4895.  
  4896.     case RECORD_FIELD:
  4897.       recordField = (RecordField *) node;
  4898.       x = evalExprsIn (recordField->type);
  4899.       x = evalExprsIn (recordField->next);
  4900.       return node;
  4901.  
  4902.     case INT_CONST:
  4903.       intConst = (IntConst *) node;
  4904.       return node;
  4905.  
  4906.     case DOUBLE_CONST:
  4907.       doubleConst = (DoubleConst *) node;
  4908.       return node;
  4909.  
  4910.     case CHAR_CONST:
  4911.       charConst = (CharConst *) node;
  4912.       return node;
  4913.  
  4914.     case STRING_CONST:
  4915.       stringConst = (StringConst *) node;
  4916.       return node;
  4917.  
  4918.     case BOOL_CONST:
  4919.       boolConst = (BoolConst *) node;
  4920.       return node;
  4921.  
  4922.     case NULL_CONST:
  4923.       nullConst = (NullConst *) node;
  4924.       return node;
  4925.  
  4926.     case CALL_EXPR:
  4927.       callExpr = (CallExpr *) node;
  4928.       x = evalExprsIn (callExpr->argList);
  4929.  
  4930.       // See if we are dealing with a known function, such as "charToInt"...
  4931.       switch (callExpr->id->primitiveSymbol) {
  4932.  
  4933.        case CHAR_TO_INT:
  4934.           if ((argCount (callExpr->argList) == 1) &&
  4935.               (isCharConst (callExpr->argList->expr))) {
  4936.             i = ((CharConst *) callExpr->argList->expr)->ivalue;
  4937.             intConst = new IntConst ();
  4938.             intConst->positionAt (node);
  4939.             intConst->ivalue = i;
  4940.             changed = 1;
  4941.             return intConst;
  4942.           }
  4943.       break;
  4944.  
  4945.        case INT_TO_CHAR:
  4946.           if ((argCount (callExpr->argList) == 1) &&
  4947.               (isIntConst (callExpr->argList->expr))) {
  4948.             i = ((IntConst *) callExpr->argList->expr)->ivalue;
  4949.             if (i<-128 || i>255) {
  4950.               error (node, "During the compile-time evaluation of intToChar, the argument was not between -128 and 255");
  4951.             }
  4952.             charConst = new CharConst ();
  4953.             charConst->positionAt (node);
  4954.             charConst->ivalue = i & 0x000000ff;
  4955.             changed = 1;
  4956.             return charConst;
  4957.           }
  4958.       break;
  4959.  
  4960.        case INT_TO_DOUBLE:
  4961.           if ((argCount (callExpr->argList) == 1) &&
  4962.               (isIntConst (callExpr->argList->expr))) {
  4963.             i = ((IntConst *) callExpr->argList->expr)->ivalue;
  4964.             doubleConst = new DoubleConst ();
  4965.             doubleConst->positionAt (node);
  4966.             doubleConst->rvalue = (double) i;
  4967.             linkDouble (doubleConst);
  4968.             changed = 1;
  4969.             return doubleConst;
  4970.           }
  4971.       break;
  4972.  
  4973.        case DOUBLE_TO_INT:
  4974.           if ((argCount (callExpr->argList) == 1) &&
  4975.               (isDoubleConst (callExpr->argList->expr))) {
  4976.             r = ((DoubleConst *) callExpr->argList->expr)->rvalue;
  4977.             intConst = new IntConst ();
  4978.             intConst->positionAt (node);
  4979.             intConst->ivalue = truncateToInt (r);
  4980.             changed = 1;
  4981.             return intConst;
  4982.           }
  4983.       break;
  4984.  
  4985.        case POS_INF:
  4986.           if (argCount (callExpr->argList) != 0) {
  4987.             error (callExpr, "Primitive POS_INF expects no arguments");
  4988.           }
  4989.           doubleConst = new DoubleConst ();
  4990.           doubleConst->positionAt (node);
  4991.           r = 0.0;
  4992.           doubleConst->rvalue = 1.0 / r;
  4993.           linkDouble (doubleConst);
  4994.           changed = 1;
  4995.           return doubleConst;
  4996.  
  4997.  
  4998.        case NEG_INF:
  4999.           if (argCount (callExpr->argList) != 0) {
  5000.             error (callExpr, "Primitive NEG_INF expects no arguments");
  5001.           }
  5002.           doubleConst = new DoubleConst ();
  5003.           doubleConst->positionAt (node);
  5004.           r = 0.0;
  5005.           doubleConst->rvalue = -1.0 / r;
  5006.           linkDouble (doubleConst);
  5007.           changed = 1;
  5008.           return doubleConst;
  5009.  
  5010.  
  5011.        case NEG_ZERO:
  5012.           if (argCount (callExpr->argList) != 0) {
  5013.             error (callExpr, "Primitive NEG_ZERO expects no arguments");
  5014.           }
  5015.           doubleConst = new DoubleConst ();
  5016.           doubleConst->positionAt (node);
  5017.           r = 0.0;
  5018.           doubleConst->rvalue = -1.0 * r;
  5019.           linkDouble (doubleConst);
  5020.           changed = 1;
  5021.           return doubleConst;
  5022.  
  5023.        // The following cases are not handled here, since they are unlikely to occur
  5024.        // often and are more likely to be inserted by the compiler later.  By not
  5025.        // reducing them here, we make it easier to test them later.
  5026.        //
  5027.        //    case I_IS_ZERO:
  5028.        //    case I_NOT_ZERO:
  5029.  
  5030.       }
  5031.       return node;
  5032.  
  5033.     case SEND_EXPR:
  5034.       sendExpr = (SendExpr *) node;
  5035.       sendExpr->receiver = (Expression *) evalExprsIn (sendExpr->receiver);
  5036.       x = evalExprsIn (sendExpr->argList);
  5037.  
  5038.       // See if we are dealing with a known message, such as "+"...
  5039.       switch (sendExpr->selector->primitiveSymbol) {
  5040.  
  5041.         case PLUS:
  5042.           if (isIntConst (sendExpr->receiver)) {
  5043.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5044.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5045.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5046.               // printf ("INTEGER ADDITION DETECTED... i = %d   j = %d\n", i, j);
  5047.               intConst = new IntConst ();
  5048.               intConst->positionAt (node);
  5049.               intConst->ivalue = i + j;
  5050.               // Check for overflow...
  5051.               if ((i<0) && (j<0)) {
  5052.                 overflow = ((i+j)>=0);
  5053.               } else if ((i>0) && (j>0)) {
  5054.                 overflow = ((i+j)<=0);
  5055.               } else {
  5056.                 overflow = 0;
  5057.               }
  5058.               if (overflow) {
  5059.                 error (node,
  5060.                   "Overflow detected during compile-time evaluation of integer addition");
  5061.               }
  5062.               changed = 1;
  5063.               return intConst;
  5064.             }
  5065.           } else if (isDoubleConst (sendExpr->receiver)) {
  5066.             d = ((DoubleConst *) sendExpr->receiver)->rvalue;
  5067.             if (sendExpr->argList && isDoubleConst (sendExpr->argList->expr)) {
  5068.               d2 = ((DoubleConst *) sendExpr->argList->expr)->rvalue;
  5069.               // printf ("DOUBLE ADDITION DETECTED... d = %g   d2 = %g\n", d, d2);
  5070.               doubleConst = new DoubleConst ();
  5071.               doubleConst->positionAt (node);
  5072.               doubleConst->rvalue = d + d2;
  5073.               // Check for not-a-number; if result is +inf or -inf it will be okay
  5074.               if (isnan (doubleConst->rvalue)) {
  5075.                 error (node, "During the compile-time evaluation of this double addition operation, the result was not-a-number");
  5076.               }
  5077.               linkDouble (doubleConst);
  5078.               changed = 1;
  5079.               return doubleConst;
  5080.             }
  5081.           }
  5082.       break;
  5083.  
  5084.         case MINUS:
  5085.           if (isIntConst (sendExpr->receiver)) {
  5086.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5087.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5088.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5089.               // printf ("INTEGER SUBTRACTION DETECTED... i = %d   j = %d\n", i, j);
  5090.               intConst = new IntConst ();
  5091.               intConst->positionAt (node);
  5092.               intConst->ivalue = i - j;
  5093.               // Check for overflow...
  5094.               if ((i>=0) && (j<0)) {
  5095.                 overflow = ((i-j)<=0);
  5096.               } else if ((i<0) && (j>0)) {
  5097.                 overflow = ((i-j)>=0);
  5098.               } else {
  5099.                 overflow = 0;
  5100.               }
  5101.               if (overflow) {
  5102.                 error (node,
  5103.                   "Overflow detected during compile-time evaluation of integer subtraction");
  5104.               }
  5105.               changed = 1;
  5106.               return intConst;
  5107.             }
  5108.           } else if (isDoubleConst (sendExpr->receiver)) {
  5109.             d = ((DoubleConst *) sendExpr->receiver)->rvalue;
  5110.             if (sendExpr->argList && isDoubleConst (sendExpr->argList->expr)) {
  5111.               d2 = ((DoubleConst *) sendExpr->argList->expr)->rvalue;
  5112.               // printf ("DOUBLE SUBTRACTION DETECTED... d = %g   d2 = %g\n", d, d2);
  5113.               doubleConst = new DoubleConst ();
  5114.               doubleConst->positionAt (node);
  5115.               doubleConst->rvalue = d - d2;
  5116.               // Check for not-a-number; if result is +inf or -inf it will be okay
  5117.               if (isnan (doubleConst->rvalue)) {
  5118.                 error (node, "During the compile-time evaluation of this double subtraction operation, the result was not-a-number");
  5119.               }
  5120.               linkDouble (doubleConst);
  5121.               changed = 1;
  5122.               return doubleConst;
  5123.             }
  5124.           }
  5125.       break;
  5126.  
  5127.         case UNARY_MINUS:
  5128.           if (isIntConst (sendExpr->receiver)) {
  5129.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5130.             if (sendExpr->argList == NULL) {
  5131.               // printf ("UNARY INT-NEGATION DETECTED... i = %d\n", i);
  5132.               intConst = new IntConst ();
  5133.               intConst->positionAt (node);
  5134.               // Check for overflow...
  5135.               if (i == 0x80000000) {
  5136.                 error (node,
  5137.                   "Overflow detected during compile-time evaluation of -(0x80000000)");
  5138.                 changed = 1;
  5139.                 return sendExpr->receiver;
  5140.               }
  5141.               intConst->ivalue = - i;
  5142.               changed = 1;
  5143.               return intConst;
  5144.             }
  5145.           } else if (isDoubleConst (sendExpr->receiver)) {
  5146.             d = ((DoubleConst *) sendExpr->receiver)->rvalue;
  5147.             if (sendExpr->argList == NULL) {
  5148.               // printf ("UNARY DOUBLE-NEGATION DETECTED... d = %g\n", d);
  5149.               doubleConst = new DoubleConst ();
  5150.               doubleConst->positionAt (node);
  5151.               doubleConst->rvalue = - d;
  5152.               linkDouble (doubleConst);
  5153.               changed = 1;
  5154.               return doubleConst;
  5155.             }
  5156.           }
  5157.       break;
  5158.  
  5159.         case STAR:
  5160.           if (isIntConst (sendExpr->receiver)) {
  5161.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5162.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5163.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5164.               // printf ("INTEGER MULTIPLICATION DETECTED... i = %d   j = %d\n", i, j);
  5165.               intConst = new IntConst ();
  5166.               intConst->positionAt (node);
  5167.               intConst->ivalue = i * j;
  5168.               // Check for overflow...
  5169.               if ((((double) i) * ((double) j)) != ((double) (i*j))) {
  5170.                 error (node,
  5171.                   "Overflow detected during compile-time evaluation of integer multiplication");
  5172.               }
  5173.               changed = 1;
  5174.               return intConst;
  5175.             }
  5176.           } else if (isDoubleConst (sendExpr->receiver)) {
  5177.             d = ((DoubleConst *) sendExpr->receiver)->rvalue;
  5178.             if (sendExpr->argList && isDoubleConst (sendExpr->argList->expr)) {
  5179.               d2 = ((DoubleConst *) sendExpr->argList->expr)->rvalue;
  5180.               // printf ("DOUBLE MULTIPLICATION DETECTED... d = %g   d2 = %g\n", d, d2);
  5181.               doubleConst = new DoubleConst ();
  5182.               doubleConst->positionAt (node);
  5183.               doubleConst->rvalue = d * d2;
  5184.               // Check for not-a-number; if result is +inf or -inf it will be okay
  5185.               if (isnan (doubleConst->rvalue)) {
  5186.                 error (node, "During the compile-time evaluation of this double multiplication operation, the result was not-a-number");
  5187.               }
  5188.               linkDouble (doubleConst);
  5189.               changed = 1;
  5190.               return doubleConst;
  5191.             }
  5192.           }
  5193.       break;
  5194.  
  5195.         case SLASH:
  5196.           if (isIntConst (sendExpr->receiver)) {
  5197.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5198.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5199.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5200.               // printf ("INTEGER DIVISION DETECTED... i = %d   j = %d\n", i, j);
  5201.               // Check for overflow...
  5202.               if (j == 0) {
  5203.                 error (node, "During the compile-time evaluation of this integer division operation, the divisor was found to be zero");
  5204.               }
  5205.               if (i == 0x80000000 && j == -1) {
  5206.                 error (node, "During the compile-time evaluation of this integer division operation, overflow occurred");
  5207.               }
  5208.               divide (i, j);
  5209.               intConst = new IntConst ();
  5210.               intConst->positionAt (node);
  5211.               intConst->ivalue = quo;
  5212.               changed = 1;
  5213.               return intConst;
  5214.             }
  5215.           } else if (isDoubleConst (sendExpr->receiver)) {
  5216.             d = ((DoubleConst *) sendExpr->receiver)->rvalue;
  5217.             if (sendExpr->argList && isDoubleConst (sendExpr->argList->expr)) {
  5218.               d2 = ((DoubleConst *) sendExpr->argList->expr)->rvalue;
  5219.               // printf ("DOUBLE DIVISION DETECTED... d = %g   d2 = %g\n", d, d2);
  5220.               doubleConst = new DoubleConst ();
  5221.               doubleConst->positionAt (node);
  5222.               doubleConst->rvalue = d / d2;
  5223.               // Check for not-a-number; if result is +inf or -inf it will be okay
  5224.               if (isnan (doubleConst->rvalue)) {
  5225.                 error (node, "During the compile-time evaluation of this double division operation, the result was not-a-number");
  5226.               }
  5227.               linkDouble (doubleConst);
  5228.               changed = 1;
  5229.               return doubleConst;
  5230.             }
  5231.           }
  5232.       break;
  5233.  
  5234.         case PERCENT:
  5235.           if (isIntConst (sendExpr->receiver)) {
  5236.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5237.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5238.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5239.               // printf ("INTEGER REMAINDER DETECTED... i = %d   j = %d\n", i, j);
  5240.               // Check for overflow...
  5241.               if (j == 0) {
  5242.                 error (node, "During the compile-time evaluation of this integer remainder operation, the divisor was found to be zero");
  5243.               }
  5244.               if (i == 0x80000000 && j == -1) {
  5245.                 error (node, "During the compile-time evaluation of this integer remainder operation, overflow occurred");
  5246.               }
  5247.               divide (i, j);
  5248.               intConst = new IntConst ();
  5249.               intConst->positionAt (node);
  5250.               intConst->ivalue = rem;
  5251.               changed = 1;
  5252.               return intConst;
  5253.             }
  5254.           }
  5255.       break;
  5256.  
  5257.         case UNARY_BANG:
  5258.           if (isBoolConst (sendExpr->receiver)) {
  5259.             i = ((BoolConst *) sendExpr->receiver)->ivalue;
  5260.             if (sendExpr->argList == NULL) {
  5261.               // printf ("UNARY NOT DETECTED... i = %d\n", i);
  5262.               if (i) {
  5263.                 boolConst = new BoolConst (0);
  5264.                 boolConst->positionAt (node);
  5265.               } else {
  5266.                 boolConst = new BoolConst (1);
  5267.                 boolConst->positionAt (node);
  5268.               }
  5269.               changed = 1;
  5270.               return boolConst;
  5271.             }
  5272.           }
  5273.           if (isIntConst (sendExpr->receiver)) {
  5274.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5275.             if (sendExpr->argList == NULL) {
  5276.               // printf ("UNARY BIT-NEGATION DETECTED... i = %d\n", i);
  5277.               intConst = new IntConst ();
  5278.               intConst->positionAt (node);
  5279.               intConst->ivalue = ~i;
  5280.               changed = 1;
  5281.               return intConst;
  5282.             }
  5283.           }
  5284.       break;
  5285.  
  5286.         case BAR_BAR:
  5287.           if (isBoolConst (sendExpr->receiver)) {
  5288.             i = ((BoolConst *) sendExpr->receiver)->ivalue;
  5289.             if (sendExpr->argList && isBoolConst (sendExpr->argList->expr)) {
  5290.               j = ((BoolConst *) sendExpr->argList->expr)->ivalue;
  5291.               // printf ("LOGICAL-OR DETECTED... i = %d   j = %d\n", i, j);
  5292.               if (i || j) {
  5293.                 boolConst = new BoolConst (1);
  5294.                 boolConst->positionAt (node);
  5295.               } else {
  5296.                 boolConst = new BoolConst (0);
  5297.                 boolConst->positionAt (node);
  5298.               }
  5299.               changed = 1;
  5300.               return boolConst;
  5301.             }
  5302.           }
  5303.       break;
  5304.  
  5305.         case AMP_AMP:
  5306.           if (isBoolConst (sendExpr->receiver)) {
  5307.             i = ((BoolConst *) sendExpr->receiver)->ivalue;
  5308.             if (sendExpr->argList && isBoolConst (sendExpr->argList->expr)) {
  5309.               j = ((BoolConst *) sendExpr->argList->expr)->ivalue;
  5310.               // printf ("LOGICAL-AND DETECTED... i = %d   j = %d\n", i, j);
  5311.               if (i && j) {
  5312.                 boolConst = new BoolConst (1);
  5313.                 boolConst->positionAt (node);
  5314.               } else {
  5315.                 boolConst = new BoolConst (0);
  5316.                 boolConst->positionAt (node);
  5317.               }
  5318.               changed = 1;
  5319.               return boolConst;
  5320.             }
  5321.           }
  5322.       break;
  5323.  
  5324.         case EQUAL_EQUAL:
  5325.           if (isBoolConst (sendExpr->receiver)) {
  5326.             i = ((BoolConst *) sendExpr->receiver)->ivalue;
  5327.             if (sendExpr->argList && isBoolConst (sendExpr->argList->expr)) {
  5328.               j = ((BoolConst *) sendExpr->argList->expr)->ivalue;
  5329.               // printf ("LOGICAL-EQUAL DETECTED... i = %d   j = %d\n", i, j);
  5330.               if (i == j) {
  5331.                 boolConst = new BoolConst (1);
  5332.                 boolConst->positionAt (node);
  5333.               } else {
  5334.                 boolConst = new BoolConst (0);
  5335.                 boolConst->positionAt (node);
  5336.               }
  5337.               changed = 1;
  5338.               return boolConst;
  5339.             }
  5340.           }
  5341.           if (isIntConst (sendExpr->receiver)) {
  5342.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5343.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5344.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5345.               // printf ("INTEGER-EQUAL DETECTED... i = %d   j = %d\n", i, j);
  5346.               if (i == j) {
  5347.                 boolConst = new BoolConst (1);
  5348.                 boolConst->positionAt (node);
  5349.               } else {
  5350.                 boolConst = new BoolConst (0);
  5351.                 boolConst->positionAt (node);
  5352.               }
  5353.               changed = 1;
  5354.               return boolConst;
  5355.             }
  5356.           }
  5357.           if (isIntConst (sendExpr->receiver)) {
  5358.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5359.             if (sendExpr->argList && i==0) {
  5360.               changed = 1;
  5361.               return insertIntIsZero (sendExpr->argList->expr);
  5362.             }
  5363.           }
  5364.           if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5365.             i = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5366.             if (i==0) {
  5367.               changed = 1;
  5368.               return insertIntIsZero (sendExpr->receiver);
  5369.             }
  5370.           }
  5371.       break;
  5372.  
  5373.         case NOT_EQUAL:
  5374.           if (isBoolConst (sendExpr->receiver)) {
  5375.             i = ((BoolConst *) sendExpr->receiver)->ivalue;
  5376.             if (sendExpr->argList && isBoolConst (sendExpr->argList->expr)) {
  5377.               j = ((BoolConst *) sendExpr->argList->expr)->ivalue;
  5378.               // printf ("LOGICAL-NOT-EQUAL DETECTED... i = %d   j = %d\n", i, j);
  5379.               if (i != j) {
  5380.                 boolConst = new BoolConst (1);
  5381.                 boolConst->positionAt (node);
  5382.               } else {
  5383.                  boolConst = new BoolConst (0);
  5384.                 boolConst->positionAt (node);
  5385.               }
  5386.               changed = 1;
  5387.               return boolConst;
  5388.             }
  5389.           }
  5390.           if (isIntConst (sendExpr->receiver)) {
  5391.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5392.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5393.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5394.               // printf ("INTEGER-NOT-EQUAL DETECTED... i = %d   j = %d\n", i, j);
  5395.               if (i != j) {
  5396.                 boolConst = new BoolConst (1);
  5397.                 boolConst->positionAt (node);
  5398.               } else {
  5399.                 boolConst = new BoolConst (0);
  5400.                 boolConst->positionAt (node);
  5401.               }
  5402.               changed = 1;
  5403.               return boolConst;
  5404.             }
  5405.           }
  5406.           if (isIntConst (sendExpr->receiver)) {
  5407.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5408.             if (sendExpr->argList && i==0) {
  5409.               changed = 1;
  5410.               return insertIntNotZero (sendExpr->argList->expr);
  5411.             }
  5412.           }
  5413.           if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5414.             i = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5415.             if (i==0) {
  5416.               changed = 1;
  5417.               return insertIntNotZero (sendExpr->receiver);
  5418.             }
  5419.           }
  5420.       break;
  5421.  
  5422.         case BAR:
  5423.           if (isIntConst (sendExpr->receiver)) {
  5424.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5425.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5426.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5427.               // printf ("INTEGER-BIT-OR DETECTED... i = %d   j = %d\n", i, j);
  5428.               intConst = new IntConst ();
  5429.               intConst->positionAt (node);
  5430.               intConst->ivalue = i | j;
  5431.               changed = 1;
  5432.               return intConst;
  5433.             }
  5434.           }
  5435.       break;
  5436.  
  5437.         case AMP:
  5438.           if (isIntConst (sendExpr->receiver)) {
  5439.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5440.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5441.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5442.               // printf ("INTEGER-BIT-AND DETECTED... i = %d   j = %d\n", i, j);
  5443.               intConst = new IntConst ();
  5444.               intConst->positionAt (node);
  5445.               intConst->ivalue = i & j;
  5446.               changed = 1;
  5447.               return intConst;
  5448.             }
  5449.           }
  5450.       break;
  5451.  
  5452.         case CARET:
  5453.           if (isIntConst (sendExpr->receiver)) {
  5454.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5455.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5456.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5457.               // printf ("INTEGER-BIT-XOR DETECTED... i = %d   j = %d\n", i, j);
  5458.               intConst = new IntConst ();
  5459.               intConst->positionAt (node);
  5460.               intConst->ivalue = i ^ j;
  5461.               changed = 1;
  5462.               return intConst;
  5463.             }
  5464.           }
  5465.       break;
  5466.  
  5467.         case LESS:
  5468.           if (isIntConst (sendExpr->receiver)) {
  5469.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5470.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5471.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5472.               if (i < j) {
  5473.                 boolConst = new BoolConst (1);
  5474.                 boolConst->positionAt (node);
  5475.               } else {
  5476.                 boolConst = new BoolConst (0);
  5477.                 boolConst->positionAt (node);
  5478.               }
  5479.               changed = 1;
  5480.               return boolConst;
  5481.             }
  5482.           }
  5483.       break;
  5484.  
  5485.         case LESS_EQUAL:
  5486.           if (isIntConst (sendExpr->receiver)) {
  5487.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5488.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5489.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5490.               if (i <= j) {
  5491.                 boolConst = new BoolConst (1);
  5492.                 boolConst->positionAt (node);
  5493.               } else {
  5494.                 boolConst = new BoolConst (0);
  5495.                 boolConst->positionAt (node);
  5496.               }
  5497.               changed = 1;
  5498.               return boolConst;
  5499.             }
  5500.           }
  5501.       break;
  5502.  
  5503.         case GREATER:
  5504.           if (isIntConst (sendExpr->receiver)) {
  5505.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5506.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5507.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5508.               if (i > j) {
  5509.                 boolConst = new BoolConst (1);
  5510.                 boolConst->positionAt (node);
  5511.               } else {
  5512.                 boolConst = new BoolConst (0);
  5513.                 boolConst->positionAt (node);
  5514.               }
  5515.               changed = 1;
  5516.               return boolConst;
  5517.             }
  5518.           }
  5519.       break;
  5520.  
  5521.         case GREATER_EQUAL:
  5522.           if (isIntConst (sendExpr->receiver)) {
  5523.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5524.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5525.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5526.               if (i >= j) {
  5527.                 boolConst = new BoolConst (1);
  5528.                 boolConst->positionAt (node);
  5529.               } else {
  5530.                 boolConst = new BoolConst (0);
  5531.                 boolConst->positionAt (node);
  5532.               }
  5533.               changed = 1;
  5534.               return boolConst;
  5535.             }
  5536.           }
  5537.       break;
  5538.  
  5539.         case LESS_LESS:
  5540.           if (isIntConst (sendExpr->receiver)) {
  5541.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5542.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5543.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5544.               if (j>31 || j<0) {
  5545.                 error (node, "During the compile-time evaluation of shift-left-logical, the shift amount was not between 0 and 31");
  5546.               }
  5547.               intConst = new IntConst ();
  5548.               intConst->positionAt (node);
  5549.               intConst->ivalue = i << j;
  5550.               changed = 1;
  5551.               return intConst;
  5552.             }
  5553.           }
  5554.       break;
  5555.  
  5556.         case GREATER_GREATER:
  5557.           if (isIntConst (sendExpr->receiver)) {
  5558.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5559.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5560.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5561.               if (j>31 || j<0) {
  5562.                 error (node, "During the compile-time evaluation of shift-right-arithmetic, the shift amount was not between 0 and 31");
  5563.               }
  5564.               intConst = new IntConst ();
  5565.               intConst->positionAt (node);
  5566.               intConst->ivalue = i >> j;
  5567.               changed = 1;
  5568.               return intConst;
  5569.             }
  5570.           }
  5571.       break;
  5572.  
  5573.         case GREATER_GREATER_GREATER:
  5574.           if (isIntConst (sendExpr->receiver)) {
  5575.             i = ((IntConst *) sendExpr->receiver)->ivalue;
  5576.             if (sendExpr->argList && isIntConst (sendExpr->argList->expr)) {
  5577.               j = ((IntConst *) sendExpr->argList->expr)->ivalue;
  5578.               if (j>31 || j<0) {
  5579.                 error (node, "During the compile-time evaluation of shift-right-logical, the shift amount was not between 0 and 31");
  5580.               }
  5581.               intConst = new IntConst ();
  5582.               intConst->positionAt (node);
  5583.               intConst->ivalue = (signed int) (((unsigned int) i) >> j);
  5584.               changed = 1;
  5585.               return intConst;
  5586.             }
  5587.           }
  5588.       break;
  5589.  
  5590.       }
  5591.       return node;
  5592.  
  5593.     case SELF_EXPR:
  5594.       selfExpr = (SelfExpr *) node;
  5595.       return node;
  5596.  
  5597.     case SUPER_EXPR:
  5598.       superExpr = (SuperExpr *) node;
  5599.       return node;
  5600.  
  5601.     case FIELD_ACCESS:
  5602.       fieldAccess = (FieldAccess *) node;
  5603.       fieldAccess->expr = (Expression *) evalExprsIn (fieldAccess->expr);
  5604.       return node;
  5605.  
  5606.     case ARRAY_ACCESS:
  5607.       arrayAccess = (ArrayAccess *) node;
  5608.       arrayAccess->arrayExpr = (Expression *) evalExprsIn (arrayAccess->arrayExpr);
  5609.       arrayAccess->indexExpr = (Expression *) evalExprsIn (arrayAccess->indexExpr);
  5610.       return node;
  5611.  
  5612.     case CONSTRUCTOR:
  5613.       constructor = (Constructor *) node;
  5614.       x = evalExprsIn (constructor->type);
  5615.       x = evalExprsIn (constructor->countValueList);
  5616.       x = evalExprsIn (constructor->fieldInits);
  5617.       return node;
  5618.  
  5619.     case CLOSURE_EXPR:
  5620.       closureExpr = (ClosureExpr *) node;
  5621.       // Skip this, since we'll x = evalExprsIn the function when we do header->closures...
  5622.       // x = evalExprsIn (closureExpr->function);
  5623.       return node;
  5624.  
  5625.     case VARIABLE_EXPR:
  5626.       var = (VariableExpr *) node;
  5627.       // If this variable names a constant, and that constant has a definition
  5628.       // which is a single value, then return that value...
  5629.       if (var->myDef) {
  5630.         constDecl = (ConstDecl *) var->myDef;
  5631.         if ((constDecl->op == CONST_DECL) && (constDecl->expr->op)) {
  5632.           if ((constDecl->expr->op == CHAR_CONST) ||
  5633.               (constDecl->expr->op == INT_CONST) ||
  5634.               (constDecl->expr->op == DOUBLE_CONST) ||
  5635.               (constDecl->expr->op == BOOL_CONST) ||
  5636.               (constDecl->expr->op == NULL_CONST) ||
  5637.               (constDecl->expr->op == STRING_CONST)) {
  5638.             changed = 1;
  5639.             return constDecl->expr;
  5640.           }
  5641.         }
  5642.       }
  5643.       return node;
  5644.  
  5645.     case AS_PTR_TO_EXPR:
  5646.       asPtrToExpr = (AsPtrToExpr *) node;
  5647.       asPtrToExpr->expr = (Expression *) evalExprsIn (asPtrToExpr->expr);
  5648.       x = evalExprsIn (asPtrToExpr->type);
  5649.       return node;
  5650.  
  5651.     case AS_INTEGER_EXPR:
  5652.       asIntegerExpr = (AsIntegerExpr *) node;
  5653.       asIntegerExpr->expr = (Expression *) evalExprsIn (asIntegerExpr->expr);
  5654.       return node;
  5655.  
  5656.     case ARRAY_SIZE_EXPR:
  5657.       arraySizeExpr = (ArraySizeExpr *) node;
  5658.       arraySizeExpr->expr = (Expression *) evalExprsIn (arraySizeExpr->expr);
  5659.       return node;
  5660.  
  5661.     case IS_INSTANCE_OF_EXPR:
  5662.       isInstanceOfExpr = (IsInstanceOfExpr *) node;
  5663.       isInstanceOfExpr->expr = (Expression *) evalExprsIn (isInstanceOfExpr->expr);
  5664.       x = evalExprsIn (isInstanceOfExpr->type);
  5665.       return node;
  5666.  
  5667.     case IS_KIND_OF_EXPR:
  5668.       isKindOfExpr = (IsKindOfExpr *) node;
  5669.       isKindOfExpr->expr = (Expression *) evalExprsIn (isKindOfExpr->expr);
  5670.       x = evalExprsIn (isKindOfExpr->type);
  5671.       return node;
  5672.  
  5673.     case SIZE_OF_EXPR:
  5674.       sizeOfExpr = (SizeOfExpr *) node;
  5675.       x = evalExprsIn (sizeOfExpr->type);
  5676.       i = sizeInBytesOfWhole (sizeOfExpr->type, node, 0);   // Want printing = 0
  5677.       // (If we have a problem, we'll print the error in checkTypes.)
  5678.       if (i >= 0) {
  5679.         intConst = new IntConst ();
  5680.         intConst->positionAt (node);
  5681.         intConst->ivalue = i;
  5682.         changed = 1;
  5683.         return intConst;
  5684.       }
  5685.       return node;
  5686.  
  5687.     case DYNAMIC_CHECK:
  5688.       dynamicCheck = (DynamicCheck *) node;
  5689.       x = evalExprsIn (dynamicCheck->expr);
  5690.       return node;
  5691.  
  5692.     case ARGUMENT:
  5693.       arg = (Argument *) node;
  5694.       arg->expr = (Expression *) evalExprsIn (arg->expr);
  5695.       x = evalExprsIn (arg->next);
  5696.       return node;
  5697.  
  5698.     case COUNT_VALUE:
  5699.       countValue = (CountValue *) node;
  5700.       countValue->count = (Expression *) evalExprsIn (countValue->count);
  5701.       countValue->value = (Expression *) evalExprsIn (countValue->value);
  5702.       x = evalExprsIn (countValue->next);
  5703.       return node;
  5704.  
  5705.     case FIELD_INIT:
  5706.       fieldInit = (FieldInit *) node;
  5707.       fieldInit->expr = (Expression *) evalExprsIn (fieldInit->expr);
  5708.       x = evalExprsIn (fieldInit->next);
  5709.       return node;
  5710.  
  5711.     default:
  5712.       printf ("node->op = %s\n", symbolName (node->op));
  5713.       programLogicError ("Unkown op in evalExprsIn");
  5714.   }
  5715. }
  5716.  
  5717.  
  5718.  
  5719. // isIntConst (node) --> bool
  5720. //
  5721. // Returns true if we have an INT_CONST.  Return false if any problems.
  5722. //
  5723. int isIntConst (AstNode * node) {
  5724.   if (node && node->op == INT_CONST) {
  5725.     return 1;
  5726.   }
  5727.   return 0;
  5728. }
  5729.  
  5730.  
  5731.  
  5732. // isCharConst (node) --> bool
  5733. //
  5734. // Returns true if we have an CHAR_CONST.  Return false if any problems.
  5735. //
  5736. int isCharConst (AstNode * node) {
  5737.   if (node && node->op == CHAR_CONST) {
  5738.     return 1;
  5739.   }
  5740.   return 0;
  5741. }
  5742.  
  5743.  
  5744.  
  5745. // isBoolConst (node) --> bool
  5746. //
  5747. // Returns true if we have an BOOL_CONST.  Return false if any problems.
  5748. //
  5749. int isBoolConst (AstNode * node) {
  5750.   if (node && node->op == BOOL_CONST) {
  5751.     return 1;
  5752.   }
  5753.   return 0;
  5754. }
  5755.  
  5756.  
  5757.  
  5758. // isDoubleConst (node) --> bool
  5759. //
  5760. // Returns true if we have an DOUBLE_CONST.  Return false if any problems.
  5761. //
  5762. int isDoubleConst (AstNode * node) {
  5763.   if (node && node->op == DOUBLE_CONST) {
  5764.     return 1;
  5765.   }
  5766.   return 0;
  5767. }
  5768.  
  5769.  
  5770.  
  5771. // testSubType (hdr)
  5772. //
  5773. // This routine is used to test...
  5774. //         "isSubType"
  5775. //         "typesEqual"
  5776. //         "assignable"
  5777. //
  5778. // This routine expects there to be a class named "C" with two fields named "x" and
  5779. // "y".  It tests whether the type of "x" is a subtype/equal/assignable to
  5780. // the type of "y".
  5781. //
  5782. // It builds a mapping, and applies that to the types.  This mapping comes
  5783. // from parts of the source.  For example:
  5784. //      class C [T1: ..., T2: ...]
  5785. //        superclass D [int, char]
  5786. //        fields
  5787. //          x: ptr to List [T1]
  5788. //          y: ptr to List [anyType]
  5789. //
  5790. // This example builds the mapping:
  5791. //        T1 --> int
  5792. //        T2 --> char
  5793. // and then tests whether "ptr to List [T1]" is a subType of "ptr to List [anyType]"
  5794. //
  5795. void testSubType (Header * hdr) {
  5796.   ClassDef * cl;
  5797.   ClassField * fx, * fy;
  5798.   Mapping <TypeParm, Type> * map;
  5799.  
  5800.   cl = (ClassDef *) hdr->packageMapping->find (lookupAndAdd ("C", ID));
  5801.   if ((cl == NULL) || (cl->op != CLASS_DEF)) {
  5802.     programLogicError ("In 'testSubType', Expecting class 'C' to exist");
  5803.   }
  5804.   fx = (ClassField *) cl->classMapping->find (lookupAndAdd ("x", ID));
  5805.   if ((fx == NULL) || (fx->op != CLASS_FIELD)) {
  5806.     programLogicError ("In 'testSubType', Expecting field 'x' to exist");
  5807.   }
  5808.   fy = (ClassField *) cl->classMapping->find (lookupAndAdd ("y", ID));
  5809.   if ((fy == NULL) || (fy->op != CLASS_FIELD)) {
  5810.     programLogicError ("In 'testSubType', Expecting field 'y' to exist");
  5811.   }
  5812.  
  5813.   map = buildSubstitution (cl->typeParms, cl->superclass->typeArgs);
  5814.   if (map) {
  5815.     printf ("Mapping = \n");
  5816.     map->print (6);
  5817.   } else {
  5818.     printf ("Mapping = NULL\n");
  5819.   }
  5820.  
  5821.   printf ("\n=============== Testing typesEqual  ===================\n");
  5822.   printf ("\n  Type(x)..... ");
  5823.   pretty (fx->type);
  5824.   printf ("\n  Type(y)..... ");
  5825.   pretty (fy->type);
  5826.   printf ("\n");
  5827.   printf ("========================================================\n");
  5828.   if (typesEqual (fx->type, fy->type)) {
  5829.     printf ("\n  Type(x) EQUAL Type(y) \n\n");
  5830.   } else {
  5831.     printf ("\n  Type(x) NOT EQUAL Type(y) \n\n");
  5832.   }
  5833.  
  5834.   printf ("=============== Testing isSubType  ===================\n");
  5835.   printf ("\n  Type(x)..... ");
  5836.   pretty (fx->type);
  5837.   printf ("\n  Type(y)..... ");
  5838.   pretty (fy->type);
  5839.   printf ("\n");
  5840.   printf ("========================================================\n");
  5841.   if (isSubType (fx->type, fy->type)) {
  5842.     printf ("\n  Type(x) SUBTYPE Type(y) \n\n");
  5843.   } else {
  5844.     printf ("\n  Type(x) NOT SUBTYPE Type(y) \n\n");
  5845.   }
  5846.  
  5847.   printf ("=============== Testing assignable  ===================\n");
  5848.   printf ("\n  Type(x)..... ");
  5849.   pretty (fx->type);
  5850.   printf ("\n  Type(y)..... ");
  5851.   pretty (fy->type);
  5852.   printf ("\n");
  5853.   printf ("========================================================\n");
  5854.   if (assignable (fx->type, fy->type)) {
  5855.     printf ("\n  Type(x) ASSIGNABLE <- Type(y) \n\n");
  5856.   } else {
  5857.     printf ("\n  Type(x) NOT ASSIGNABLE Type(y) \n\n");
  5858.   }
  5859.  
  5860. }
  5861.  
  5862.  
  5863.  
  5864. // typesEqual (t1, t2) --> bool
  5865. //
  5866. // This routine is passed two Types.  It returns true if type t1 is
  5867. // equal to type t2.
  5868. //
  5869. // If problems are encountered, we just return true.
  5870. //
  5871. // A type may be recursively defined.  For example:
  5872. //    type REC1 = record
  5873. //                  next: ptr to REC1
  5874. //                endRecord
  5875. // In general this is OK.  But occassionally it causes problems.  For example,
  5876. // if we try to compare REC1 with a similar type, REC2, we get into a recursion
  5877. // problem.
  5878. //    type REC2 = record
  5879. //                  next: ptr to REC2
  5880. //                endRecord
  5881. // These two types are equal iff the types of each of their fields are equal.  So
  5882. // we must compare "ptr to REC1" to "ptr to REC2".  These equal iff the two base types
  5883. // are equal, so we compare "REC1" to "REC2", getting into an infinite loop.
  5884. //
  5885. // For this reason, we use a "recursionCounter" to detect when we *may* be in an
  5886. // infinite recursion, comparing two cyclic data structures.
  5887. //
  5888. int typesEqual (Type * t1, Type * t2) {
  5889.   TypeArg * typeArg1, * typeArg2;
  5890.   TypeDef * typeDef;
  5891.   NamedType * namedType1, * namedType2;
  5892.   ClassDef * classDef1;
  5893.   Interface * interface1;
  5894.   RecordType * rec1, * rec2;
  5895.   RecordField * rf1, *rf2;
  5896.   FunctionType * fType1, * fType2;
  5897.   TypeParm * typeParm, * typeParm2;
  5898.   int equal;
  5899.   IntConst * intCon1, * intCon2;
  5900.  
  5901.   // printf ("                       -----   typesEqual t1 = ");
  5902.   // pretty (t1);
  5903.   // printf ("                       -----              t2 = ");
  5904.   // pretty (t2);
  5905.  
  5906.   // printf ("-----  Testing typesEqual...\n");
  5907.   // printf ("-----    t1 = ");
  5908.   // pretty (t1);
  5909.   // printf ("-----    t2 = ");
  5910.   // pretty (t2);
  5911.  
  5912.   // Quick check...
  5913.   if (t1 == t2) return 1;
  5914.  
  5915.   // If for any reason, we've had earlier problems, just return immediately...
  5916.   if (t1 == NULL || t2 == NULL) return 1;
  5917.  
  5918.   // If either of the types is a type-def, then use that...
  5919.   if (t1->op == NAMED_TYPE) {
  5920.     typeDef = (TypeDef *) (((NamedType *) t1)->myDef);
  5921.     if (typeDef) {
  5922.       if (typeDef->op == TYPE_DEF) {
  5923.         return typesEqual (typeDef->type, t2);
  5924.       }
  5925.     } else {
  5926.       return 1;
  5927.     }
  5928.   }
  5929.   if (t2->op == NAMED_TYPE) {
  5930.     typeDef = (TypeDef *) (((NamedType *) t2)->myDef);
  5931.     if (typeDef) {
  5932.       if (typeDef->op == TYPE_DEF) {
  5933.         return typesEqual (t1, typeDef->type);
  5934.       }
  5935.     } else {
  5936.       return 1;
  5937.     }
  5938.   }
  5939.  
  5940.   switch (t1->op) {
  5941.  
  5942.     case ANY_TYPE:                            // in typesEqual
  5943.        return (t2->op == ANY_TYPE);
  5944.  
  5945.     case CHAR_TYPE:                           // in typesEqual
  5946.       return (t2->op == CHAR_TYPE);
  5947.  
  5948.     case INT_TYPE:                            // in typesEqual
  5949.       return (t2->op == INT_TYPE);
  5950.  
  5951.     case DOUBLE_TYPE:                         // in typesEqual
  5952.       return (t2->op == DOUBLE_TYPE);
  5953.  
  5954.     case BOOL_TYPE:                           // in typesEqual
  5955.       return (t2->op == BOOL_TYPE);
  5956.  
  5957.     case VOID_TYPE:                           // in typesEqual
  5958.       return (t2->op == VOID_TYPE);
  5959.  
  5960.     case TYPE_OF_NULL_TYPE:                   // in typesEqual
  5961.       return (t2->op == TYPE_OF_NULL_TYPE);
  5962.  
  5963.     case PTR_TYPE:                            // in typesEqual
  5964.       if (t2->op != PTR_TYPE) return 0;
  5965.       if (((PtrType *) t1)->baseType &&
  5966.           ((PtrType *) t1)->baseType->op == VOID_TYPE) return 1;
  5967.       if (((PtrType *) t2)->baseType &&
  5968.           ((PtrType *) t2)->baseType->op == VOID_TYPE) return 1;
  5969.       if (recursionCounter++ > 100) {
  5970.         error (t1, "This type appears to be recursively defined");
  5971.         error2 (t2, "This type appears to be recursively defined");
  5972.         recursionCounter--;
  5973.         return 1;
  5974.       }
  5975.       equal = typesEqual (((PtrType *) t1)->baseType,
  5976.                            ((PtrType *) t2)->baseType);
  5977.       recursionCounter--;
  5978.       return equal;
  5979.  
  5980.     case FUNCTION_TYPE:                       // in typesEqual
  5981.       if (t2->op != FUNCTION_TYPE) return 0;
  5982.       fType1 = (FunctionType *) t1;
  5983.       fType2 = (FunctionType *) t2;
  5984.       typeArg1 = fType1->parmTypes;
  5985.       typeArg2 = fType2-> parmTypes;
  5986.       while (1) {
  5987.         if ((typeArg1 == NULL) && (typeArg2 == NULL)) break;
  5988.         if ((typeArg1 == NULL) || (typeArg2 == NULL)) return 0;
  5989.         if (recursionCounter++ > 100) {
  5990.           error (t1, "This type appears to be recursively defined");
  5991.           error2 (t2, "This type appears to be recursively defined");
  5992.           recursionCounter--;
  5993.           return 1;
  5994.         }
  5995.         equal = typesEqual (typeArg2->type, typeArg1->type);
  5996.         recursionCounter--;
  5997.         if (!equal) return 0;
  5998.         typeArg1 = typeArg1->next;
  5999.         typeArg2 = typeArg2->next;
  6000.       }
  6001.       if (fType1->retType == NULL) {
  6002.         return fType2->retType == NULL;
  6003.       } else if (fType2->retType == NULL) {
  6004.         return 0;
  6005.       }
  6006.       if (recursionCounter++ > 100) {
  6007.         error (t1, "This type appears to be recursively defined  (24)");
  6008.         error2 (t2, "This type appears to be recursively defined");
  6009.         recursionCounter--;
  6010.         return 1;
  6011.       }
  6012.       equal = typesEqual (fType1->retType,
  6013.                           fType2->retType);
  6014.       recursionCounter--;
  6015.       return equal;
  6016.  
  6017.     case ARRAY_TYPE:                          // in typesEqual
  6018.       if (t2->op != ARRAY_TYPE) return 0;
  6019.       if (recursionCounter++ > 100) {
  6020.         error (t1, "This type appears to be recursively defined");
  6021.         error2 (t2, "This type appears to be recursively defined");
  6022.         recursionCounter--;
  6023.         return 1;
  6024.       }
  6025.       // printf ("t1->sizeExpr = ");  pretty (((ArrayType *) t1)->sizeExpr);
  6026.       // printf ("t2->sizeExpr = ");  pretty (((ArrayType *) t2)->sizeExpr);
  6027.       equal = typesEqual (((ArrayType *) t1)->baseType,
  6028.                           ((ArrayType *) t2)->baseType);
  6029.       recursionCounter--;
  6030.       if (!equal) return 0;
  6031.       // Next, take a look at the size expressions...
  6032.       intCon1 = (IntConst *) ((ArrayType *) t1)->sizeExpr;
  6033.       intCon2 = (IntConst *) ((ArrayType *) t2)->sizeExpr;
  6034.       // Either (1) both must be dynamic or (2) neither are dynamic...
  6035.       if ((intCon1 == NULL) && (intCon2 == NULL)) return 1;
  6036.       if ((intCon1 == NULL) || (intCon2 == NULL)) return 0;
  6037.       // We have run evalExprs already, so we *hope* that all expressions
  6038.       // have been evaluated.  However, there may be perfectly reasonable
  6039.       // size expressions (e.g., involving constants) which have not been
  6040.       // computed at the time "typesEqual" is used.
  6041.       if (intCon1->op != INT_CONST) {
  6042.         error (intCon1, "The size of the array cannot be determined at this time");
  6043.         errorWithType ("when comparing for equality, this type", t1);
  6044.         errorWithType ("and this type", t2);
  6045.         return 1;
  6046.       }
  6047.       if (intCon2->op != INT_CONST) {
  6048.         error (intCon2, "The size of the array cannot be determined at this time");
  6049.         errorWithType ("when comparing for equality, this type", t1);
  6050.         errorWithType ("and this type", t2);
  6051.         return 1;
  6052.       }
  6053.       return intCon1->ivalue == intCon2->ivalue;
  6054.  
  6055.     case RECORD_TYPE:                         // in typesEqual
  6056.       if (t2->op != RECORD_TYPE) return 0;
  6057.       // To be a subtype, the records must match exactly...
  6058.       rec1 = (RecordType *) t1;
  6059.       rec2 = (RecordType *) t2;
  6060.       rf1 = rec1->fields;
  6061.       rf2 = rec2->fields;
  6062.       while (1) {
  6063.         if ((rf1 == NULL) && (rf2 == NULL)) return 1;
  6064.         if ((rf1 == NULL) || (rf2 == NULL)) return 0;
  6065.         if (rf1->id != rf2->id) return 0;
  6066.         if (recursionCounter++ > 100) {
  6067.           error (t1, "This type appears to be recursively defined");
  6068.           error2 (t2, "This type appears to be recursively defined");
  6069.           recursionCounter--;
  6070.           return 1;
  6071.         }
  6072.         equal = typesEqual (rf1->type, rf2->type);
  6073.         recursionCounter--;
  6074.         if (!equal) return 0;
  6075.         rf1 = (RecordField *) rf1->next;
  6076.         rf2 = (RecordField *) rf2->next;
  6077.       }
  6078.       return 1;
  6079.  
  6080.     case NAMED_TYPE:                          // in typesEqual
  6081.       if (t2->op != NAMED_TYPE) return 0;
  6082.       namedType1 = (NamedType *) t1;
  6083.       namedType2 = (NamedType *) t2;
  6084.       // Wouldn't it be better to compare their "myDef" fields, to make sure
  6085.       // the ID's refer to the same class/interface/typeParm...?
  6086.       if (namedType1->id == namedType2->id) {
  6087.         // We have something like "List[int, int]" and "List [char]" (or "T" and "T")...
  6088.         typeArg1 = namedType1->typeArgs;
  6089.         typeArg2 = namedType2->typeArgs;
  6090.         while (1) {
  6091.           // We'll check that we have correct # of args later...
  6092.           if (typeArg1 == NULL) return 1;
  6093.           if (typeArg2 == NULL) return 1;
  6094.           // Check that each arg is equal...
  6095.           if (recursionCounter++ > 100) {
  6096.             error (t1, "This type appears to be recursively defined");
  6097.             error2 (t2, "This type appears to be recursively defined");
  6098.             recursionCounter--;
  6099.             return 1;
  6100.           }
  6101.           equal = typesEqual (typeArg2->type, typeArg1->type);
  6102.           recursionCounter--;
  6103.           if (!equal) return 0;
  6104.           typeArg1 = typeArg1->next;
  6105.           typeArg2 = typeArg2->next;
  6106.         }
  6107.         return 1;
  6108.       } else {
  6109.         // Two classes or interfaces can only be equal to themselves; if this had
  6110.         // been the case, they would have had NamedTypes with id==id.
  6111.         return 0;
  6112.       }
  6113.  
  6114.     default:                                  // in typesEqual
  6115.       printf ("t1->op = %s\n", symbolName (t1->op));
  6116.       printf ("t2->op = %s\n", symbolName (t2->op));
  6117.       programLogicError ("Unknown op in typesEqual");
  6118.   }
  6119.  
  6120. }
  6121.  
  6122.  
  6123.  
  6124. // isSubType (t1, t2) --> bool
  6125. //
  6126. // This routine is passed two Types.  It returns true if type t1 is
  6127. // a subtype of type t2.
  6128. //
  6129. // A type may be recursively defined.  For example:
  6130. //    type REC1 = record
  6131. //                  next: ptr to REC1
  6132. //                endRecord
  6133. //
  6134. // In general this is OK.  But occassionally it causes problems.  For example,
  6135. // if we try to compare REC1 with a similar type, REC2, we get into a recursion
  6136. // problem.
  6137. //    type REC2 = record
  6138. //                  next: ptr to REC2
  6139. //                endRecord
  6140. // These two types are equal iff the types of each of their fields are equal.  So
  6141. // we must compare "ptr to REC1" to "ptr to REC2".  These are equal iff the two base
  6142. // type are equal, so we compare "REC1" to "REC2", getting into an infinite loop.
  6143. //
  6144. // For this reason, we use a "recursionCounter" to detect when we *may* be in an
  6145. // infinite recursion, comparing two cyclic data structures.
  6146. //
  6147. // If problems, this routine returns true, hoping to supress further error messages.
  6148. //
  6149. int isSubType (Type * t1, Type * t2) {
  6150.   TypeArg * typeArg1, * typeArg2;
  6151.   TypeDef * typeDef;
  6152.   NamedType * namedType1, * namedType2;
  6153.   ClassDef * classDef1;
  6154.   Interface * interface1;
  6155.   RecordType * rec1, * rec2;
  6156.   RecordField * rf1, *rf2;
  6157.   FunctionType * fType1, * fType2;
  6158.   TypeParm * typeParm, * typeParm2;
  6159.   AstNode * def1, * def2;
  6160.   Mapping<TypeParm,Type> * subst;
  6161.   int sub;
  6162.  
  6163.   // printf ("-----  Testing isSubType...\n");
  6164.   // printf ("-----    t1 = ");
  6165.   // pretty (t1);
  6166.   // printf ("-----    t2 = ");
  6167.   // pretty (t2);
  6168.  
  6169. //  // Perform the substitutions, if they are present...
  6170. //  if (subst1 != NULL) {
  6171. //    t1 = copyTypeWithSubst (t1, subst1);
  6172. //    // printf ("-----      new t1 = ");
  6173. //    // pretty (t1);
  6174. //  }
  6175. //  if (subst2 != NULL) {
  6176. //    t2 = copyTypeWithSubst (t2, subst2);
  6177. //    // printf ("-----      new t2 = ");
  6178. //    // pretty (t2);
  6179. //  }
  6180.  
  6181.   if (t1 == t2) return 1;
  6182.  
  6183.   // If for any reason, we've had earlier problems, just return immediately...
  6184.   if (t1 == NULL || t2 == NULL) return 1;
  6185.  
  6186.   // If either of the types is a type-def, then use that...
  6187.   if (t1->op == NAMED_TYPE) {
  6188.     typeDef = (TypeDef *) (((NamedType *) t1)->myDef);
  6189.     if (typeDef) {
  6190.       if (typeDef->op == TYPE_DEF) {
  6191.         return isSubType (typeDef->type, t2);
  6192.       }
  6193.     } else {
  6194.       return 1;
  6195.     }
  6196.   }
  6197.   if (t2->op == NAMED_TYPE) {
  6198.     typeDef = (TypeDef *) (((NamedType *) t2)->myDef);
  6199.     if (typeDef) {
  6200.       if (typeDef->op == TYPE_DEF) {
  6201.         return isSubType (t1, typeDef->type);
  6202.       }
  6203.     } else {
  6204.       return 1;
  6205.     }
  6206.   }
  6207.  
  6208.   if (t1 == t2) return 1;
  6209.  
  6210.   if (t2->op == ANY_TYPE) return 1;
  6211.  
  6212.   switch (t1->op) {
  6213.  
  6214.     case ANY_TYPE:                                  // in isSubType
  6215.       return 0;
  6216.  
  6217.     case CHAR_TYPE:                                 // in isSubType
  6218.       return (t2->op == CHAR_TYPE);
  6219.  
  6220.     case INT_TYPE:                                  // in isSubType
  6221.       return (t2->op == INT_TYPE);
  6222.  
  6223.     case DOUBLE_TYPE:                               // in isSubType
  6224.       return (t2->op == DOUBLE_TYPE);
  6225.  
  6226.     case BOOL_TYPE:                                 // in isSubType
  6227.       return (t2->op == BOOL_TYPE);
  6228.  
  6229.     case VOID_TYPE:                                 // in isSubType
  6230.       return (t2->op == VOID_TYPE);
  6231.  
  6232.     case TYPE_OF_NULL_TYPE:                         // in isSubType
  6233.       return ((t2->op == PTR_TYPE) || (t2->op == TYPE_OF_NULL_TYPE));
  6234.  
  6235.     case PTR_TYPE:                                  // in isSubType
  6236.       if (t2->op != PTR_TYPE) return 0;
  6237.       if (!safe && isVoidType (((PtrType *) t1)->baseType)) return 1;
  6238.       if (!safe && isVoidType (((PtrType *) t2)->baseType)) return 1;
  6239.       if (recursionCounter++ > 100) {
  6240.         error (t1, "This type appears to be recursively defined");
  6241.         error2 (t2, "This type appears to be recursively defined");
  6242.         recursionCounter--;
  6243.         return 1;
  6244.       }
  6245.       sub = isSubType (((PtrType *) t1)->baseType,
  6246.                           ((PtrType *) t2)->baseType);
  6247.       recursionCounter--;
  6248.       return sub;
  6249.  
  6250.     case RECORD_TYPE:                               // in isSubType
  6251.       if (t2->op != RECORD_TYPE) return 0;
  6252.       // To be a subtype, the records must match exactly...
  6253.       rec1 = (RecordType *) t1;
  6254.       rec2 = (RecordType *) t2;
  6255.       rf1 = rec1->fields;
  6256.       rf2 = rec2->fields;
  6257.       while (1) {
  6258.         if ((rf1 == NULL) && (rf2 == NULL)) return 1;
  6259.         if ((rf1 == NULL) || (rf2 == NULL)) return 0;
  6260.         if (rf1->id != rf2->id) return 0;
  6261.         if (!typesEqual (rf1->type, rf2->type)) return 0;
  6262.         rf1 = (RecordField *) rf1->next;
  6263.         rf2 = (RecordField *) rf2->next;
  6264.       }
  6265.       return 1;
  6266.  
  6267.     case ARRAY_TYPE:                                // in isSubType
  6268.       if (t2->op != ARRAY_TYPE) return 0;
  6269.       if (recursionCounter++ > 100) {
  6270.         error (t1, "This type appears to be recursively defined");
  6271.         error2 (t2, "This type appears to be recursively defined");
  6272.         recursionCounter--;
  6273.         return 1;
  6274.       }
  6275.       sub = typesEqual (((ArrayType *) t1)->baseType,
  6276.                           ((ArrayType *) t2)->baseType);
  6277.       recursionCounter--;
  6278.       return sub;
  6279.  
  6280.     case FUNCTION_TYPE:                             // in isSubType
  6281.       if (t2->op != FUNCTION_TYPE) return 0;
  6282.       fType1 = (FunctionType *) t1;
  6283.       fType2 = (FunctionType *) t2;
  6284.       typeArg1 = fType1->parmTypes;
  6285.       typeArg2 = fType2-> parmTypes;
  6286.       while (1) {
  6287.         if ((typeArg1 == NULL) && (typeArg2 == NULL)) break;
  6288.         if ((typeArg1 == NULL) || (typeArg2 == NULL)) return 1;
  6289.         if (recursionCounter++ > 100) {
  6290.           error (t1, "This type appears to be recursively defined");
  6291.           error2 (t2, "This type appears to be recursively defined");
  6292.           recursionCounter--;
  6293.           return 1;
  6294.         }
  6295.         sub = assignable (typeArg1->type, typeArg2->type);
  6296.         recursionCounter--;
  6297.         if (!sub) return 0;
  6298.         typeArg1 = typeArg1->next;
  6299.         typeArg2 = typeArg2->next;
  6300.       }
  6301.  
  6302.       // Check the return type.  If either is "void", both must be "void"...
  6303.       if (fType1->retType == NULL) {
  6304.         programLogicError ("FunctionType.retType will never be NULL (1)");
  6305.       }
  6306.       if (fType2->retType == NULL) {
  6307.         programLogicError ("FunctionType.retType will never be NULL (2)");
  6308.       }
  6309.       if (isVoidType (fType1->retType) && isVoidType (fType2->retType)) return 1;
  6310.       if (isVoidType (fType1->retType)) return 0;
  6311.       if (isVoidType (fType2->retType)) return 0;
  6312.       // Make sure the return types are assignable...
  6313.       if (recursionCounter++ > 100) {
  6314.         error (t1, "This type appears to be recursively defined");
  6315.         error2 (t2, "This type appears to be recursively defined");
  6316.         recursionCounter--;
  6317.         return 1;
  6318.       }
  6319.       sub = assignable (fType2->retType, fType1->retType);
  6320.       recursionCounter--;
  6321.       return sub;
  6322.  
  6323.     case NAMED_TYPE:                                // in isSubType
  6324.  
  6325.       // Get the definition of t1.  If it happens to be
  6326.       // undefined, it is an error, so just return true.
  6327.       namedType1 = (NamedType *) t1;
  6328.       def1 = namedType1->myDef;
  6329.       if (def1 == NULL) return 1;
  6330.  
  6331.       // If t1 is a TypeParameter, then see if t1.constraint < T.
  6332.       if (def1->op == TYPE_PARM) {
  6333.         if (recursionCounter++ > 100) {
  6334.           error (t1, "This type appears to be recursively defined");
  6335.           error2 (t2, "This type appears to be recursively defined");
  6336.           recursionCounter--;
  6337.           return 1;
  6338.         }
  6339.         sub = isSubType (((TypeParm *) def1)->type, t2);
  6340.         recursionCounter--;
  6341.         if (sub) return 1;
  6342.       }
  6343.  
  6344.       // Make sure t2 is also a NamedType...
  6345.       if (t2->op != NAMED_TYPE) return 0;
  6346.  
  6347.       // Get the definition of t2.  If it happens to be
  6348.       // undefined, it is an error, so just return true.
  6349.       namedType2 = (NamedType *) t2;
  6350.       def2 = namedType2->myDef;
  6351.       if (def2 == NULL) return 1;
  6352.  
  6353.       // printf ("SubType  t1 = ");
  6354.       // pretty (t1);
  6355.       // printf ("         t2 = ");
  6356.       // pretty (t2);
  6357.  
  6358.       // If both types refer to the same TypeParameter, return true;
  6359.       if ((def1->op == TYPE_PARM) && (def2 == def1)) return 1;
  6360.  
  6361.       // If t2 is a TypeParameter, then return false.
  6362.       if (def2->op == TYPE_PARM) return 0;
  6363.  
  6364.       // We have something like "Person < Student" or "List[int] < Set[anyType]"...
  6365.  
  6366.       // NamedTypes may be: TypeDefs, TypeParms, Interfaces, Classes, or undefined.
  6367.       // By this time, we have checked for everything except classes and interfaces,
  6368.       // so check that they both name a class or interface.
  6369.       if ((def1->op != CLASS_DEF) && (def1->op != INTERFACE)) {
  6370.         printf ("namedType1->id = %s\n", namedType1->id->chars);
  6371.         printf ("def1->op = %s\n", symbolName (def1->op));
  6372.         programLogicError ("In isSubType: This must be a CLASS_DEF or INTERFACE");
  6373.       }
  6374.       if ((def2->op != CLASS_DEF) && (def2->op != INTERFACE)) {
  6375.         printf ("namedType2->id = %s\n", namedType2->id->chars);
  6376.         printf ("def2->op = %s\n", symbolName (def2->op));
  6377.         programLogicError ("In isSubType: This must be a CLASS_DEF or INTERFACE");
  6378.       }
  6379.  
  6380.       // If the class names are the same...
  6381.       if (namedType1->id == namedType2->id) {
  6382.  
  6383.         // Make sure there are the same number  and make sure they are pairwise equal...
  6384.         typeArg1 = namedType1->typeArgs;
  6385.         typeArg2 = namedType2->typeArgs;
  6386.         while (1) {
  6387.           if ((typeArg1 == NULL) && (typeArg2 == NULL)) return 1;
  6388.           if ((typeArg1 == NULL) || (typeArg2 == NULL)) return 0;
  6389.           if (!typesEqual (typeArg1->type, typeArg2->type)) return 0;
  6390.           typeArg1 = typeArg1->next;
  6391.           typeArg2 = typeArg2->next;
  6392.         }
  6393.         programLogicError ("The above infinite loop terminates with returns");
  6394.  
  6395.       } else {      // Else, the two IDs are different...
  6396.  
  6397.         // If t1 is a CLASS...
  6398.         if (namedType1->myDef->op == CLASS_DEF) {
  6399.  
  6400.           // printf ("Within class ");  pretty (namedType1);
  6401.           classDef1 = (ClassDef *) (namedType1->myDef);
  6402.  
  6403.           // We've got "List[int]" and "Collection[...]"; Assume that the class
  6404.           // looks like this "List [T:...]".  Build a subst "T->int".
  6405.           subst = buildSubstitution (classDef1->typeParms, namedType1->typeArgs);
  6406.  
  6407.           // If t1 has a superclass, then try going up that chain...
  6408.           if (classDef1->superclass) {
  6409.             // printf ("subst = \n");
  6410.             // if (subst == NULL) {
  6411.             //   printf ("NULL\n");
  6412.             // } else {
  6413.             //   subst->print (6);
  6414.             // }
  6415.             // printf ("Testing superclass relationship...\n");
  6416.             if (recursionCounter++ > 100) {
  6417.               error (t1, "This type appears to be recursively defined");
  6418.               error2 (t2, "This type appears to be recursively defined");
  6419.               recursionCounter--;
  6420.               return 1;
  6421.             }
  6422.             sub = isSubType (
  6423.                      copyTypeWithSubst (classDef1->superclass, subst),
  6424.                      t2);
  6425.             recursionCounter--;
  6426.             if (sub) return 1;
  6427.           }
  6428.  
  6429.           // Else, run through the interfaces that t1 implements and see if
  6430.           // t1 is a subType of any of those...
  6431.           // printf ("Testing superImplements relationship in ");  pretty (namedType1);
  6432.           for (typeArg1 = classDef1->implements;
  6433.                typeArg1;
  6434.                typeArg1 = typeArg1->next) {
  6435.             // printf ("  Looking at ");  pretty (typeArg1->type);
  6436.             if (recursionCounter++ > 100) {
  6437.               error (t1, "This type appears to be recursively defined");
  6438.               error2 (t2, "This type appears to be recursively defined");
  6439.               recursionCounter--;
  6440.               return 1;
  6441.             }
  6442.             sub = isSubType (
  6443.                      copyTypeWithSubst (typeArg1->type, subst),
  6444.                      t2);
  6445.             recursionCounter--;
  6446.             if (sub) return 1;
  6447.           }
  6448.           return 0;
  6449.  
  6450.         // Else if t2 is an Interface...
  6451.         } else if (namedType1->myDef->op == INTERFACE) {
  6452.  
  6453.           // printf ("Within interface ");  pretty (namedType1);
  6454.           interface1 = (Interface *) (namedType1->myDef);
  6455.  
  6456.           // We've got "List[int]" and "Collection[...]"; Assume that the interface
  6457.           // looks like this "List [T:...]".  Build a subst "T->int".
  6458.           subst = buildSubstitution (interface1->typeParms, namedType1->typeArgs);
  6459.  
  6460.           // Run through the interfaces that t1 extends and see if
  6461.           // t1 is a subType of any of those...
  6462.           // printf ("Testing superExtends relationship in ");  pretty (namedType1);
  6463.           for (typeArg1 = interface1->extends;
  6464.                             typeArg1; typeArg1 = typeArg1->next) {
  6465.             // printf ("  Looking at ");  pretty (typeArg1->type);
  6466.             if (recursionCounter++ > 100) {
  6467.               error (t1, "This type appears to be recursively defined");
  6468.               error2 (t2, "This type appears to be recursively defined");
  6469.               recursionCounter--;
  6470.               return 1;
  6471.             }
  6472.             sub = isSubType (
  6473.                      copyTypeWithSubst (typeArg1->type, subst),
  6474.                      t2);
  6475.             recursionCounter--;
  6476.             if (sub) return 1;
  6477.           }
  6478.           return 0;
  6479.  
  6480.         } else {
  6481.           programLogicError ("Tested above that t1 was either Class or Interface");
  6482.         }
  6483.       }
  6484.       return 1;
  6485.  
  6486.     default:                                        // in isSubType
  6487.       printf ("t1->op = %s\n", symbolName (t1->op));
  6488.       printf ("t2->op = %s\n", symbolName (t2->op));
  6489.       programLogicError ("Unknown op in isSubType");
  6490.   }
  6491.  
  6492. }
  6493.  
  6494.  
  6495.  
  6496. // assignable (t1, t2) --> bool
  6497. //
  6498. // This routine is passed two Types.  It returns true if
  6499. //        t1 <- t2
  6500. //
  6501. // If problems arise, this routine returns true, hoping to
  6502. // supress further error messages.
  6503. //
  6504. int assignable (Type * t1, Type * t2) {
  6505.   TypeArg * typeArg1, * typeArg2;
  6506.   TypeDef * typeDef;
  6507.   NamedType * namedType1, * namedType2;
  6508.   ClassDef * classDef1;
  6509.   Interface * interface1;
  6510.   RecordType * rec1, * rec2;
  6511.   RecordField * rf1, *rf2;
  6512.   FunctionType * fType1, * fType2;
  6513.   AstNode * def1, * def2;
  6514.   int sub, equal;
  6515.   IntConst * intCon1, * intCon2;
  6516.  
  6517.   // printf ("-----  Testing assignable...\n");
  6518.   // printf ("-----    t1 = ");
  6519.   // pretty (t1);
  6520.   // printf ("-----    t2 = ");
  6521.   // pretty (t2);
  6522.  
  6523.   // If for any reason, we've had earlier problems, just return immediately...
  6524.   if (t1 == NULL || t2 == NULL) return 1;
  6525.  
  6526.   // If either of the types is a type-def, then use that...
  6527.   if (t1->op == NAMED_TYPE) {
  6528.     typeDef = (TypeDef *) (((NamedType *) t1)->myDef);
  6529.     if (typeDef) {
  6530.       if (typeDef->op == TYPE_DEF) {
  6531.         return assignable (typeDef->type, t2);
  6532.       }
  6533.     } else {
  6534.       return 1;
  6535.     }
  6536.   }
  6537.   if (t2->op == NAMED_TYPE) {
  6538.     typeDef = (TypeDef *) (((NamedType *) t2)->myDef);
  6539.     if (typeDef) {
  6540.       if (typeDef->op == TYPE_DEF) {
  6541.         return assignable (t1, typeDef->type);
  6542.       }
  6543.     } else {
  6544.       return 1;
  6545.     }
  6546.   }
  6547.  
  6548.   if (t2->op == ANY_TYPE) return 0;
  6549.  
  6550.   switch (t1->op) {
  6551.  
  6552.     case ANY_TYPE:                                  // in assignable
  6553.       return 0;
  6554.  
  6555.     case CHAR_TYPE:                                 // in assignable
  6556.       return (t2->op == CHAR_TYPE);
  6557.  
  6558.     case INT_TYPE:                                  // in assignable
  6559.       return (t2->op == INT_TYPE);
  6560.  
  6561.     case DOUBLE_TYPE:                               // in assignable
  6562.       return (t2->op == DOUBLE_TYPE);
  6563.  
  6564.     case BOOL_TYPE:                                 // in assignable
  6565.       return (t2->op == BOOL_TYPE);
  6566.  
  6567.     case VOID_TYPE:                                 // in assignable
  6568.       return (t2->op == VOID_TYPE);
  6569.  
  6570.     case TYPE_OF_NULL_TYPE:                         // in assignable
  6571.       return (t2->op == TYPE_OF_NULL_TYPE);
  6572.  
  6573.     case PTR_TYPE:                                  // in assignable
  6574.       if (t2->op == TYPE_OF_NULL_TYPE) return 1;
  6575.       if (t2->op != PTR_TYPE) return 0;
  6576.       if (!safe && isVoidType (((PtrType *) t1)->baseType)) return 1;
  6577.       if (!safe && isVoidType (((PtrType *) t2)->baseType)) return 1;
  6578.       if (recursionCounter++ > 100) {
  6579.         error (t1, "This type appears to be recursively defined");
  6580.         error2 (t2, "This type appears to be recursively defined");
  6581.         recursionCounter--;
  6582.         return 1;
  6583.       }
  6584.       sub = isSubType (((PtrType *) t2)->baseType,
  6585.                           ((PtrType *) t1)->baseType);
  6586.       recursionCounter--;
  6587.       return sub;
  6588.  
  6589.     case RECORD_TYPE:                               // in assignable
  6590.       if (t2->op != RECORD_TYPE) return 0;
  6591.       // To be a assignable, the records must match exactly...
  6592.       rec1 = (RecordType *) t1;
  6593.       rec2 = (RecordType *) t2;
  6594.       rf1 = rec1->fields;
  6595.       rf2 = rec2->fields;
  6596.       while (1) {
  6597.         if ((rf1 == NULL) && (rf2 == NULL)) return 1;
  6598.         if ((rf1 == NULL) || (rf2 == NULL)) return 0;
  6599.         if (rf1->id != rf2->id) return 0;
  6600.         if (!typesEqual (rf1->type, rf2->type)) return 0;
  6601.         rf1 = (RecordField *) rf1->next;
  6602.         rf2 = (RecordField *) rf2->next;
  6603.       }
  6604.       return 1;
  6605.  
  6606.     case ARRAY_TYPE:                                // in assignable
  6607.       if (t2->op != ARRAY_TYPE) return 0;
  6608.       if (recursionCounter++ > 100) {
  6609.         error (t1, "This type appears to be recursively defined");
  6610.         error2 (t2, "This type appears to be recursively defined");
  6611.         recursionCounter--;
  6612.         return 1;
  6613.       }
  6614.  
  6615.       // printf ("t1->sizeExpr = ");  pretty (((ArrayType *) t1)->sizeExpr);
  6616.       // printf ("t2->sizeExpr = ");  pretty (((ArrayType *) t2)->sizeExpr);
  6617.  
  6618.       equal = typesEqual (((ArrayType *) t1)->baseType,
  6619.                           ((ArrayType *) t2)->baseType);
  6620.       recursionCounter--;
  6621.       if (!equal) return 0;
  6622.       // Next, take a look at the size expressions...
  6623.       intCon1 = (IntConst *) ((ArrayType *) t1)->sizeExpr;
  6624.       intCon2 = (IntConst *) ((ArrayType *) t2)->sizeExpr;
  6625.       // If either is dynamic, not assignable...
  6626.       if ((intCon1 == NULL) || (intCon2 == NULL)) return 0;
  6627.       // We have run evalExprs already, so we *hope* that all expressions
  6628.       // have been evaluated.  However, there may be perfectly reasonable
  6629.       // size expressions (e.g., involving constants) which have not been
  6630.       // computed at the time "typesEqual" is used.
  6631.       if (intCon1->op != INT_CONST) {
  6632.         error (intCon1, "The size of the array cannot be determined at this time");
  6633.         errorWithType ("when testing for assignability, this type", t1);
  6634.         errorWithType ("and this type", t2);
  6635.         return 1;
  6636.       }
  6637.       if (intCon2->op != INT_CONST) {
  6638.         error (intCon2, "The size of the array cannot be determined at this time");
  6639.         errorWithType ("when testing for assignability, this type", t1);
  6640.         errorWithType ("and this type", t2);
  6641.         return 1;
  6642.       }
  6643.       return intCon1->ivalue == intCon2->ivalue;
  6644.  
  6645.     case FUNCTION_TYPE:                             // in assignable
  6646.       return 0;
  6647.  
  6648.     case NAMED_TYPE:                                // in assignable
  6649.       // If one type is a NamedType, make sure both types are NamedTypes.
  6650.       // If either happens to be undefined, it is an error, so just return true.
  6651.       namedType1 = (NamedType *) t1;
  6652.       def1 = namedType1->myDef;
  6653.       if (def1 == NULL) return 1;
  6654.  
  6655.       if (t2->op != NAMED_TYPE) return 0;
  6656.       namedType2 = (NamedType *) t2;
  6657.       def2 = namedType2->myDef;
  6658.       if (def2 == NULL) return 1;
  6659.  
  6660.       // If both types refer to the same TypeParameter, return true;
  6661.       // Else if either is a typeParm, then return false.
  6662.       if (def1->op == TYPE_PARM) return (def2 == def1);
  6663.       if (def2->op == TYPE_PARM) return 0;
  6664.  
  6665.       // If either type refers to an interface, then return false.
  6666.       if (def1->op == INTERFACE) return 0;
  6667.       if (def2->op == INTERFACE) return 0;
  6668.  
  6669.       // We have something like "Person <- Person" or "List[anyType] <- List[int]"...
  6670.       // Make sure the ID's are the same.
  6671.       if (namedType1->id != namedType2->id) return 0;
  6672.  
  6673.       // The names are known to be defined; make sure they refer to the same class.
  6674.       if (def2 != def1) return 0;
  6675.  
  6676.       // NamedTypes may be: TypeDefs, TypeParms, Interfaces, Classes, or undefined.
  6677.       // By this time, we have checked for everything except classes, so they
  6678.       // must both name a class.
  6679.       if (def1->op != CLASS_DEF) {
  6680.         programLogicError ("In assignable: This must be a CLASS_DEF, but is not");
  6681.       }
  6682.  
  6683.       // Now run through the typeArgs.  Make sure there are the same number
  6684.       // and make sure they are pairwise equal...
  6685.       typeArg1 = namedType1->typeArgs;
  6686.       typeArg2 = namedType2->typeArgs;
  6687.       while (1) {
  6688.         if ((typeArg1 == NULL) && (typeArg2 == NULL)) return 1;
  6689.         if ((typeArg1 == NULL) || (typeArg2 == NULL)) return 0;
  6690.         if (!typesEqual (typeArg1->type, typeArg2->type)) return 0;
  6691.         typeArg1 = typeArg1->next;
  6692.         typeArg2 = typeArg2->next;
  6693.       }
  6694.       programLogicError ("The above infinite loop terminates with returns");
  6695.  
  6696.     default:                                  // in assignable
  6697.       printf ("t1->op = %s\n", symbolName (t1->op));
  6698.       printf ("t2->op = %s\n", symbolName (t2->op));
  6699.       programLogicError ("Unknown op in assignable");
  6700.   }
  6701.  
  6702. }
  6703.  
  6704.  
  6705.  
  6706. // buildSubstitution (listOfTypeParms, listOfTypeArgs) -> mapping
  6707. //
  6708. // This routine is passed a list of TypeParms and a list of TypeArgs.
  6709. //
  6710. // It returns a substitution, which is a mapping from typeParms to types.
  6711. //
  6712. // Either of the args may be NULL, in which case it returns the NULL
  6713. // substitution.  If the lists are not the same length, it just does what it
  6714. // can without printing any error messages.
  6715. //
  6716. Mapping <TypeParm, Type> * buildSubstitution (TypeParm * typeParm,
  6717.                                               TypeArg * typeArg) {
  6718.   Mapping <TypeParm, Type> * mapping;
  6719.  
  6720.   if (typeParm == NULL) return NULL;
  6721.   if (typeArg == NULL) return NULL;
  6722.   mapping = new Mapping <TypeParm, Type> (5, NULL);
  6723.   while (1) {
  6724.     // We'll check that we have correct # of args later...
  6725.     if (typeParm == NULL) return mapping;
  6726.     if (typeArg == NULL) return mapping;
  6727.     mapping->enter (typeParm, typeArg->type);
  6728.     typeParm = typeParm->next;
  6729.     typeArg = typeArg->next;
  6730.   }
  6731.   return mapping;
  6732. }
  6733.  
  6734.  
  6735.  
  6736. // checkImplements (hdr)
  6737. //
  6738. // This routine looks at each class and then looks at the interfaces that it
  6739. // "implements".  It makes sure that the class provides a method for each message
  6740. // that is in the interface and that the parameter types and return type are correct,
  6741. // according to co- and contra-variance.
  6742. //
  6743. void checkImplements (Header * hdr) {
  6744.   ClassDef * cl;
  6745.   TypeArg * typeArg, * superTypeArg;
  6746.   TypeParm * typeParm;
  6747.   NamedType * nType;
  6748.   Interface * superInter;
  6749.   Mapping <TypeParm, Type> * subst;
  6750.   MethodProto * proto, * classProto;
  6751.   Parameter * superParm, * subParm;
  6752.  
  6753.   // Run through all classes...
  6754.   for (cl = hdr->classes; cl; cl = cl->next) {
  6755.  
  6756.     // Run through each of the interfaces that this class implements...
  6757.     for (superTypeArg = cl->implements;
  6758.          superTypeArg;
  6759.          superTypeArg = superTypeArg->next) {
  6760.       nType = (NamedType *) superTypeArg->type;
  6761.       superInter = (Interface *) (nType->myDef);
  6762.       // If no previous errors...
  6763.       if (superInter) {
  6764.         if (superInter->op == INTERFACE) {
  6765.  
  6766.           // Build a substitution for the TypeParms...
  6767.           subst = NULL;
  6768.           typeParm = superInter->typeParms;
  6769.           typeArg = nType->typeArgs;
  6770.           while (1) {
  6771.             if ((typeParm == NULL) && (typeArg == NULL)) break;
  6772.             if ((typeParm == NULL) || (typeArg == NULL)) {
  6773.               error (superTypeArg, "The number of type arguments here does not match the number of type parameters in the interface definition");
  6774.               break;
  6775.             }
  6776.             if (subst == NULL) {
  6777.               subst = new Mapping <TypeParm, Type> (3, NULL);
  6778.             }
  6779.             subst->enter (typeParm, typeArg->type);
  6780.             typeParm = typeParm->next;
  6781.             typeArg = typeArg->next;
  6782.           }
  6783.  
  6784.           // printf ("subst = \n");
  6785.           // if (subst) {
  6786.           //   subst->print (6);
  6787.           // } else {
  6788.           //   printf ("NULL\n");
  6789.           // }
  6790.  
  6791.           // Run through the superInterfaces's methodProtos...
  6792.           for (proto = superInter->methodProtos; proto; proto=proto->next) {
  6793.             // First, make sure this class has this method...
  6794.             classProto = cl->selectorMapping->findInTopScope (proto->selector);
  6795.             if (classProto == NULL) {
  6796.               error (cl, "This class fails to provide a method");
  6797.               error2 (proto, "Here is the message from an interface this class implements");
  6798.             } else {
  6799.               // Make sure the parameter types are correct...
  6800.               superParm = proto->parmList;
  6801.               subParm = classProto->parmList;
  6802.               while (1) {
  6803.                 if ((superParm == NULL) && (subParm == NULL)) break;
  6804.                 if ((superParm == NULL) || (subParm == NULL)) {
  6805.                   error (classProto, "This method does not have the correct number of parameters");
  6806.                   error2 (proto, "Here is the message from an interface this class implements");
  6807.                   break;
  6808.                 }
  6809.                 if (!assignable (subParm->type,
  6810.                                  copyTypeWithSubst (superParm->type, subst))) {
  6811.                   error (subParm, "This parameter's type is not correct (perhaps it is not general enough)");
  6812.                   error2 (superParm, "Here is the corresponding parameter from a message in an interface this class implements");
  6813.                   errorWithType (
  6814.                          "The interface requires that this parameter be able to handle values of type",
  6815.                          copyTypeWithSubst (superParm->type, subst));
  6816.                   errorWithType (
  6817.                          "The type of this method's parameter is",
  6818.                          subParm->type);
  6819.                 }
  6820.                 superParm = (Parameter *) superParm->next;
  6821.                 subParm = (Parameter *) subParm->next;
  6822.               }
  6823.               // Make sure the return type is correct...
  6824.               if (!assignable (copyTypeWithSubst (proto->retType, subst),
  6825.                                classProto->retType)) {
  6826.                 error (classProto, "The return type of this method is not correct (perhaps it is too general)");
  6827.                 error2 (proto, "Here is the corresponding message in an interface this class implements");
  6828.                 errorWithType (
  6829.                          "The interface requires this method to return a type assignable to",
  6830.                          copyTypeWithSubst (proto->retType, subst));
  6831.                 errorWithType (
  6832.                          "This method's return type is",
  6833.                          classProto->retType);
  6834.               }
  6835.               // Make sure the kind is correct...
  6836.               if (proto->kind != classProto->kind) {
  6837.                 error (classProto, "This method is not the correct kind (infix, binary, keyword, normal)");
  6838.                 error2 (proto, "Here is the message from an interface this class implements");
  6839.               }
  6840.             }
  6841.           }        // for all protos
  6842.  
  6843.         }        // if superInter == INTERFACE
  6844.       }        // if superInter
  6845.     }        // for all superTypeArgs
  6846.   }        // for all classes
  6847. }
  6848.  
  6849.  
  6850.  
  6851. // checkMethodProtos (hdr)
  6852. //
  6853. // This routine looks at each class and does the following:
  6854. //
  6855. // 1.  For each method, make sure its parameter types and return type match a prototype
  6856. //     in that class.
  6857. // 2.  When methods are inherited, make sure that the parameter and return types
  6858. //     of the super-prototype and the sub-prototype respect co/contra-variance.
  6859. // 3.  Make sure the names of the parameters exactly match in the Method and in the
  6860. //     MethodPrototype.
  6861. //
  6862. void checkMethodProtos (Header * hdr) {
  6863.   ClassDef * cl;
  6864.   Method * meth;
  6865.   MethodProto * proto, * protoSuper, * protoSub;
  6866.   Parameter * methParm, * protoParm, * subParm;
  6867.   String * superSelector;
  6868.  
  6869.   // Run through all classes...
  6870.   for (cl = hdr->classes; cl; cl = cl->next) {
  6871.     // printf ("Looking at class %s...\n", cl->id->chars);
  6872.  
  6873.     // Run though all the methods...
  6874.     for (meth=cl->methods; meth; meth = meth->next) {
  6875.  
  6876.       // Find the prototype in this class...
  6877.       proto = cl->selectorMapping->findInTopScope (meth->selector);
  6878.       if (proto) {       // If no earlier errors...
  6879.  
  6880.         // printf ("Looking at method %s and proto %s...\n",
  6881.         //         meth->selector->chars, proto->selector->chars);
  6882.  
  6883.         // Make sure it is the same kind.  (This is not strictly necessary, since if
  6884.         // they are different kinds, there will always be another error message.)
  6885.         if (meth->kind != proto->kind) {
  6886.           error (meth, "This method is not the same kind (infix, prefix, keyword, normal) as the corresponding prototype");
  6887.           error2 (proto, "Here is the prototype");
  6888.         }
  6889.  
  6890.         // Make sure each parameter type matches according to contra-variance...
  6891.         protoParm = proto->parmList;
  6892.         methParm = meth->parmList;
  6893.         while (1) {
  6894.           if ((protoParm == NULL) && (methParm == NULL)) break;
  6895.           if ((protoParm == NULL) || (methParm == NULL)) {
  6896.             error (meth, "This method does not have the same number of parameters as the corresponding prototype");
  6897.             error2 (proto, "Here is the prototype");
  6898.             break;
  6899.           }
  6900.           if (! assignable (methParm->type, protoParm->type)) {
  6901.             error (methParm, "The type of this parameter fails to match the type of the corresponding parameter in the prototype (perhaps the type is not general enough)");
  6902.             error2 (proto, "Here is the method prototype");
  6903.             errorWithType ("The type of the method parameter is", methParm->type);
  6904.             errorWithType ("The expected type is", protoParm->type);
  6905.           }
  6906.           // Make sure that the parameters have the same names...
  6907.           if (protoParm->id != methParm->id) {
  6908.             error (methParm, "The name of this parameter does not match the name of the corresponding parameter in the method prototype");
  6909.             error2 (protoParm, "Here is the name used in the method prototype");
  6910.           }
  6911.           protoParm = (Parameter *) protoParm->next;
  6912.           methParm = (Parameter *) methParm->next;
  6913.         }
  6914.  
  6915.         // Make sure the return types match according to covariance...
  6916.         if (! assignable (proto->retType, meth->retType)) {
  6917.           error (meth, "The return type of this method fails to match the corresponding prototype (perhaps the type is too general)");
  6918.           error2 (proto, "Here is the method prototype");
  6919.           errorWithType ("The return type of this method is", meth->retType);
  6920.           errorWithType ("The expected type is", proto->retType);
  6921.         }
  6922.  
  6923.         // Make this MethodProto point to this Method, and the Method
  6924.         // point to the MethodProto...
  6925.  
  6926.       }
  6927.     }
  6928.  
  6929.     // Run through all methods that override something from the superclass...
  6930.     for (meth = cl->methods; meth; meth=meth->next) {
  6931.  
  6932.       // printf ("Looking at method %s\n", meth->selector->chars);
  6933.  
  6934.       // See if we have prototypes for this method and for an inherited version...
  6935.       superSelector = addSuperTo (meth->selector);
  6936.       protoSub = cl->selectorMapping->findInTopScope (meth->selector);
  6937.       protoSuper = cl->selectorMapping->findInTopScope (superSelector);
  6938.       if (protoSub && protoSuper) {
  6939.         // printf ("     protoSuper = ");
  6940.         // pretty (protoSuper);
  6941.         // printf ("     protoSub   = ");
  6942.         // pretty (protoSub);
  6943.         checkProtos (protoSuper, protoSub);
  6944.       }
  6945.     }
  6946.  
  6947.   }     // for all classes
  6948. }
  6949.  
  6950.  
  6951.  
  6952. // checkProtos (protoSuper, protoSub)
  6953. //
  6954. // This routine is passed two MethodProtos.  It checks to make sure they are compatable
  6955. // according to co- and contra-variance.  It will print error messages if not.
  6956. //
  6957. // See also checkProtos2, which is a VERY SIMILAR ROUTINE.
  6958. //
  6959. void checkProtos (MethodProto * protoSuper, MethodProto * protoSub) {
  6960.   Parameter * protoParm, * subParm;
  6961.  
  6962.   if ((protoSuper == NULL) || (protoSub == NULL)) {
  6963.     programLogicError ("Should have two non-NULL protos");
  6964.   }
  6965.  
  6966.   // printf ("Looking at protoSuper = ");
  6967.   // pretty (protoSuper);
  6968.   // printf ("           protoSub = ");
  6969.   // pretty (protoSub);
  6970.  
  6971.   // They should have the same kind...
  6972.   if (protoSuper->kind != protoSub->kind) {
  6973.     programLogicError ("Kind mismatch in checkProtos");
  6974.   }
  6975.  
  6976.   // Make sure each parm type matches according to contra-variance...
  6977.   protoParm = protoSuper->parmList;
  6978.   subParm = protoSub->parmList;
  6979.   while (1) {
  6980.     if ((protoParm == NULL) && (subParm == NULL)) break;
  6981.     if ((protoParm == NULL) || (subParm == NULL)) {
  6982.       error (protoSub, "This method does not have the same number of parameters as the corresponding method in the super class");
  6983.       error2 (protoSuper, "Here is the prototype from the super class");
  6984.       break;
  6985.     }
  6986.     if (! assignable (subParm->type, protoParm->type)) {
  6987.       error (subParm, "When overriding a method... the type of this parameter fails to match the type of the corresponding parameter in the method from the super class (perhaps it is not general enough)");
  6988.       error2 (protoSuper, "Here is the method from the super class");
  6989.       errorWithType ("The parameter type in the subclass is", subParm->type);
  6990.       errorWithType ("The expected type is", protoParm->type);
  6991.     }
  6992.     protoParm = (Parameter *) protoParm->next;
  6993.     subParm = (Parameter *) subParm->next;
  6994.   }
  6995.  
  6996.   // Make sure the return types match according to covariance...
  6997.   if (! assignable (protoSuper->retType, protoSub->retType)) {
  6998.     error (protoSub, "When overriding a method... the return type of this method fails to match the corresponding method from the super class (perhaps it is too general)");
  6999.     error2 (protoSuper, "Here is the method from the super class");
  7000.     errorWithType ("The type returned in the subclass is", protoSub->retType);
  7001.     errorWithType ("The expected type is", protoSuper->retType);
  7002.   }
  7003. }
  7004.  
  7005.  
  7006.  
  7007. // checkProtos2 (protoSuper, protoSub)
  7008. //
  7009. // This routine is passed two MethodProtos.  It checks to make sure they are compatable
  7010. // according to co- and contra-variance.  It will print error messages if not.
  7011. //
  7012. // This routine differs from "checkProtos" in that it is used for checking "extends"
  7013. // among interfaces.  The code is the same, but the error message texts differ slightly.
  7014. //
  7015. void checkProtos2 (MethodProto * protoSuper, MethodProto * protoSub) {
  7016.   Parameter * protoParm, * subParm;
  7017.  
  7018.   if ((protoSuper == NULL) || (protoSub == NULL)) {
  7019.     programLogicError ("Should have two non-NULL protos");
  7020.   }
  7021.  
  7022.   // printf ("Looking at protoSuper = ");
  7023.   // pretty (protoSuper);
  7024.   // printf ("           protoSub = ");
  7025.   // pretty (protoSub);
  7026.  
  7027.   // They should have the same kind...
  7028.   if (protoSuper->kind != protoSub->kind) {
  7029.     programLogicError ("Kind mismatch in checkProtos2");
  7030.   }
  7031.  
  7032.   // Make sure each parm type matches according to contra-variance...
  7033.   protoParm = protoSuper->parmList;
  7034.   subParm = protoSub->parmList;
  7035.   while (1) {
  7036.     if ((protoParm == NULL) && (subParm == NULL)) break;
  7037.     if ((protoParm == NULL) || (subParm == NULL)) {
  7038.       error (protoSub, "This message does not have the same number of parameters as the corresponding message in an interface we are extending");
  7039.       error2 (protoSuper, "Here is the prototype from the super-interface");
  7040.       break;
  7041.     }
  7042.     if (! assignable (subParm->type, protoParm->type)) {
  7043.       error (subParm, "The type of this parameter fails to match the type of the corresponding parameter in the same message in an interface we are extending (perhaps it is not general enough)");
  7044.       error2 (protoSuper, "Here is the message from the super-interface");
  7045.       errorWithType ("The parameter type in the sub-interface is", subParm->type);
  7046.       errorWithType ("The expected type is", protoParm->type);
  7047.     }
  7048.     protoParm = (Parameter *) protoParm->next;
  7049.     subParm = (Parameter *) subParm->next;
  7050.   }
  7051.  
  7052.   // Make sure the return types match according to covariance...
  7053.   if (! assignable (protoSuper->retType, protoSub->retType)) {
  7054.     error (protoSub, "The return type of this message fails to match the corresponding message in an interface we are extending (perhaps it is too general)");
  7055.     error2 (protoSuper, "Here is the message from the super-interface");
  7056.     errorWithType ("The type returned in the sub-interface is", protoSub->retType);
  7057.     errorWithType ("The expected type is", protoSuper->retType);
  7058.   }
  7059. }
  7060.  
  7061.  
  7062.  
  7063. // checkProtos3 (proto1, proto2)
  7064. //
  7065. // This routine is passed two MethodProtos.  It checks to make sure their parameter and
  7066. // return types are equal.  It will print error messages if not.
  7067. //
  7068. void checkProtos3 (MethodProto * proto1, MethodProto * proto2, Interface * inter) {
  7069.   Parameter * parm1, * parm2;
  7070.  
  7071.   if ((proto1 == NULL) || (proto2 == NULL)) {
  7072.     programLogicError ("Should have two non-NULL protos in checkProtos3");
  7073.   }
  7074.  
  7075.   // printf ("Looking at proto1 = ");
  7076.   // pretty (proto1);
  7077.   // printf ("           proto2 = ");
  7078.   // pretty (proto2);
  7079.  
  7080.   // They should have the same kind...
  7081.   if (proto1->kind != proto2->kind) {
  7082.     programLogicError ("Kind mismatch in checkProtos3");
  7083.   }
  7084.  
  7085.   // Make sure each parm type matches exactly...
  7086.   parm1 = proto1->parmList;
  7087.   parm2 = proto2->parmList;
  7088.   while (1) {
  7089.     if ((parm1 == NULL) && (parm2 == NULL)) break;
  7090.     if ((parm1 == NULL) || (parm2 == NULL)) {
  7091.       error (inter, "This interface extends two other interfaces; both contain the same message but the messages do not have the same number of parameters");
  7092.       error2 (proto1, "Here is the message in one super-interface");
  7093.       error2 (proto2, "Here is the message in the other super-interface");
  7094.       break;
  7095.     }
  7096.     if (! typesEqual (parm1->type, parm2->type)) {
  7097.       error (inter, "This interface extends two other interfaces and both contain the same message; since there is no corresponding message in this interface, the types of the parameters must match exactly, but they do not (You might consider adding a message in this interface with a parameter type that is more general)");
  7098.       error2 (parm2, "Here is the parameter from one super-interface");
  7099.       error2 (parm1, "Here is the parameter from the other super-interface");
  7100.     }
  7101.     parm1 = (Parameter *) parm1->next;
  7102.     parm2 = (Parameter *) parm2->next;
  7103.   }
  7104.  
  7105.   // Make sure the return types match according to covariance...
  7106.   if (! typesEqual (proto2->retType, proto1->retType)) {
  7107.     error (inter, "This interface extends two other interfaces and both contain the same message; since there is no corresponding message in this interface, the return types of must match exactly, but they do not (You might consider adding a message in this interface with a more specific return type)");
  7108.     error2 (proto1, "Here is the message from one super interface");
  7109.     error2 (proto2, "Here is the message from the other super interface");
  7110.   }
  7111. }
  7112.  
  7113.  
  7114.  
  7115. // checkExtends (hdr)
  7116. //
  7117. // This routine runs through each interface and for each, checks the following:
  7118. //
  7119. // 1.  If this interface provides a message that is also inherited, we make sure
  7120. //     that the parameter and return types respect co- and contra-variance.
  7121. // 2.  If this interface inherits the same message from different sources,
  7122. //     but does not contain the message itself, we check to make sure that
  7123. //     the parameter and return types are equal on all versions of the inherited
  7124. //     method.
  7125. //
  7126. void checkExtends (Header * hdr) {
  7127.   Interface * inter;
  7128.   MethodProto * protoSuper, * protoSub, * otherProto;
  7129.   Mapping <String, MethodProto> * otherMap;
  7130.  
  7131.   otherMap = new Mapping <String, MethodProto> (0, NULL);
  7132.  
  7133.   // Run through all interfaces...
  7134.   for (inter = hdr->interfaces; inter; inter = inter->next) {
  7135.     // printf ("Looking at interface %s...\n", inter->id->chars);
  7136.  
  7137.     // Run through all inherited methods...
  7138.     for (protoSuper = inter->inheritedMethodProtos;
  7139.          protoSuper;
  7140.          protoSuper = protoSuper->next) {
  7141.  
  7142.       // printf ("Looking at proto = %s...\n", protoSuper->selector->chars);
  7143.  
  7144.       // See if this interface also provides this method and, if so, check that
  7145.       // they are compatible...
  7146.       protoSub = inter->selectorMapping->findInTopScope (protoSuper->selector);
  7147.       if (protoSub) {
  7148.         checkProtos2 (protoSuper, protoSub);
  7149.  
  7150.       // If this message is inherited, but not present in this class...
  7151.       } else {
  7152.         // See if we've seen something similar before...
  7153.         // printf ("This proto is not in this method; looking in otherMap...\n");
  7154.         otherProto = otherMap->findInTopScope (protoSuper->selector);
  7155.         if (otherProto) {
  7156.           // printf ("Found another one...\n");
  7157.           checkProtos3 (protoSuper, otherProto, inter);
  7158.         } else {
  7159.           // printf ("Not found; adding it...\n");
  7160.           otherMap->enter (protoSuper->selector, protoSuper);
  7161.         }
  7162.       }
  7163.       
  7164.     }
  7165.  
  7166.     // Now run through all inherited methods and add them to our "selectorMapping".
  7167.     // There may be duplicates, due to multiple inheritance, but they must all
  7168.     // have equal parm and return types.  If there are multiple occurrences, just
  7169.     // add the first one.
  7170.     for (protoSuper = inter->inheritedMethodProtos;
  7171.          protoSuper;
  7172.          protoSuper = protoSuper->next) {
  7173.  
  7174.       // printf ("Looking at proto = %s...\n", protoSuper->selector->chars);
  7175.  
  7176.       // If not found, add it...
  7177.       protoSub = inter->selectorMapping->findInTopScope (protoSuper->selector);
  7178.       if (protoSub == NULL) {
  7179.         inter->selectorMapping->enter (protoSuper->selector, protoSuper);
  7180.       }
  7181.     }
  7182.  
  7183.   }
  7184.  
  7185. }
  7186.  
  7187.  
  7188.  
  7189. // checkTypes (node) --> type
  7190. //
  7191. // This routine walks the entire Abstract Syntax Tree, visiting every node.
  7192. // For each expression, it computes the type of the expression and returns it.
  7193. // For other sorts of nodes, it simply returns NULL.
  7194. //
  7195. // If errors occur, it returns NULL.
  7196. //
  7197. // It catches the following errors:
  7198. //        ...
  7199. //
  7200. // This routine also checks that each Function matches its FunctionProto, making
  7201. // sure that the parameters have the same names and types.
  7202. //         The parm names on a Function do not match those in the FunctionProto
  7203. //         There are a different number of parms in Function and FunctionProto
  7204. //         The parm/return types do not match in Function and FunctionProto
  7205. //
  7206. // This routine also identifies primitive operations.
  7207. //
  7208. Type * checkTypes (AstNode * node) {
  7209.     Header * header;
  7210.     Code * code;
  7211.     Uses * uses;
  7212.     Renaming * renaming;
  7213.     Interface * interface;
  7214.     ClassDef * cl;
  7215.     Behavior * behavior;
  7216.     TypeDef * typeDef;
  7217.     ConstDecl * constDecl;
  7218.     ErrorDecl * errorDecl;
  7219.     FunctionProto * functionProto;
  7220.     Function * fun;
  7221.     MethodProto * methodProto;
  7222.     Method * meth;
  7223.     TypeParm * typeParm;
  7224.     TypeArg * typeArg, * typeArgList, * nextTypeArg;
  7225.     CharType * charType;
  7226.     IntType * intType;
  7227.     DoubleType * doubleType;
  7228.     BoolType * boolType;
  7229.     VoidType * voidType;
  7230.     TypeOfNullType * typeOfNullType;
  7231.     AnyType * anyType;
  7232.     PtrType * pType;
  7233.     ArrayType * aType;
  7234.     RecordType * rType;
  7235.     FunctionType * fType;
  7236.     NamedType * nType, * namedType2;
  7237.     IfStmt * ifStmt;
  7238.     AssignStmt * assignStmt;
  7239.     CallStmt * callStmt;
  7240.     SendStmt * sendStmt;
  7241.     WhileStmt * whileStmt;
  7242.     DoStmt * doStmt;
  7243.     BreakStmt * breakStmt;
  7244.     ContinueStmt * continueStmt;
  7245.     ReturnStmt * returnStmt;
  7246.     ForStmt * forStmt;
  7247.     SwitchStmt * switchStmt;
  7248.     TryStmt * tryStmt;
  7249.     ThrowStmt * throwStmt;
  7250.     FreeStmt * freeStmt;
  7251.     DebugStmt * debugStmt;
  7252.     Case * cas;
  7253.     Catch * cat;
  7254.     Global * global;
  7255.     Local * local;
  7256.     Parameter * parm;
  7257.     ClassField * classField;
  7258.     RecordField * recordField;
  7259.     CallExpr * callExpr;
  7260.     SendExpr * sendExpr;
  7261.     SelfExpr * selfExpr;
  7262.     SuperExpr * superExpr;
  7263.     FieldAccess * fieldAccess;
  7264.     ArrayAccess * arrayAccess;
  7265.     Constructor * constructor;
  7266.     ClosureExpr * closureExpr;
  7267.     VariableExpr * var;
  7268.     AsPtrToExpr * asPtrToExpr;
  7269.     AsIntegerExpr * asIntegerExpr;
  7270.     ArraySizeExpr * arraySizeExpr;
  7271.     IsInstanceOfExpr * isInstanceOfExpr;
  7272.     IsKindOfExpr * isKindOfExpr;
  7273.     SizeOfExpr * sizeOfExpr;
  7274.     DynamicCheck * dynamicCheck;
  7275.     Argument * arg;
  7276.     CountValue * countValue;
  7277.     FieldInit * fieldInit;
  7278.     Type * t, * t2, * resultType;
  7279.     VarDecl * varDecl;
  7280.     String * nameWithoutSuper, * newSelector;
  7281.     AstNode * def;
  7282.     int recvrIsSuper, count, i, looksLikeDeref, numberOfCases;
  7283.     Mapping <String, AstNode> * tempMap;
  7284.     Parameter * protoParm, * subParm, * funParm;
  7285.     int arSize, j;
  7286.     Case * * caseArray;
  7287.     DoubleConst * doubleConst;
  7288.     StringConst * stringConst;
  7289.     IntConst * intConst;
  7290.  
  7291.   if (node == NULL) return NULL;
  7292.  
  7293.   // printf ("%s...\n", symbolName (node->op));
  7294.  
  7295.   switch (node->op) {
  7296.  
  7297.     case HEADER:                               // in checkTypes
  7298.       header = (Header *) node;
  7299.       // printf ("  %s\n", header->packageName->chars);
  7300.       t = checkTypes (header->uses);
  7301.       t = checkTypes (header->consts);
  7302.       t = checkTypes (header->errors);
  7303.       t = checkTypes (header->globals);
  7304.       t = checkTypes (header->typeDefs);
  7305.       t = checkTypes (header->functionProtos);
  7306.       t = checkTypes (header->closures);  // do clos before funs, so debug printing works
  7307.       t = checkTypes (header->functions);
  7308.       t = checkTypes (header->interfaces);
  7309.       t = checkTypes (header->classes);
  7310.       // t = checkTypes (header->next);
  7311.       return NULL;
  7312.  
  7313. //    case CODE:                               // in checkTypes
  7314. //      code = (Code *) node;
  7315. //      t = checkTypes (code->consts);
  7316. //      t = checkTypes (code->globals);
  7317. //      t = checkTypes (code->typeDefs);
  7318. //      t = checkTypes (code->functions);
  7319. //      t = checkTypes (code->interfaces);
  7320. //      t = checkTypes (code->classes);
  7321. //      t = checkTypes (code->behaviors);
  7322. //      return NULL;
  7323.  
  7324.     case USES:                               // in checkTypes
  7325.       uses = (Uses *) node;
  7326.       t = checkTypes (uses->renamings);
  7327.       t = checkTypes (uses->next);
  7328.       return NULL;
  7329.  
  7330.     case RENAMING:                               // in checkTypes
  7331.       renaming = (Renaming *) node;
  7332.       t = checkTypes (renaming->next);
  7333.       return NULL;
  7334.  
  7335.     case INTERFACE:                               // in checkTypes
  7336.       interface = (Interface *) node;
  7337.       // printf ("  %s\n", interface->id->chars);
  7338.       t = checkTypes (interface->typeParms);
  7339.       t = checkTypes (interface->extends);
  7340.       t = checkTypes (interface->methodProtos);
  7341.       t = checkTypes (interface->next);
  7342.       return NULL;
  7343.  
  7344.     case CLASS_DEF:                               // in checkTypes
  7345.       cl = (ClassDef *) node;
  7346.       currentClass = cl;
  7347.       // printf ("  %s\n", cl->id->chars);
  7348.       // Create a subtree to represent the type of "self"...
  7349.       nType = new NamedType ();
  7350.       nType->positionAt (cl);
  7351.       nType->id = cl->id;
  7352.       nType->myDef = cl;
  7353.       typeArgList = NULL;
  7354.       // Build a list of parameters...
  7355.       for (typeParm = cl->typeParms; typeParm; typeParm = typeParm->next) {
  7356.         typeArg = new TypeArg ();
  7357.         typeArg->positionAt (cl);
  7358.           namedType2 = new NamedType ();
  7359.           namedType2->positionAt (cl);
  7360.           namedType2->id = typeParm->id;
  7361.           namedType2->myDef = typeParm;
  7362.         typeArg->type = namedType2;
  7363.         typeArg->next = typeArgList;
  7364.         typeArgList = typeArg;
  7365.       }
  7366.       // Reverse the list...
  7367.       typeArg = typeArgList;
  7368.       while (typeArg) {
  7369.         nextTypeArg = typeArg->next;
  7370.         typeArg->next = nType->typeArgs;
  7371.         nType->typeArgs = typeArg;
  7372.         typeArg = nextTypeArg;
  7373.       }
  7374.       pType = new PtrType ();
  7375.       pType->positionAt (cl);
  7376.       pType->baseType = nType;
  7377.       cl->typeOfSelf = pType;
  7378.       t = checkTypes (cl->typeParms);
  7379.       t = checkTypes (cl->implements);
  7380.       t = checkTypes (cl->superclass);
  7381.       t = checkTypes (cl->fields);
  7382.       t = checkTypes (cl->methodProtos);
  7383.       t = checkTypes (cl->methods);
  7384.       t = checkTypes (cl->next);
  7385.       currentClass = NULL;
  7386.       return NULL;
  7387.  
  7388. //    case BEHAVIOR:                               // in checkTypes
  7389. //      behavior = (Behavior *) node;
  7390. //      printf ("  %s\n", behavior->id->chars);
  7391. //      t = checkTypes (behavior->methods);
  7392. //      t = checkTypes (behavior->next);
  7393. //      return NULL;
  7394.  
  7395.     case TYPE_DEF:                               // in checkTypes
  7396.       typeDef = (TypeDef *) node;
  7397.       // printf ("  %s\n", typeDef->id->chars);
  7398.       t = checkTypes (typeDef->type);
  7399.       // The following check is not really necessary; it is more of a warning...
  7400.       // if (isObjectType (typeDef->type)) {
  7401.       //   error (typeDef, "You may not give classes or interfaces a second name");
  7402.       // }
  7403.       t = checkTypes (typeDef->next);
  7404.       return NULL;
  7405.  
  7406.     case CONST_DECL:                               // in checkTypes
  7407.       constDecl = (ConstDecl *) node;
  7408.       // printf ("  %s\n", constDecl->id->chars);
  7409.       t = checkTypes (constDecl->expr);
  7410.       if (constDecl->expr) {
  7411.         if ((constDecl->expr->op != CHAR_CONST) &&
  7412.             (constDecl->expr->op != INT_CONST) &&
  7413.             (constDecl->expr->op != DOUBLE_CONST) &&
  7414.             (constDecl->expr->op != BOOL_CONST) &&
  7415.             (constDecl->expr->op != NULL_CONST) &&
  7416.             (constDecl->expr->op != STRING_CONST)) {
  7417.           error (node, "Unable to determine the value of this constant at compile-time");
  7418.         }
  7419.       }
  7420.       t = checkTypes (constDecl->next);
  7421.       return NULL;
  7422.  
  7423.     case ERROR_DECL:                               // in checkTypes
  7424.       errorDecl = (ErrorDecl *) node;
  7425.       // printf ("  %s\n", errorDecl->id->chars);
  7426.       t = checkTypes (errorDecl->parmList);
  7427.       t = checkTypes (errorDecl->next);
  7428.       return NULL;
  7429.  
  7430.     case FUNCTION_PROTO:                               // in checkTypes
  7431.       functionProto = (FunctionProto *) node;
  7432.       // printf ("  %s\n", functionProto->id->chars);
  7433.  
  7434.       // Check that the main function is not external and not private...
  7435.       if (functionProto->id == stringMain) {
  7436.         if (functionProto->isPrivate) {
  7437.           error (functionProto, "There is no prototype for the 'main' function in the header file");
  7438.         }
  7439.         if (functionProto->isExternal) {
  7440.           error (functionProto, "The 'main' function must not be 'external'");
  7441.         }
  7442.        }
  7443.  
  7444.       t = checkTypes (functionProto->parmList);
  7445.       t = checkTypes (functionProto->retType);
  7446.       functionProto->retSize = sizeInBytesOfWhole(functionProto->retType,
  7447.                                                   functionProto->retType,
  7448.                                                   0);    // wantPrinting = 0
  7449.       t = checkTypes (functionProto->next);
  7450.       return NULL;
  7451.  
  7452.     case FUNCTION:                               // in checkTypes
  7453.       fun = (Function *) node;
  7454.       // if (fun->id) {
  7455.       //   printf ("    CheckTypes: Within function %s\n", fun->id->chars);
  7456.       // } else {
  7457.       //   printf ("    CheckTypes: Within closure\n");
  7458.       // }
  7459.  
  7460.       // If this is a "main" function...
  7461.       if (fun->id == stringMain) {
  7462.         if (fun->parmList != NULL) {
  7463.           error (fun, "The 'main' function must not have any parameters");
  7464.         }
  7465.         if (! isVoidType (fun->retType)) {
  7466.           error (fun, "The 'main' function must not return a result");
  7467.         }
  7468.         // if (fun->myProto == NULL) {
  7469.         //   error (fun, "There is no prototype for the 'main' function in the header file");
  7470.         // }
  7471.       }
  7472.  
  7473.       // Run through the prototype and make sure that the parameter names and types
  7474.       // match exactly...
  7475.       functionProto = fun->myProto;
  7476.       if (functionProto != NULL) {
  7477.  
  7478.         // Make sure each parameter type matches...
  7479.         protoParm = functionProto->parmList;
  7480.         funParm = fun->parmList;
  7481.         while (1) {
  7482.           if ((protoParm == NULL) && (funParm == NULL)) break;
  7483.           if ((protoParm == NULL) || (funParm == NULL)) {
  7484.             error (fun, "This function does not have the same number of parameters as the corresponding prototype");
  7485.             error2 (functionProto, "Here is the prototype");
  7486.             break;
  7487.           }
  7488.           if (! typesEqual (protoParm->type, funParm->type)) {
  7489.             error (funParm, "The type of this parameter does not match the type of the corresponding parameter in the prototype");
  7490.             error2 (fun, "Here is the function");
  7491.             errorWithType ("The parameter type in the function is", funParm->type);
  7492.             errorWithType ("The parameter type in the function prototype is", protoParm->type);
  7493.           }
  7494.           // Make sure that the parameters have the same names...
  7495.           if (protoParm->id != funParm->id) {
  7496.             error (funParm, "The name of this parameter does not match the name of the corresponding parameter in the function prototype");
  7497.             error2 (fun, "Here is the function");
  7498.             error2 (protoParm, "Here is the name used in the function prototype");
  7499.           }
  7500.           protoParm = (Parameter *) protoParm->next;
  7501.           funParm = (Parameter *) funParm->next;
  7502.         }
  7503.  
  7504.         // Make sure the return types match...
  7505.         if (! typesEqual (fun->retType, functionProto->retType)) {
  7506.           error (fun, "The return type of this function does not match the corresponding prototype");
  7507.           errorWithType ("The return type in the function is", fun->retType);
  7508.           errorWithType ("The return type in the function prototype is", functionProto->retType);
  7509.         }
  7510.       }
  7511.  
  7512.       maxArgBytesSoFar = 0;
  7513.       // printf ("setting maxArgBytesSoFar to zero...\n");
  7514.  
  7515.       t = checkTypes (fun->parmList);
  7516.       t = checkTypes (fun->retType);
  7517.       t = checkTypes (fun->locals);
  7518.       t = checkTypes (fun->stmts);
  7519.  
  7520.       // printf ("Setting fun->maxArgBytes = %d...\n", maxArgBytesSoFar);
  7521.       fun->maxArgBytes = maxArgBytesSoFar;
  7522.       maxArgBytesSoFar = -1;
  7523.  
  7524.       t = checkTypes (fun->next);
  7525.  
  7526.       return NULL;
  7527.  
  7528.     case METHOD_PROTO:                               // in checkTypes
  7529.       methodProto = (MethodProto *) node;
  7530.       // printf ("  %s\n", methodProto->selector->chars);
  7531.  
  7532.       // Check to see if this selector could override a built-in operator.
  7533.       // For example, overriding "+" makes "ptrToObj + xxx" ambiguous.  However,
  7534.       // some methods are okay.  For example, we can have a method for "*" since
  7535.       // "ptrToObj * x" would otherwise be illegal...
  7536.       if (methodProto->kind == PREFIX) {
  7537.         switch (methodProto->selector->primitiveSymbol) {
  7538.           case UNARY_STAR:
  7539.             error (methodProto, "Defining a prefix method with this selector causes confusion with the built-in dereference operator, in '* ptrToObj'");
  7540.             break;
  7541.           case UNARY_BANG:
  7542.             error (methodProto, "Defining a prefix method with this selector causes confusion with a built-in operator in the boolean expression '! ptrToObj'");
  7543.             break;
  7544.           case UNARY_AMP:
  7545.             error (methodProto, "Defining a prefix method with this selector causes confusion with the built-in address-of operator");
  7546.             break;
  7547.         }
  7548.       }
  7549.       if (methodProto->kind == INFIX) {
  7550.         switch (methodProto->selector->primitiveSymbol) {
  7551.           case MINUS:
  7552.             error (methodProto, "Defining an infix method with this selector causes confusion with built-in pointer subtraction in 'ptrToObj - x'");
  7553.             break;
  7554.           case PLUS:
  7555.             error (methodProto, "Defining an infix method with this selector causes confusion with built-in pointer addition in 'ptrToObj + x'");
  7556.             break;
  7557.           case BAR_BAR:
  7558.             error (methodProto, "Defining an infix method with this selector causes confusion with a built-in operator in the boolean expression 'ptrToObj || x'");
  7559.             break;
  7560.           case AMP_AMP:
  7561.             error (methodProto, "Defining an infix method with this selector causes confusion with a built-in operator in the boolean expression 'ptrToObj && x'");
  7562.             break;
  7563.           case EQUAL_EQUAL:
  7564.             error (methodProto, "Defining an infix method with this selector causes confusion with the built-in EQUALS operator");
  7565.             break;
  7566.           case NOT_EQUAL:
  7567.             error (methodProto, "Defining an infix method with this selector causes confusion with the built-in NOT-EQUALS operator");
  7568.             break;
  7569.         }
  7570.       }
  7571.       t = checkTypes (methodProto->parmList);
  7572.       t = checkTypes (methodProto->retType);
  7573.       methodProto->retSize = sizeInBytesOfWhole(methodProto->retType,
  7574.                                                 methodProto->retType,
  7575.                                                 0);    // wantPrinting = 0
  7576.       t = checkTypes (methodProto->next);
  7577.       return NULL;
  7578.  
  7579.     case METHOD:                               // in checkTypes
  7580.       meth = (Method *) node;
  7581.       // printf ("  %s\n", meth->selector->chars);
  7582.  
  7583.       maxArgBytesSoFar = 0;
  7584.  
  7585.       t = checkTypes (meth->parmList);
  7586.       t = checkTypes (meth->retType);
  7587.       t = checkTypes (meth->locals);
  7588.       t = checkTypes (meth->stmts);
  7589.  
  7590.       meth->maxArgBytes = maxArgBytesSoFar;
  7591.       maxArgBytesSoFar = -1;
  7592.  
  7593.       t = checkTypes (meth->next);
  7594.  
  7595.       return NULL;
  7596.  
  7597.     case TYPE_PARM:                               // in checkTypes
  7598.       typeParm = (TypeParm *) node;
  7599.       // Make sure that the constraint type is not a basic type...
  7600.       if (isCharType (typeParm->type) ||
  7601.           isIntType (typeParm->type) ||
  7602.           isBoolType (typeParm->type) ||
  7603.           isDoubleType (typeParm->type) ||
  7604.           isVoidType (typeParm->type) ||
  7605.           isTypeOfNullType (typeParm->type)) {
  7606.         error (typeParm, "The constraint on this type parameter is a basic type; this is meaningless, since this parameter can only be instantiated by that type itself");
  7607.         errorWithType ("The constraint is", typeParm->type);
  7608.       }
  7609.       t = checkTypes (typeParm->type);
  7610.       t = checkTypes (typeParm->next);
  7611.       return NULL;
  7612.  
  7613.     case TYPE_ARG:                               // in checkTypes
  7614.       typeArg = (TypeArg *) node;
  7615.       t = checkTypes (typeArg->type);
  7616.       t = checkTypes (typeArg->next);
  7617.       return NULL;
  7618.  
  7619.     case CHAR_TYPE:                              // in checkTypes
  7620.       return NULL;
  7621.  
  7622.     case INT_TYPE:                               // in checkTypes
  7623.       return NULL;
  7624.  
  7625.     case DOUBLE_TYPE:                            // in checkTypes
  7626.       return NULL;
  7627.  
  7628.     case BOOL_TYPE:                              // in checkTypes
  7629.       return NULL;
  7630.  
  7631.     case VOID_TYPE:                              // in checkTypes
  7632.       return NULL;
  7633.  
  7634.     case TYPE_OF_NULL_TYPE:                      // in checkTypes
  7635.       return NULL;
  7636.  
  7637.     case ANY_TYPE:                               // in checkTypes
  7638.       return NULL;
  7639.  
  7640.     case PTR_TYPE:                               // in checkTypes
  7641.       pType = (PtrType *) node;
  7642.       t = checkTypes (pType->baseType);
  7643.       if (pType->baseType && pType->baseType->op == VOID_TYPE && safe) {
  7644.         error (pType, "Using 'ptr to void' is unsafe; you must compile with the 'unsafe' option if you wish to do this");
  7645.       }
  7646.       return NULL;
  7647.  
  7648.     case ARRAY_TYPE:                             // in checkTypes
  7649.       aType = (ArrayType *) node;
  7650.       t = checkTypes (aType->sizeExpr);
  7651.       if (t && !isIntType (t)) {
  7652.         error (aType, "The array size expression must have type 'int'");
  7653.       }
  7654.       if ((aType->sizeExpr) && (aType->sizeExpr->op != INT_CONST)) {
  7655.         error (aType, "The array size expression must be an integer value determinable at compile-time");
  7656.       }
  7657.       t = checkTypes (aType->baseType);
  7658.       return NULL;
  7659.  
  7660.     case RECORD_TYPE:                               // in checkTypes
  7661.       rType = (RecordType *) node;
  7662.       t = checkTypes (rType->fields);
  7663.       return NULL;
  7664.  
  7665.     case FUNCTION_TYPE:                               // in checkTypes
  7666.       fType = (FunctionType *) node;
  7667.       t = checkTypes (fType->parmTypes);
  7668.       t = checkTypes (fType->retType);
  7669.       setParmSizeInFunctionType (fType);
  7670.       return NULL;
  7671.  
  7672.     case NAMED_TYPE:                               // in checkTypes
  7673.       nType = (NamedType *) node;
  7674.       t = checkTypes (nType->typeArgs);
  7675.       if (nType->myDef != NULL) {
  7676.         switch (nType->myDef->op) {
  7677.  
  7678.           case TYPE_PARM:
  7679.             if (nType->typeArgs) {
  7680.               error (node, "This is the name of a type parameter of this class or interface; this type must not be followed with '[TypeArgs]'");
  7681.             }
  7682.             break;
  7683.  
  7684.           case INTERFACE:
  7685.             interface = (Interface *) nType->myDef;
  7686.             checkTypeInstantiation (nType->typeArgs,
  7687.                                     interface->typeParms,
  7688.                                     interface,
  7689.                                     nType);
  7690.             break;
  7691.  
  7692.           case CLASS_DEF:
  7693.             cl = (ClassDef *) nType->myDef;
  7694.             checkTypeInstantiation (nType->typeArgs,
  7695.                                     cl->typeParms,
  7696.                                     cl,
  7697.                                     nType);
  7698.             break;
  7699.  
  7700.           case TYPE_DEF:
  7701.             if (nType->typeArgs) {
  7702.               error (node, "This is the name of a defined type; this type must not be followed with '[TypeArgs]'");
  7703.               error2 (nType->myDef, "Here is the type definition");
  7704.             }
  7705.             break;
  7706.  
  7707.           default:
  7708.             programLogicError ("NamedType->myDef is an unexpected value");
  7709.         }
  7710.       }
  7711.       return NULL;
  7712.  
  7713.     case IF_STMT:                               // in checkTypes
  7714.       ifStmt = (IfStmt *) node;
  7715.       // t = checkTypes (ifStmt->expr);    // This is done in checkAssignment
  7716.       // Make sure the conditional expression has type boolean...
  7717.       ifStmt->expr = checkAssignment (
  7718.                 ifStmt->expr,
  7719.                 basicBoolType,
  7720.                 "The conditional expression in this IF statement does not have type 'bool'",
  7721.                 NULL);
  7722.       t = checkTypes (ifStmt->thenStmts);
  7723.       t = checkTypes (ifStmt->elseStmts);
  7724.       t = checkTypes (ifStmt->next);
  7725.       return NULL;
  7726.  
  7727.     case ASSIGN_STMT:                               // in checkTypes
  7728.       assignStmt = (AssignStmt *) node;
  7729.       // printf ("\n----------------------  About to process:  ");
  7730.       // pretty (node);
  7731.       // printf ("     The lefthand side is:\n");
  7732.       // printAst (12, assignStmt->lvalue);
  7733.       // printf ("     The righthand side is:\n");
  7734.       // printAst (12, assignStmt->expr);
  7735.       // pretty (checkTypes (assignStmt->expr));
  7736.       t2 = checkTypes (assignStmt->lvalue);
  7737.       if (!isLValue (assignStmt->lvalue)) {
  7738.         error (assignStmt->lvalue, "The lefthand side of this assignment is not an l-value; it is not something that can be assigned to");
  7739.       }
  7740.       assignStmt->sizeInBytes = sizeInBytesOfWhole (t2, node, 0);  // wantPrinting = 0
  7741.       // printf ("    sizeInBytes to be copied is: %d\n", assignStmt->sizeInBytes);
  7742.       // t = checkTypes (assignStmt->expr);    // This is done in checkAssignment
  7743.       // Make sure the RHS expression has the right type...
  7744.       assignStmt->expr = checkAssignment (
  7745.                 assignStmt->expr,
  7746.                 t2,
  7747.                 "The expression on the righthand side of this assignment does not have the correct type",
  7748.                 assignStmt);
  7749.       // printf ("\n     The type of ");
  7750.       // pretty (assignStmt->expr);
  7751.       // printf ("          is ");
  7752.       // pretty (checkTypes (assignStmt->expr));
  7753.       t = checkTypes (assignStmt->next);
  7754.       return NULL;
  7755.  
  7756.     case CALL_STMT:                               // in checkTypes
  7757.       callStmt = (CallStmt *) node;
  7758.       // printf ("\n----------------------  About to process:  ");
  7759.       // pretty (node);
  7760.       t = checkTypes (callStmt->expr);
  7761.       if (!isVoidType (t)) {
  7762.         error (node, "This function returns a value; you must either assign this value to some variable or change the function to return nothing");
  7763.         errorWithType ("Here is the type returned", t);
  7764.       }
  7765.       t = checkTypes (callStmt->next);
  7766.       return NULL;
  7767.  
  7768.     case SEND_STMT:                               // in checkTypes
  7769.       sendStmt = (SendStmt *) node;
  7770.       // printf ("\n----------------------  About to process:  ");
  7771.       // pretty (node);
  7772.       t = checkTypes (sendStmt->expr);
  7773.       if (!isVoidType (t)) {
  7774.         error (node, "This send-statement returns a value; you must either assign this value to some variable or change the method to return nothing");
  7775.         errorWithType ("Here is the type returned", t);
  7776.       }
  7777.       t = checkTypes (sendStmt->next);
  7778.       return NULL;
  7779.  
  7780.     case WHILE_STMT:                               // in checkTypes
  7781.       whileStmt = (WhileStmt *) node;
  7782.       // printf ("\n----------------------  About to process:  ");
  7783.       // pretty (node);
  7784.       // t = checkTypes (whileStmt->expr);  // Done in checkAssignment below...
  7785.       // Make sure the conditional expression has type boolean...
  7786.       whileStmt->expr = checkAssignment (
  7787.                 whileStmt->expr,
  7788.                 basicBoolType,
  7789.                 "The conditional expression in this WHILE statement does not have type 'bool'",
  7790.                 NULL);
  7791.       t = checkTypes (whileStmt->stmts);
  7792.       t = checkTypes (whileStmt->next);
  7793.       return NULL;
  7794.  
  7795.     case DO_STMT:                               // in checkTypes
  7796.       doStmt = (DoStmt *) node;
  7797.       // printf ("\n----------------------  About to process:  ");
  7798.       // pretty (node);
  7799.       t = checkTypes (doStmt->stmts);
  7800.       // t = checkTypes (doStmt->expr);  // Done in checkAssignment below...
  7801.       // Make sure the conditional expression has type boolean...
  7802.       doStmt->expr = checkAssignment (
  7803.                 doStmt->expr,
  7804.                 basicBoolType,
  7805.                 "The conditional expression in 'DO stmts UNTIL expr' does not have type 'bool'",
  7806.                 NULL);
  7807.       t = checkTypes (doStmt->next);
  7808.       return NULL;
  7809.  
  7810.     case BREAK_STMT:                               // in checkTypes
  7811.       breakStmt = (BreakStmt *) node;
  7812.       // printf ("\n----------------------  About to process:  ");
  7813.       // pretty (node);
  7814.       t = checkTypes (breakStmt->next);
  7815.       return NULL;
  7816.  
  7817.     case CONTINUE_STMT:                               // in checkTypes
  7818.       continueStmt = (ContinueStmt *) node;
  7819.       // printf ("\n----------------------  About to process:  ");
  7820.       // pretty (node);
  7821.       t = checkTypes (continueStmt->next);
  7822.       return NULL;
  7823.  
  7824.     case RETURN_STMT:                               // in checkTypes
  7825.       returnStmt = (ReturnStmt *) node;
  7826.       // printf ("\n----------------------  About to process:  ");
  7827.       // pretty (node);
  7828.       // t = checkTypes (returnStmt->expr);   // Checked below in checkAssignment...
  7829.       if (returnStmt->enclosingMethOrFunction) {
  7830.         if (returnStmt->enclosingMethOrFunction->op == METHOD) {
  7831.           meth = (Method *) returnStmt->enclosingMethOrFunction;
  7832.           resultType = meth->retType;
  7833.         } else if (returnStmt->enclosingMethOrFunction->op == FUNCTION) {
  7834.           fun = (Function *) returnStmt->enclosingMethOrFunction;
  7835.           resultType = fun->retType;
  7836.         } else {
  7837.           programLogicError ("NULL retType; we should have void instead");
  7838.         }
  7839.         if (isVoidType (resultType)) {
  7840.           if (returnStmt->expr) {
  7841.             // If problems, resultType will be NULL; isVoid will return true...
  7842.             error (returnStmt->expr, "This method/function does not return a value, yet one is provided in this RETURN statement");
  7843.           }
  7844.         } else {
  7845.           if (returnStmt->expr) {
  7846.             // Make sure the return expression is compatible with the resultType...
  7847.             returnStmt->expr = checkAssignment (
  7848.                       returnStmt->expr,
  7849.                       resultType,
  7850.                       "The value in this RETURN statement does not have the type being returned by this method/function",
  7851.                       NULL);
  7852.             returnStmt->retSize = sizeInBytesOfWhole (resultType, returnStmt, 0);
  7853.           } else {
  7854.             programLogicError ("Checked during parsing");
  7855.             error (returnStmt->expr, "This method/function returns a value, yet none is provided in this RETURN statement");
  7856.           }
  7857.         }
  7858.       }
  7859.       t = checkTypes (returnStmt->next);
  7860.       return NULL;
  7861.  
  7862.     case FOR_STMT:                               // in checkTypes
  7863.       forStmt = (ForStmt *) node;
  7864.       //   printf ("\n----------------------  About to process:  ");
  7865.       //   pretty (node);
  7866.       t2 = checkTypes (forStmt->lvalue);
  7867.       if (isPtrType (t2)) {
  7868.         if (safe) {
  7869.           error (forStmt->lvalue, "Using a ptr as an index in a FOR statement is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  7870.         }
  7871.       } else if (!isIntType (t2)) {
  7872.         error (forStmt->lvalue, "The index of this FOR statement must have type 'int'");
  7873.       }
  7874.       if (!isLValue (forStmt->lvalue)) {
  7875.         error (forStmt->lvalue, "The index of this FOR statement is not an l-value; it is not something that can be assigned to");
  7876.       }
  7877.       if (!isPtrType (t2) || !isPtrType (checkTypes (forStmt->expr1))) {
  7878.         forStmt->expr1 = checkAssignment (
  7879.                 forStmt->expr1,
  7880.                 basicIntType,
  7881.                 "The starting value in this FOR statement does not have the correct type",
  7882.                 NULL);
  7883.       }
  7884.       if (!isPtrType (t2) || !isPtrType (checkTypes (forStmt->expr2))) {
  7885.         forStmt->expr2= checkAssignment (
  7886.                 forStmt->expr2,
  7887.                 basicIntType,
  7888.                 "The stopping value in this FOR statement does not have the correct type",
  7889.                 NULL);
  7890.       }
  7891.       // t = checkTypes (forStmt->expr3);  // Checked below in checkAssignment
  7892.       forStmt->expr3 = checkAssignment (
  7893.                 forStmt->expr3,
  7894.                 basicIntType,
  7895.                 "The increment value in this FOR statement does not have the correct type",
  7896.                 NULL);
  7897.       intConst = (IntConst *) forStmt->expr3;
  7898.       if (intConst &&
  7899.           (intConst->op == INT_CONST) &&
  7900.           (intConst->ivalue < 1)) {
  7901.         error (forStmt->expr3, "The step expression in this FOR loop is negative");
  7902.       }
  7903.       t = checkTypes (forStmt->stmts);
  7904.       t = checkTypes (forStmt->next);
  7905.       return NULL;
  7906.  
  7907.     case SWITCH_STMT:                               // in checkTypes
  7908.       switchStmt = (SwitchStmt *) node;
  7909.       // printf ("\n----------------------  About to process:  ");
  7910.       // pretty (node);
  7911.       // t = checkTypes (switchStmt->expr);
  7912.       switchStmt->expr = checkAssignment (
  7913.                 switchStmt->expr,
  7914.                 basicIntType,
  7915.                 "The expression in this SWITCH statement must have type 'int'",
  7916.                 NULL);
  7917.       // Run through the case clauses and process them...
  7918.       numberOfCases = 0;
  7919.       for (cas = switchStmt->caseList; cas != NULL; cas = cas->next) {
  7920.         numberOfCases = numberOfCases + 1;
  7921.         // t = checkTypes (cas->expr);
  7922.         cas->expr = checkAssignment (
  7923.                   cas->expr,
  7924.                   basicIntType,
  7925.                   "The expression following CASE must have type 'int'",
  7926.                   NULL);
  7927.         cas->expr = (Expression *) evalExprsIn (cas->expr);
  7928.         if (cas->expr->op != INT_CONST) {
  7929.           error (cas->expr, "The value following CASE must be an integer whose value can be determined at compile-time");
  7930.         } else {
  7931.           cas->ivalue = ((IntConst *) (cas->expr))->ivalue;
  7932.           // printf (" cas->ivalue = %d\n", cas->ivalue);
  7933.           if ((cas->ivalue) > (switchStmt->highValue)) {
  7934.             // printf (" Setting high...\n");
  7935.             switchStmt->highValue = cas->ivalue;
  7936.           }
  7937.           if (cas->ivalue < switchStmt->lowValue) {
  7938.             // printf (" Setting low...\n");
  7939.             switchStmt->lowValue = cas->ivalue;
  7940.           }
  7941.         }
  7942.         t = checkTypes (cas->stmts);
  7943.       }
  7944.  
  7945.       // Next, check to make sure we have no duplicate values.
  7946.       // Create a hash table of ptrs to CASE nodes.
  7947.       arSize = numberOfCases * 2 + 1;    // Make it twice as big & at least 1.
  7948.       caseArray = (Case * *) calloc (4, arSize);
  7949.       for (cas = switchStmt->caseList; cas; cas = cas->next) {
  7950.         i = cas->ivalue;
  7951.         if (i<0) {
  7952.           j = (-i) % arSize;
  7953.         } else {
  7954.           j = i % arSize;
  7955.         }
  7956.         while (caseArray [j] != NULL) {
  7957.           if (caseArray [j] -> ivalue == i) {
  7958.             error (caseArray [j], "This CASE clause has the same value as some other CASE in this SWITCH");
  7959.             error2 (cas, "Here is another CASE clause with the same value");
  7960.             break;
  7961.           }
  7962.           j = (j + 1) % arSize;
  7963.         }
  7964.         if (caseArray [j] == NULL) {
  7965.           caseArray [j] = cas;
  7966.         }
  7967.       }
  7968.       // Print the array...
  7969.       // for (j = 0; j < arSize; j++) {
  7970.       //   if (caseArray[j] == NULL) {
  7971.       //     printf ("         j= %d       caseArray[j]->ivalue= NULL\n", j);
  7972.       //   } else {
  7973.       //     printf ("         j= %d       caseArray[j]->ivalue= %d\n",
  7974.       //             j, caseArray [j] -> ivalue);
  7975.       //   }
  7976.       // }
  7977.       delete caseArray;
  7978.  
  7979.       t = checkTypes (switchStmt->defaultStmts);
  7980.       t = checkTypes (switchStmt->next);
  7981.       return NULL;
  7982.  
  7983.     case TRY_STMT:                               // in checkTypes
  7984.       tryStmt = (TryStmt *) node;
  7985.       // printf ("\n----------------------  About to process:  ");
  7986.       // pretty (node);
  7987.       t = checkTypes (tryStmt->stmts);
  7988.       t = checkTypes (tryStmt->catchList);
  7989.       // Run thru the catch clauses and make sure each is different...
  7990.       tempMap = new Mapping <String, AstNode> (5, NULL);
  7991.       for (cat = tryStmt->catchList; cat; cat = cat->next) {
  7992.         def = tempMap->find (cat->id);
  7993.         if (def) {
  7994.           error (cat, "This CATCH clause catches the same error as some other CATCH in this TRY statement");
  7995.             error2 (def, "Here is another CATCH clause for the same error");
  7996.         } else {
  7997.           tempMap->enter (cat->id, cat);
  7998.         }
  7999.       }
  8000.       delete tempMap;
  8001.       if (tryStmt->catchList == NULL) {
  8002.         error (tryStmt, "This TRY statement has no CATCH clauses; either eliminate 'try' and 'endTry' or add some CATCH clauses");
  8003.       }
  8004.       t = checkTypes (tryStmt->next);
  8005.       return NULL;
  8006.  
  8007.     case THROW_STMT:                               // in checkTypes
  8008.       throwStmt = (ThrowStmt *) node;
  8009.       // printf ("\n----------------------  About to process:  ");
  8010.       // pretty (node);
  8011.       // t = checkTypes (throwStmt->argList);  // Done within checkArgList...
  8012.       if (throwStmt->myDef) {
  8013.         checkArgList (throwStmt->argList,
  8014.                       throwStmt->myDef->parmList,
  8015.                       throwStmt->myDef,
  8016.                       throwStmt);
  8017.         updateMaxArgBytes (throwStmt->myDef->totalParmSize);
  8018.       }
  8019.       t = checkTypes (throwStmt->next);
  8020.       return NULL;
  8021.  
  8022.     case FREE_STMT:                               // in checkTypes
  8023.       freeStmt = (FreeStmt *) node;
  8024.       // printf ("\n----------------------  About to process:  ");
  8025.       // pretty (node);
  8026.       t = checkTypes (freeStmt->expr);
  8027.       if (!isPtrType (t)) {
  8028.         error (freeStmt->expr, "The expression in this FREE statement is not a pointer");
  8029.       }
  8030.       if (safe) {
  8031.         error (node, "Using the FREE statement is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  8032.       }
  8033.       t = checkTypes (freeStmt->next);
  8034.       return NULL;
  8035.  
  8036.     case DEBUG_STMT:                               // in checkTypes
  8037.       debugStmt = (DebugStmt *) node;
  8038.       // printf ("\n----------------------  About to process:  ");
  8039.       // pretty (node);
  8040.       t = checkTypes (debugStmt->next);
  8041.       return NULL;
  8042.  
  8043.     case CASE:                                // in checkTypes
  8044.       programLogicError ("This is handled in SWITCH_STMT");
  8045.       return NULL;
  8046.  
  8047.     case CATCH:                               // in checkTypes
  8048.       cat = (Catch *) node;
  8049.       t = checkTypes (cat->parmList);
  8050.       // Take a look at the errorDecl...
  8051.       if (cat->myDef) {
  8052.         // Make sure each parm type matches according to contra-variance...
  8053.         protoParm = cat->myDef->parmList;
  8054.         subParm = cat->parmList;
  8055.         while (1) {
  8056.           if ((protoParm == NULL) && (subParm == NULL)) break;
  8057.           if ((protoParm == NULL) || (subParm == NULL)) {
  8058.             error (cat, "This catch does not have the same number of parameters as the corresponding error declaration");
  8059.             error2 (cat->myDef, "Here is the error declaration");
  8060.             break;
  8061.           }
  8062.           if (! assignable (subParm->type, protoParm->type)) {
  8063.             error (subParm, "The type of this parameter fails to match the type of the corresponding parameter in the error declaration (perhaps it is not general enough)");
  8064.             error2 (cat->myDef, "Here is the error declaration");
  8065.             errorWithType ("The type of this parameter in the error declaration is",
  8066.                            protoParm->type);
  8067.             errorWithType ("The type of this parameter in the catch clause is",
  8068.                            subParm->type);
  8069.           }
  8070.           protoParm = (Parameter *) protoParm->next;
  8071.           subParm = (Parameter *) subParm->next;
  8072.         }
  8073.       }
  8074.       t = checkTypes (cat->stmts);
  8075.       // At this point the "offset"s have been assigned sequentially; these
  8076.       // args will be pushed using these offsets during a throw.  Go through
  8077.       // the parms and copy all offsets into the "throwSideOffset"s.
  8078.       for (parm = cat->parmList; parm; parm = (Parameter *) parm->next) {
  8079.         parm->throwSideOffset = parm->offset;
  8080.       }
  8081.  
  8082. /**********
  8083.       // Now add all the parameters here to the list of LOCALS for this function
  8084.       // or method.  From now on, they'll be treated as locals.
  8085.  
  8086. This is a bad idea.  It makes it impossible to walk the list of parameters for
  8087. a catch stmt; we just keep going and hit other stuff in the list.
  8088.  
  8089.       printf ("Processing catch %s...\n", cat->id->chars);
  8090.       if (cat->parmList) {
  8091.         lastParm = cat->parmList;
  8092.         while (1)  {
  8093.           lastParm->throwSideOffset = lastParm->offset;
  8094.           printf ("  Processing parm %s   offset=%d   throwSideOffset=%d\n",
  8095.                   lastParm->id->chars,
  8096.                   lastParm->offset,
  8097.                   lastParm->throwSideOffset);
  8098.           if (lastParm->next == NULL) break;
  8099.           lastParm = (Parameter *) (lastParm->next);
  8100.         }
  8101.         if (cat->enclosingMethOrFunction->op = FUNCTION) {
  8102.           fun = (Function *) (cat->enclosingMethOrFunction);
  8103.           lastParm->next = fun->locals;
  8104.           fun->locals = (Local *) cat->parmList;
  8105.         } else if (cat->enclosingMethOrFunction->op = METHOD) {
  8106.           meth = (Method *) (cat->enclosingMethOrFunction);
  8107.           lastParm->next = meth->locals;
  8108.           meth->locals = (Local *) cat->parmList;
  8109.         } else {
  8110.           programLogicError ("cat->enclosingMethOrFunction is not FUNCTION or METHOD");
  8111.         }
  8112.       }
  8113. **********/
  8114.  
  8115.  
  8116.       t = checkTypes (cat->next);
  8117.       return NULL;
  8118.  
  8119.     case GLOBAL:                               // in checkTypes
  8120.       global = (Global *) node;
  8121.       // printf ("GLOBAL %s\n", global->id->chars);
  8122.       t2 = checkTypes (global->type);
  8123.       // t = checkTypes (global->initExpr);    // done in checkAssignment
  8124.       // First, check the expression to make sure it is static...
  8125.       // Make sure the initializing expression (if any) has the correct type...
  8126.       if (global->initExpr) {
  8127.         global->initExpr = checkAssignment (
  8128.                 global->initExpr,
  8129.                 global->type,
  8130.                 "The initializing expression does not have the correct type",
  8131.                 NULL);
  8132.       }
  8133.       global->initExpr = (Expression *) evalExprsIn (global->initExpr);
  8134.       checkStaticData (global->initExpr, global);
  8135.       t = checkTypes (global->next);
  8136.       return t2;
  8137.  
  8138.     case LOCAL:                               // in checkTypes
  8139.       local = (Local *) node;
  8140.       t = checkTypes (local->type);
  8141.       local->sizeInBytes = sizeInBytesOfWhole (local->type, local, 1);
  8142.       // t2 = checkTypes (local->initExpr);    // done in checkAssignment
  8143.       // Make sure the initializing expression (if any) has the correct type...
  8144.       if (local->initExpr) {
  8145.         local->initExpr = checkAssignment (
  8146.                 local->initExpr,
  8147.                 local->type,
  8148.                 "The initializing expression does not have the correct type",
  8149.                 NULL);
  8150.       }
  8151.       t = checkTypes (local->next);
  8152.       return NULL;
  8153.  
  8154.     case PARAMETER:                               // in checkTypes
  8155.       parm = (Parameter *) node;
  8156.       t = checkTypes (parm->type);
  8157.       parm->sizeInBytes = sizeInBytesOfWhole (parm->type, parm, 1);
  8158.       t = checkTypes (parm->next);
  8159.       return NULL;
  8160.  
  8161.     case CLASS_FIELD:                               // in checkTypes
  8162.       classField = (ClassField *) node;
  8163.       t = checkTypes (classField->type);
  8164.       t = checkTypes (classField->next);
  8165.       return NULL;
  8166.  
  8167.     case RECORD_FIELD:                               // in checkTypes
  8168.       recordField = (RecordField *) node;
  8169.       t = checkTypes (recordField->type);
  8170.       t = checkTypes (recordField->next);
  8171.       return NULL;
  8172.  
  8173.     case INT_CONST:                               // in checkTypes
  8174.       return basicIntType;
  8175.  
  8176.     case DOUBLE_CONST:                               // in checkTypes
  8177.       doubleConst = (DoubleConst *) node;
  8178.       linkDouble (doubleConst);
  8179.       return basicDoubleType;
  8180.  
  8181.     case CHAR_CONST:                               // in checkTypes
  8182.       return basicCharType;
  8183.  
  8184.     case STRING_CONST:                               // in checkTypes
  8185.       stringConst = (StringConst *) node;
  8186.       if (stringConst->nameOfConstant == NULL) {
  8187.         stringConst->next = stringList;
  8188.         stringList = stringConst;
  8189.         stringConst->nameOfConstant = newName ("StringConst");
  8190.       }
  8191.       return basicCharArrayPtrType;
  8192.  
  8193.     case BOOL_CONST:                               // in checkTypes
  8194.       return basicBoolType;
  8195.  
  8196.     case NULL_CONST:                               // in checkTypes
  8197.       return basicTypeOfNullType;
  8198.  
  8199.  
  8200.  
  8201.     case CALL_EXPR:                               // in checkTypes
  8202.       callExpr = (CallExpr *) node;
  8203.         // printf ("callExpr->id = %s\n", callExpr->id->chars);
  8204.         // printf ("callExpr->id->primitiveSymbol = %s\n",
  8205.         // symbolName (callExpr->id->primitiveSymbol));
  8206.  
  8207.       // Identify primitive functions, and check their types...
  8208.       switch (callExpr->id->primitiveSymbol) {
  8209.  
  8210.         // Check for primitive functions...
  8211.  
  8212.         case INT_TO_DOUBLE:                      // in checkTypes for CALL_EXPR...
  8213.           if (argCount (callExpr->argList) == 1) {
  8214.             callExpr->argList->expr = checkAssignment (
  8215.                 callExpr->argList->expr,
  8216.                 basicIntType,
  8217.                 "Primitive INT_TO_DOUBLE expects its argument to be of type int",
  8218.                 NULL);
  8219.             callExpr->primitiveSymbol = PRIMITIVE_INT_TO_DOUBLE;
  8220.           } else {
  8221.             error (callExpr, "Primitive INT_TO_DOUBLE expects exactly one argument");
  8222.           }
  8223.           // updateMaxArgBytes (8); // allocate frame space, in case we insert a real call
  8224.           return basicDoubleType;
  8225.  
  8226.        case DOUBLE_TO_INT:                      // in checkTypes for CALL_EXPR...
  8227.           if (argCount (callExpr->argList) == 1) {
  8228.             callExpr->argList->expr = checkAssignment (
  8229.                 callExpr->argList->expr,
  8230.                 basicDoubleType,
  8231.                 "Primitive DOUBLE_TO_INT expects its argument to be of type double",
  8232.                 NULL);
  8233.             callExpr->primitiveSymbol = PRIMITIVE_DOUBLE_TO_INT;
  8234.           } else {
  8235.             error (callExpr, "Primitive DOUBLE_TO_INT expects exactly one argument");
  8236.           }
  8237.           // updateMaxArgBytes (8); // allocate frame space, in case we insert a real call
  8238.           return basicIntType;
  8239.  
  8240.        case INT_TO_CHAR:                      // in checkTypes for CALL_EXPR...
  8241.           if (argCount (callExpr->argList) == 1) {
  8242.             callExpr->argList->expr = checkAssignment (
  8243.                 callExpr->argList->expr,
  8244.                 basicIntType,
  8245.                 "Primitive INT_TO_CHAR expects its argument to be of type int",
  8246.                 NULL);
  8247.             callExpr->primitiveSymbol = PRIMITIVE_INT_TO_CHAR;
  8248.           } else {
  8249.             error (callExpr, "Primitive INT_TO_CHAR expects exactly one argument");
  8250.           }
  8251.           // updateMaxArgBytes (4); // allocate frame space, in case we insert a real call
  8252.           return basicCharType;
  8253.  
  8254.        case CHAR_TO_INT:                      // in checkTypes for CALL_EXPR...
  8255.           if (argCount (callExpr->argList) == 1) {
  8256.             callExpr->argList->expr = checkAssignment (
  8257.                 callExpr->argList->expr,
  8258.                 basicCharType,
  8259.                 "Primitive CHAR_TO_INT expects its argument to be of type char",
  8260.                 NULL);
  8261.             callExpr->primitiveSymbol = PRIMITIVE_CHAR_TO_INT;
  8262.           } else {
  8263.             error (callExpr, "Primitive CHAR_TO_INT expects exactly one argument");
  8264.           }
  8265.           // updateMaxArgBytes (4); // allocate frame space, in case we insert a real call
  8266.           return basicIntType;
  8267.  
  8268.        case PTR_TO_BOOL:                      // in checkTypes for CALL_EXPR...
  8269.           if (argCount (callExpr->argList) == 1) {
  8270.             callExpr->argList->expr = checkAssignment (
  8271.                 callExpr->argList->expr,
  8272.                 basicAnyPtrType,
  8273.                 "Primitive PTR_TO_BOOL expects its argument to be of type ptr",
  8274.                 NULL);
  8275.             callExpr->primitiveSymbol = PRIMITIVE_PTR_TO_BOOL;
  8276.           } else {
  8277.             error (callExpr, "Primitive PTR_TO_BOOL expects exactly one argument");
  8278.           }
  8279.           // updateMaxArgBytes (4); // allocate frame space, in case we insert a real call
  8280.           return basicBoolType;
  8281.  
  8282.        case POS_INF:                      // in checkTypes for CALL_EXPR...
  8283.           programLogicError ("POS_INF was eliminated in evalExprs");
  8284.           // if (argCount (callExpr->argList) != 0) {
  8285.           //   error (callExpr, "Primitive POS_INF expects no arguments");
  8286.           // }
  8287.           // callExpr->primitiveSymbol = POS_INF;
  8288.           // updateMaxArgBytes (8); // allocate frame space, in case we insert a real call
  8289.           // return basicDoubleType;
  8290.  
  8291.        case NEG_INF:                      // in checkTypes for CALL_EXPR...
  8292.           programLogicError ("NEG_INF was eliminated in evalExprs");
  8293.           // if (argCount (callExpr->argList) != 0) {
  8294.           //   error (callExpr, "Primitive NEG_INF expects no arguments");
  8295.           // }
  8296.           // callExpr->primitiveSymbol = NEG_INF;
  8297.           // updateMaxArgBytes (8); // allocate frame space, in case we insert a real call
  8298.           // return basicDoubleType;
  8299.  
  8300.        case NEG_ZERO:                      // in checkTypes for CALL_EXPR...
  8301.           programLogicError ("NEG_ZERO was eliminated in evalExprs");
  8302.           // if (argCount (callExpr->argList) != 0) {
  8303.           //   error (callExpr, "Primitive NEG_ZERO expects no arguments");
  8304.           // }
  8305.           // callExpr->primitiveSymbol = NEG_ZERO;
  8306.           // updateMaxArgBytes (8); // allocate frame space, in case we insert a real call
  8307.           // return basicDoubleType;
  8308.  
  8309.        case I_IS_ZERO:                      // in checkTypes for CALL_EXPR...
  8310.           if (argCount (callExpr->argList) == 1) {
  8311.             callExpr->argList->expr = checkAssignment (
  8312.                 callExpr->argList->expr,
  8313.                 basicIntType,
  8314.                 "Primitive I_IS_ZERO expects its argument to be of type int",
  8315.                 NULL);
  8316.             callExpr->primitiveSymbol = PRIMITIVE_I_IS_ZERO;
  8317.           } else {
  8318.             error (callExpr, "Primitive I_IS_ZERO expects exactly one argument");
  8319.           }
  8320.           // updateMaxArgBytes (4); // allocate frame space, in case we insert a real call
  8321.           return basicBoolType;
  8322.  
  8323.        case I_NOT_ZERO:                      // in checkTypes for CALL_EXPR...
  8324.           if (argCount (callExpr->argList) == 1) {
  8325.             callExpr->argList->expr = checkAssignment (
  8326.                 callExpr->argList->expr,
  8327.                 basicIntType,
  8328.                 "Primitive I_NOT_ZERO expects its argument to be of type int",
  8329.                 NULL);
  8330.             callExpr->primitiveSymbol = PRIMITIVE_I_NOT_ZERO;
  8331.           } else {
  8332.             error (callExpr, "Primitive I_NOT_ZERO expects exactly one argument");
  8333.           }
  8334.           // updateMaxArgBytes (4); // allocate frame space, in case we insert a real call
  8335.           return basicBoolType;
  8336.  
  8337.         default:
  8338.           // Continue below, checking for user-defined functions...
  8339.           break;
  8340.       }
  8341.  
  8342.       if (callExpr->myDef) {
  8343.         if ((callExpr->myDef->op == LOCAL) ||
  8344.             (callExpr->myDef->op == GLOBAL) ||
  8345.             (callExpr->myDef->op == PARAMETER) ||
  8346.             (callExpr->myDef->op == CLASS_FIELD)) {
  8347.           varDecl = (Local *) callExpr->myDef;
  8348.           fType = getFunctionType (varDecl->type);
  8349.           if (fType != NULL) {
  8350.             // Make sure each arg type matches the corresponding parm type...
  8351.             checkArgList2 (callExpr->argList,
  8352.                           fType->parmTypes,
  8353.                           fType,
  8354.                           callExpr);
  8355.             // Next line untested
  8356.             callExpr->retSize = sizeInBytesOfWhole (fType->retType,
  8357.                                                     fType->retType,
  8358.                                                     0);    // wantPrinting = 0
  8359.             updateMaxArgBytes (fType->totalParmSize);  // includes return value
  8360.             return fType->retType;
  8361.           } else {
  8362.             error (callExpr, "The thing you are invoking here does not have type 'ptr to function'");
  8363.             error2 (varDecl, "Here is its definition");
  8364.             return NULL;
  8365.           }
  8366.         } else if (callExpr->myDef->op == FUNCTION_PROTO) {
  8367.           functionProto = (FunctionProto *) callExpr->myDef;
  8368.           // Make sure each arg type matches the corresponding parm type...
  8369.           checkArgList (callExpr->argList,
  8370.                         functionProto->parmList,
  8371.                         functionProto,
  8372.                         callExpr);
  8373.           // printf ("Calling updateMaxArgBytes (%d) -- Function %s\n",
  8374.           //         functionProto->totalParmSize, functionProto->id->chars);
  8375.           updateMaxArgBytes (functionProto->totalParmSize);
  8376.           callExpr->retSize = sizeInBytesOfWhole (functionProto->retType,
  8377.                                                  functionProto->retType,
  8378.                                                  0);    // wantPrinting = 0
  8379.           updateMaxArgBytes (callExpr->retSize);
  8380.           return functionProto->retType;
  8381.         } else {
  8382.           programLogicError ("Already checked that callExpr->myDef was the right sort of thing");
  8383.         }
  8384.  
  8385.       } else {
  8386.         error (callExpr, "There is no function with this name (nor is there a variable with this name known at this point)");
  8387.         return basicVoidType;
  8388.       }
  8389.  
  8390.  
  8391.  
  8392.     case SEND_EXPR:                               // in checkTypes
  8393.       sendExpr = (SendExpr *) node;
  8394.  
  8395.       //    printf ("\nPROCESSING SEND EXPR ======>  ");
  8396.       //    pretty (sendExpr);
  8397.  
  8398.       // If the recvr is "super"...
  8399.       if (sendExpr->receiver->op == SUPER_EXPR) {
  8400.         recvrIsSuper = 1;
  8401.  
  8402.       // Else, if the recvr is "*super"...
  8403.       } else if ((sendExpr->receiver->op == SEND_EXPR) &&
  8404.                  (((SendExpr *) sendExpr->receiver)->selector->primitiveSymbol ==
  8405.                                                           UNARY_STAR) &&
  8406.                  (((SendExpr *) sendExpr->receiver)->receiver->op == SUPER_EXPR)) {
  8407.           error (sendExpr->receiver,
  8408.                  "Dereferencing super is not allowed; either use '* self' or use super directly, as in 'super.meth (x)' or 'super at: x put: y' or 'super ++ x'");
  8409.           return NULL;
  8410.  
  8411.       } else {
  8412.         recvrIsSuper = 0;
  8413.       }
  8414.  
  8415.       // Determine the type of the receiver expression...
  8416.       if (recvrIsSuper) {
  8417.         if (currentClass == NULL) {
  8418.           error (sendExpr->receiver,
  8419.                  "Super may only be used within a method, not within a function");
  8420.         } else {
  8421.           t = currentClass->typeOfSelf;
  8422.         }
  8423.       } else {
  8424.         t = checkTypes (sendExpr->receiver);
  8425.       }
  8426.       t = resolveNamedType (t);
  8427.       if (t == NULL) return NULL;
  8428.  
  8429.       // printf ("Processing sendExpr = ");
  8430.       // pretty (sendExpr);
  8431.       // printf ("receiver type = ");
  8432.       // pretty (t);
  8433.       // printf ("Processing sendExpr...\n");
  8434.       // printAst (8, sendExpr);
  8435.  
  8436.       // This will be set if we have "*any".  If any doesn't understand prefix *,
  8437.       // then we'll print out a special error message such as "deref is invalid".
  8438.       looksLikeDeref = 0;
  8439.  
  8440.       // See if we are dealing with a primitive message, such as "+"...
  8441.       switch (sendExpr->selector->primitiveSymbol) {
  8442.  
  8443.         // Check for primitive messages...
  8444.  
  8445.         case PLUS:                            // in checkTypes for SEND_EXPR...
  8446.           resultType = checkForPrimitive (sendExpr, t, PRIMITIVE_I_ADD, PRIMITIVE_D_ADD);
  8447.           if (resultType) return resultType;
  8448.           // Check for the special case of ptr+int...
  8449.           if (isPtrType (t)) {
  8450.             if (argCount (sendExpr->argList) == 1) {
  8451.               t2 = checkTypes (sendExpr->argList->expr);
  8452.               if (isIntType (t2)) {
  8453.                 if (safe) {
  8454.                   error (sendExpr, "Adding ptrs to ints is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  8455.                 }
  8456.                 sendExpr->primitiveSymbol = PRIMITIVE_I_ADD;
  8457.                 return t;
  8458.               } else {
  8459.                 error (sendExpr, "This built-in operator expects the right operand to be an int");
  8460.                 return t;
  8461.               }
  8462.             }
  8463.           }
  8464.       break;
  8465.  
  8466.         case MINUS:                            // in checkTypes for SEND_EXPR...
  8467.           resultType = checkForPrimitive (sendExpr, t, PRIMITIVE_I_SUB, PRIMITIVE_D_SUB);
  8468.           if (resultType) return resultType;
  8469.           // Check for the special case of ptr-int or ptr-ptr...
  8470.           if (isPtrType (t)) {
  8471.             if (argCount (sendExpr->argList) == 1) {
  8472.               t2 = checkTypes (sendExpr->argList->expr);
  8473.               if (isIntType (t2)) {
  8474.                 if (safe) {
  8475.                   error (sendExpr, "Subtracting an int from a ptr is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  8476.                 }
  8477.                 sendExpr->primitiveSymbol = PRIMITIVE_I_SUB;
  8478.                 return t;
  8479.               } else if (isPtrType (t2)) {
  8480.                 if (safe) {
  8481.                   error (sendExpr, "Subtracting a ptr from a ptr is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  8482.                 }
  8483.                 sendExpr->primitiveSymbol = PRIMITIVE_I_SUB;
  8484.                 return basicIntType;
  8485.               } else {
  8486.                 error (sendExpr, "This built-in operator expects the right operand to be an int");
  8487.                 return t;
  8488.               }
  8489.             }
  8490.           }
  8491.       break;
  8492.  
  8493.         case UNARY_MINUS:                            // in checkTypes for SEND_EXPR...
  8494.           // Check for the special case of -char, -int, or -double...
  8495.           if (argCount (sendExpr->argList) == 0) {
  8496.             if (isIntType (t)) {
  8497.               sendExpr->primitiveSymbol = PRIMITIVE_I_NEG;
  8498.               return t;
  8499.             } else if (isDoubleType (t)) {
  8500.               sendExpr->primitiveSymbol = PRIMITIVE_D_NEG;
  8501.               return t;
  8502.             } else if (isCharType (t)) {
  8503.               sendExpr->receiver = insertCharToInt (sendExpr->receiver);
  8504.               sendExpr->primitiveSymbol = PRIMITIVE_I_NEG;
  8505.               return basicIntType;
  8506.             }
  8507.           }
  8508.       break;
  8509.  
  8510.         case UNARY_STAR:                            // in checkTypes for SEND_EXPR...
  8511.           looksLikeDeref = 1;
  8512.           pType = getPtrType (t);
  8513.           if (pType) {
  8514.             sendExpr->primitiveSymbol = PRIMITIVE_DEREF;
  8515.             return pType->baseType;
  8516.           }
  8517.       break;
  8518.  
  8519.         case STAR:                            // in checkTypes for SEND_EXPR...
  8520.           resultType = checkForPrimitive (sendExpr, t, PRIMITIVE_I_MUL, PRIMITIVE_D_MUL);
  8521.           if (resultType) return resultType;
  8522.       break;
  8523.  
  8524.         case SLASH:                            // in checkTypes for SEND_EXPR...
  8525.           resultType = checkForPrimitive (sendExpr, t, PRIMITIVE_I_DIV, PRIMITIVE_D_DIV);
  8526.           if (resultType) return resultType;
  8527.       break;
  8528.  
  8529.         case PERCENT:                            // in checkTypes for SEND_EXPR...
  8530.           resultType = checkForPrimitive2 (sendExpr, t, PRIMITIVE_I_REM);
  8531.           if (resultType) return resultType;
  8532.       break;
  8533.  
  8534.         case LESS_LESS:                            // in checkTypes for SEND_EXPR...
  8535.           resultType = checkForPrimitive2 (sendExpr, t, PRIMITIVE_I_SLL);
  8536.           if (resultType) return resultType;
  8537.       break;
  8538.  
  8539.         case GREATER_GREATER:                       // in checkTypes for SEND_EXPR...
  8540.           resultType = checkForPrimitive2 (sendExpr, t, PRIMITIVE_I_SRA);
  8541.           if (resultType) return resultType;
  8542.       break;
  8543.  
  8544.         case GREATER_GREATER_GREATER:                // in checkTypes for SEND_EXPR...
  8545.           resultType = checkForPrimitive2 (sendExpr, t, PRIMITIVE_I_SRL);
  8546.           if (resultType) return resultType;
  8547.       break;
  8548.  
  8549.         case BAR:                            // in checkTypes for SEND_EXPR...
  8550.           resultType = checkForPrimitive2 (sendExpr, t, PRIMITIVE_I_OR);
  8551.           if (resultType) return resultType;
  8552.       break;
  8553.  
  8554.         case CARET:                            // in checkTypes for SEND_EXPR...
  8555.           resultType = checkForPrimitive2 (sendExpr, t, PRIMITIVE_I_XOR);
  8556.           if (resultType) return resultType;
  8557.       break;
  8558.  
  8559.         case UNARY_AMP:                            // in checkTypes for SEND_EXPR...
  8560.           if (sendExpr->receiver->op == VARIABLE_EXPR) {
  8561.             var = (VariableExpr *) sendExpr->receiver;
  8562.             functionProto = (FunctionProto *) var->myDef;
  8563.             if ((functionProto != NULL) &&
  8564.                 (functionProto->op == FUNCTION_PROTO)) {
  8565.               error (sendExpr, "Taking the address of a function is not allowed; just use the function name directly and a 'ptr to function' will be understood");
  8566.             }
  8567.           }
  8568.           if (isLValue (sendExpr->receiver)) {
  8569.             sendExpr->primitiveSymbol = PRIMITIVE_ADDRESS_OF;
  8570.             pType = new PtrType ();
  8571.             pType->positionAt (sendExpr);
  8572.             pType->baseType = t;
  8573.             // If we are compiling with "safe"
  8574.             if (safe) {
  8575.               if (sendExpr->receiver->op == FIELD_ACCESS) {
  8576.                 error (sendExpr, "Taking the address of field within a record or object is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  8577.               }
  8578.               if (sendExpr->receiver->op == ARRAY_ACCESS) {
  8579.                 error (sendExpr, "Taking the address of an element within an array is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  8580.               }
  8581.               if (sendExpr->receiver->op == VARIABLE_EXPR) {
  8582.                 var = (VariableExpr *) sendExpr->receiver;
  8583.                 varDecl = (VarDecl *) var->myDef;
  8584.                 if ((varDecl != NULL) &&
  8585.                     (varDecl->op != GLOBAL)) {
  8586.                   error (sendExpr, "Taking the address of a non-global variable is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  8587.                 }
  8588.               }
  8589.             }
  8590.             return pType;
  8591.           }
  8592.       break;
  8593.  
  8594.         case AMP:                            // in checkTypes for SEND_EXPR...
  8595.           resultType = checkForPrimitive2 (sendExpr, t, PRIMITIVE_I_AND);
  8596.           if (resultType) return resultType;
  8597.       break;
  8598.  
  8599.         case UNARY_BANG:                            // in checkTypes for SEND_EXPR...
  8600.           // Check for the special case of !int or !bool...
  8601.           if (argCount (sendExpr->argList) == 0) {
  8602.             if (isIntType (t)) {
  8603.               sendExpr->primitiveSymbol = PRIMITIVE_I_NOT;
  8604.               return basicIntType;
  8605.             } else if (isBoolType (t)) {
  8606.               sendExpr->primitiveSymbol = PRIMITIVE_B_NOT;
  8607.               return basicBoolType;
  8608.             } else if (isPtrType (t)) {
  8609.               sendExpr->receiver = insertPtrToBool (sendExpr->receiver);
  8610.               sendExpr->primitiveSymbol = PRIMITIVE_B_NOT;
  8611.               return basicBoolType;
  8612.             }
  8613.           }
  8614.           break;
  8615.  
  8616.         case BAR_BAR:                            // in checkTypes for SEND_EXPR...
  8617.           resultType = checkForPrimitive4 (sendExpr, t, PRIMITIVE_B_OR);
  8618.           if (resultType) return resultType;
  8619.       break;
  8620.  
  8621.         case AMP_AMP:                            // in checkTypes for SEND_EXPR...
  8622.           resultType = checkForPrimitive4 (sendExpr, t, PRIMITIVE_B_AND);
  8623.           if (resultType) return resultType;
  8624.       break;
  8625.  
  8626.         case LESS:                            // in checkTypes for SEND_EXPR...
  8627.           resultType = checkForPrimitive3 (sendExpr, t, PRIMITIVE_I_LT, PRIMITIVE_D_LT);
  8628.           if (resultType) return resultType;
  8629.       break;
  8630.  
  8631.         case LESS_EQUAL:                            // in checkTypes for SEND_EXPR...
  8632.           resultType = checkForPrimitive3 (sendExpr, t, PRIMITIVE_I_LE, PRIMITIVE_D_LE);
  8633.           if (resultType) return resultType;
  8634.       break;
  8635.  
  8636.         case GREATER:                            // in checkTypes for SEND_EXPR...
  8637.           resultType = checkForPrimitive3 (sendExpr, t, PRIMITIVE_I_GT, PRIMITIVE_D_GT);
  8638.           if (resultType) return resultType;
  8639.       break;
  8640.  
  8641.         case GREATER_EQUAL:                            // in checkTypes for SEND_EXPR...
  8642.           resultType = checkForPrimitive3 (sendExpr, t, PRIMITIVE_I_GE, PRIMITIVE_D_GE);
  8643.           if (resultType) return resultType;
  8644.       break;
  8645.  
  8646.         case EQUAL_EQUAL:                            // in checkTypes for SEND_EXPR...
  8647.           resultType = checkForPrimitive5 (sendExpr, t, PRIMITIVE_I_EQ, PRIMITIVE_D_EQ, PRIMITIVE_B_EQ, PRIMITIVE_OBJECT_EQ);
  8648.           if (resultType) return resultType;
  8649.       break;
  8650.  
  8651.         case NOT_EQUAL:                            // in checkTypes for SEND_EXPR...
  8652.           resultType = checkForPrimitive5 (sendExpr, t, PRIMITIVE_I_NE, PRIMITIVE_D_NE, PRIMITIVE_B_NE, PRIMITIVE_OBJECT_NE);
  8653.           if (resultType) return resultType;
  8654.       break;
  8655.  
  8656.         default:                            // in checkTypes for SEND_EXPR...
  8657.           // Continue below, checking for user-defined operators...
  8658.           break;
  8659.       }
  8660.  
  8661.       // printf ("\nSEND EXPR = ");
  8662.       // pretty (sendExpr);
  8663.       // printf ("    receiver type = ");
  8664.       // pretty (t);
  8665.  
  8666.       // If this is a ptr, insert a dereference node...
  8667.       pType = getPtrType (t);
  8668.       if (pType != NULL) {
  8669.         sendExpr->receiver = insertDeref (sendExpr->receiver);
  8670.         t = pType->baseType;
  8671.       }
  8672.  
  8673.       nameWithoutSuper = sendExpr->selector;
  8674.  
  8675.       // printf ("  At this point sendExpr =");
  8676.       // pretty (sendExpr);
  8677.  
  8678.       // If we are sending to "super", append "_super_" to the selector...
  8679.       if (recvrIsSuper) {
  8680.         newSelector = addSuperTo (nameWithoutSuper);
  8681.       } else {
  8682.         newSelector = nameWithoutSuper;
  8683.       }
  8684.  
  8685.       // printf ("Binding send.... selector = %s\n", sendExpr->selector->chars);
  8686.       // printf ("           newSelector = %s\n", newSelector->chars);
  8687.  
  8688.       // Make sure it is a class or interface...
  8689.       t = resolveNamedType (t);
  8690.       if (t == NULL) return NULL;
  8691.       if (t->op == NAMED_TYPE) {
  8692.         nType = (NamedType *) t;
  8693.         if (nType->myDef == NULL) return NULL;
  8694.  
  8695.         // If the reciever is a class...
  8696.         if (nType->myDef->op == CLASS_DEF) {
  8697.           cl = (ClassDef *) nType->myDef;
  8698.  
  8699.           // Build the substitution...
  8700.           if (nType->subst == NULL) {
  8701.             nType->subst = buildSubstitution (cl->typeParms, nType->typeArgs);
  8702.           }
  8703.           // printf ("  subst = \n");
  8704.           // if (nType->subst) {
  8705.           //   nType->subst->print (6);
  8706.           // } else {
  8707.           //   printf ("NULL\n");
  8708.           // }
  8709.  
  8710.           // Look for a MethodProto in this class's "selectorMapping"...
  8711.           //     printf ("SelectorMapping for class %s...\n", cl->id->chars);
  8712.           //     cl->selectorMapping->print(0);
  8713.           methodProto = cl->selectorMapping->find (newSelector);
  8714.           // If the send is to "super", we must have a local method in this class
  8715.           // by the same name and we must have an overriden version of this method...
  8716.           if (recvrIsSuper &&
  8717.               ((cl->localMethodMapping->find (nameWithoutSuper) == NULL) ||
  8718.                (methodProto == NULL))) {
  8719.               error (sendExpr, "This message was not overridden in this class; use 'self' not 'super'");
  8720.           }
  8721.           // printf (" methodProto before subst = ");
  8722.           // pretty (methodProto);
  8723.           // printf ("  methodProto with subst = ");
  8724.           // pretty (copyTypeWithSubst (methodProto, nType->subst));
  8725.           // printf ("\n\n");
  8726.  
  8727.           // Check that the send expression satisfies the methodProto...
  8728.           return checkMessageSend (methodProto, sendExpr, t, nType->subst);
  8729.  
  8730.         // If the reciever is an interface...
  8731.         } else if (nType->myDef->op == INTERFACE) {
  8732.           interface = (Interface *) nType->myDef;
  8733.  
  8734.           // Build the substitution...
  8735.           if (nType->subst == NULL) {
  8736.             nType->subst = buildSubstitution (interface->typeParms, nType->typeArgs);
  8737.           }
  8738.  
  8739.           // Look for a MethodProto in this interface's "selectorMapping"...
  8740.           //     printf ("SelectorMapping for interface %s...\n", interface->id->chars);
  8741.           //     interface->selectorMapping->print(0);
  8742.           methodProto = interface->selectorMapping->find (newSelector);
  8743.  
  8744.           // Check that the send expression satisfies the methodProto...
  8745.           return checkMessageSend (methodProto, sendExpr, t, nType->subst);
  8746.         }
  8747.       }
  8748.  
  8749.       // It must be an error...
  8750.       if (looksLikeDeref) {
  8751.         error (sendExpr, "The dereference operator may only be applied to ptr types (Objects may understand a prefix * method, but this is not an object)");
  8752.         errorWithType ("The type of the receiver is", t);
  8753.         return NULL;
  8754.       }
  8755.       error (sendExpr, "This message is not understood by this type of receiver (1)");
  8756.       errorWithType ("The type of the receiver is", t);
  8757.       return NULL;
  8758.  
  8759.     case SELF_EXPR:                               // in checkTypes
  8760.       selfExpr = (SelfExpr *) node;
  8761.       if (currentClass == NULL) {
  8762.         error (node, "Self may only be used within a method, not within a function");
  8763.       } else {
  8764.         return currentClass->typeOfSelf;
  8765.       }
  8766.       return NULL;
  8767.  
  8768.     case SUPER_EXPR:                               // in checkTypes
  8769.       error (node, "Super may only be used as the target of a message send; use 'self' instead");
  8770.       return NULL;
  8771.  
  8772.     case FIELD_ACCESS:                               // in checkTypes
  8773.       fieldAccess = (FieldAccess *) node;
  8774.       // printf ("FIELD ACCESS: ");
  8775.       // pretty (fieldAccess);
  8776.       t = checkTypes (fieldAccess->expr);
  8777.       // errorWithType ("FIELD ACCESS: Here is the starting type...", t);
  8778.       // If this is a ptr, insert a dereference node...
  8779.       pType = getPtrType (t);
  8780.       if (pType != NULL) {
  8781.         fieldAccess->expr = insertDeref (fieldAccess->expr);
  8782.         t = pType->baseType;
  8783.       }
  8784.       t = resolveNamedType (t);
  8785.       if (t == NULL) return NULL;
  8786.  
  8787.       // See if this is a record.field access...
  8788.       if (t->op == RECORD_TYPE) {
  8789.         rType = (RecordType *) t;
  8790.         recordField = rType->fieldMapping->find (fieldAccess->id);
  8791.         if (recordField == NULL) {
  8792.           error (node, "In field access 'record.field', this field is not in this record");
  8793.           return NULL;
  8794.         }
  8795.         fieldAccess->offset = recordField->offset;
  8796.         return recordField->type;
  8797.       }
  8798.  
  8799.       // See if this is a class.field access...
  8800.       if (t->op == NAMED_TYPE) {
  8801.         nType = (NamedType *) t;
  8802.         cl = (ClassDef *) nType->myDef;
  8803.         if (cl == NULL) return NULL;
  8804.         if (cl->op == CLASS_DEF) {   // Actual type may be a subtype, but that's okay...
  8805.           // Find the field...
  8806.           classField = (ClassField *) cl->classMapping->find (fieldAccess->id);
  8807.           if ((classField == NULL) || (classField->op != CLASS_FIELD)) {
  8808.             error (node, "In field access 'ObjectExpr.field', this field is not in this class");
  8809.             errorWithType ("The class of ObjectExpr is", nType);
  8810.             return NULL;
  8811.           }
  8812.           fieldAccess->offset = classField->offset;
  8813.           // Build the substitution...
  8814.           if (nType->subst == NULL) {
  8815.             nType->subst = buildSubstitution (cl->typeParms, nType->typeArgs);
  8816.           }
  8817.           // printf ("  subst = \n");
  8818.           // if (nType->subst) {
  8819.           //   nType->subst->print (6);
  8820.           // } else {
  8821.           //   printf ("NULL\n");
  8822.           // }
  8823.           // printf (" type before subst = ");
  8824.           // pretty (classField->type);
  8825.           // printf ("  type with subst = ");
  8826.           // pretty (copyTypeWithSubst (classField->type, nType->subst));
  8827.           // printf ("\n\n");
  8828.           // Apply the substitution to this field's type and return the result...
  8829.           return copyTypeWithSubst (classField->type, nType->subst);
  8830.         }
  8831.       }
  8832.       error (fieldAccess->expr, "In 'expr.field' the expression before the '.' is not a 'class', 'ptr to class', 'record', or 'ptr to record'");
  8833.       errorWithType ("The type of the expression is", t);
  8834.       return NULL;
  8835.  
  8836.     case ARRAY_ACCESS:                               // in checkTypes
  8837.       arrayAccess = (ArrayAccess *) node;
  8838.       t = checkTypes (arrayAccess->arrayExpr);
  8839.       // If this is a ptr, insert a dereference node...
  8840.       pType = getPtrType (t);
  8841.       if (pType != NULL) {
  8842.         arrayAccess->arrayExpr = insertDeref (arrayAccess->arrayExpr);
  8843.         t = pType->baseType;
  8844.       }
  8845.       // t2 = checkTypes (arrayAccess->indexExpr);  // checkTypes called in checkAssgnmt
  8846.       aType = getArrayType (t);
  8847.       if (aType == NULL) {
  8848.         error (arrayAccess->arrayExpr, "In array access 'a[i]', the expression 'a' is not an array");
  8849.         return NULL;
  8850.       }
  8851.       arrayAccess->indexExpr = checkAssignment (
  8852.                 arrayAccess->indexExpr,
  8853.                 basicIntType,
  8854.                 "In array access 'a[i]', the index expression 'i' is not an int",
  8855.                 NULL);
  8856.       arrayAccess->sizeOfElements = aType->sizeOfElements;
  8857.       return aType->baseType;
  8858.  
  8859.     case CONSTRUCTOR:                               // in checkTypes
  8860.       constructor = (Constructor *) node;
  8861.       t = checkConstructor (constructor);
  8862.       if (constructor->allocKind == NEW) {
  8863.         return t;
  8864.       } else if (constructor->allocKind == ALLOC) {
  8865.         if (t == NULL) return NULL;
  8866.         pType = new PtrType ();
  8867.         pType->positionAt (constructor);
  8868.         pType->baseType = t;
  8869.         return pType;
  8870.       } else {
  8871.         programLogicError ("Unexpected constructor->allocKind in checkTypes");
  8872.       }
  8873.  
  8874.     case CLOSURE_EXPR:                               // in checkTypes
  8875.       closureExpr = (ClosureExpr *) node;
  8876.       // Skip checkTypes, since we'll walk the function when we do header->closures...
  8877.       // t = checkTypes (closureExpr->function);
  8878.       // Look at the function and construct a new 'ptr to function...' type.
  8879.       fun = closureExpr->function;
  8880.       fType = new FunctionType ();
  8881.       fType->positionAt (node);
  8882.       // Build a list of TypeArgs...
  8883.       typeArgList = NULL;
  8884.       for (parm = fun->parmList; parm; parm = (Parameter *) parm->next) {
  8885.         typeArg = new TypeArg ();
  8886.         typeArg->positionAt (parm);
  8887.         typeArg->type = parm->type;
  8888.         typeArg->next = typeArgList;
  8889.         typeArgList = typeArg;
  8890.       }
  8891.       // Reverse the list and set fType->parms to point to it...
  8892.       typeArg = typeArgList;
  8893.       while (typeArg) {
  8894.         nextTypeArg = typeArg->next;
  8895.         typeArg->next = fType->parmTypes;
  8896.         fType->parmTypes = typeArg;
  8897.         typeArg = nextTypeArg;
  8898.       }
  8899.       // Fill in fType->retType...
  8900.       fType->retType = fun->retType;
  8901.  
  8902.       pType = new PtrType ();
  8903.       pType->positionAt (node);
  8904.       pType->baseType = fType;
  8905.       return pType;
  8906.  
  8907.     case VARIABLE_EXPR:                               // in checkTypes
  8908.       var = (VariableExpr *) node;
  8909.       if (var->myDef) {
  8910.         varDecl = (VarDecl *) var->myDef;
  8911.  
  8912.         // If we have a normal variable reference, then return the var's type...
  8913.         if ((varDecl->op == LOCAL) ||
  8914.             (varDecl->op == GLOBAL) ||
  8915.             (varDecl->op == PARAMETER) ||
  8916.             (varDecl->op == CLASS_FIELD)) {
  8917.           return varDecl->type;
  8918.  
  8919.         } else if (varDecl->op == RECORD_FIELD) {
  8920.           programLogicError ("Lone record fields will be undefined variables");
  8921.  
  8922.         // Else if this variable names a function, build a type such as:
  8923.         //          ptr to function (int, int) returns double
  8924.         } else if (varDecl->op == FUNCTION_PROTO) {
  8925.           functionProto = (FunctionProto *) varDecl;
  8926.           fType = new FunctionType ();
  8927.           fType->positionAt (node);
  8928.           // Build a list of TypeArgs...
  8929.           typeArgList = NULL;
  8930.           for (parm = functionProto->parmList; parm; parm = (Parameter *) parm->next) {
  8931.             typeArg = new TypeArg ();
  8932.             typeArg->positionAt (parm);
  8933.             typeArg->type = parm->type;
  8934.             typeArg->next = typeArgList;
  8935.             typeArgList = typeArg;
  8936.           }
  8937.           // Reverse the list and set fType->parms to point to it...
  8938.           typeArg = typeArgList;
  8939.           while (typeArg) {
  8940.             nextTypeArg = typeArg->next;
  8941.             typeArg->next = fType->parmTypes;
  8942.             fType->parmTypes = typeArg;
  8943.             typeArg = nextTypeArg;
  8944.           }
  8945.           // Fill in fType->retType...
  8946.           fType->retType = functionProto->retType;
  8947.           // Build a ptr-to node and return it...
  8948.           pType = new PtrType ();
  8949.           pType->positionAt (node);
  8950.           pType->baseType = fType;
  8951.           // printf ("Use of function %s as a variable; type of expr is ",
  8952.           //            var->id->chars);
  8953.           // pretty (pType);
  8954.           return pType;
  8955.           
  8956.         } else {
  8957.           programLogicError ("varDecl->myDef is wrong");
  8958.         }
  8959.       }
  8960.  
  8961.       return NULL;
  8962.  
  8963.     case AS_PTR_TO_EXPR:                               // in checkTypes
  8964.       asPtrToExpr = (AsPtrToExpr *) node;
  8965.       if (safe) {
  8966.         error (node, "Using 'asPtrTo' is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  8967.       }
  8968.       t = checkTypes (asPtrToExpr->expr);
  8969.       t2 = checkTypes (asPtrToExpr->type);
  8970.       pType = new PtrType ();
  8971.       pType->positionAt (node);
  8972.       pType->baseType = asPtrToExpr->type;
  8973.       if (assignable (pType, t)) {
  8974.         if (! isPtrToVoidType (t)) {
  8975.           error (node, "You do not need 'asPtrTo' here; the expression already has the desired type");
  8976.         }
  8977.       }
  8978.       if (!isIntType (t) && !isPtrType (t)) {
  8979.         error (node, "You may only coerce a ptr or an int into a ptr type");
  8980.         errorWithType ("The type of this expression is", t);
  8981.       }
  8982.       return pType;
  8983.  
  8984.     case AS_INTEGER_EXPR:                               // in checkTypes
  8985.       asIntegerExpr = (AsIntegerExpr *) node;
  8986.       t = checkTypes (asIntegerExpr->expr);
  8987.       // if (safe) {
  8988.       //   error (node, "Using 'asInteger' is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  8989.       // }
  8990.       t = checkTypes (asIntegerExpr->expr);
  8991.       if (!isPtrType (t)) {
  8992.         error (node, "You may only coerce a ptr into an int");
  8993.         errorWithType ("The type of this expression is", t);
  8994.       }
  8995.       return basicIntType;
  8996.  
  8997.     case ARRAY_SIZE_EXPR:                               // in checkTypes
  8998.       arraySizeExpr = (ArraySizeExpr *) node;
  8999.       t = checkTypes (arraySizeExpr->expr);
  9000.       // If this is a ptr, insert a dereference node...
  9001.       pType = getPtrType (t);
  9002.       if (pType != NULL) {
  9003.         arraySizeExpr->expr = insertDeref (arraySizeExpr->expr);
  9004.         t = pType->baseType;
  9005.       }
  9006.       if (getArrayType (t) == NULL) {
  9007.         error (arraySizeExpr->expr, "In 'Expr sizeOf', this expression is not an array");
  9008.       }
  9009.       return basicIntType;
  9010.  
  9011.     case IS_INSTANCE_OF_EXPR:                               // in checkTypes
  9012.       isInstanceOfExpr = (IsInstanceOfExpr *) node;
  9013.       t = checkTypes (isInstanceOfExpr->expr);
  9014.       // If this is a ptr, insert a dereference node...
  9015.       pType = getPtrType (t);
  9016.       if (pType != NULL) {
  9017.         isInstanceOfExpr->expr = insertDeref (isInstanceOfExpr->expr);
  9018.         t = pType->baseType;
  9019.       }
  9020.  
  9021.       // Make sure the type of the expression is a class or interface...
  9022.       if (!isObjectType (t)) {
  9023.         error (node, "In 'EXPR isInstanceOf TYPE', EXPR is not an object; it is impossible to check its type at runtime");
  9024.         errorWithType ("The type of 'expr' is", t);
  9025.       }
  9026.  
  9027.       // Make sure the type on the right is a legal, concrete class...
  9028.       checkTypes (isInstanceOfExpr->type);
  9029.       checkConcreteClass (
  9030.             isInstanceOfExpr->type,
  9031.             isInstanceOfExpr->type,
  9032.             "In 'EXPR isInstanceOf TYPE', the TYPE must be a concrete class");
  9033.  
  9034.       isInstanceOfExpr->classDef = getClassDef (isInstanceOfExpr->type);
  9035.       if (isInstanceOfExpr->classDef == NULL) {
  9036.         error (isInstanceOfExpr->type,
  9037.                "In 'EXPR isInstanceOf TYPE', the TYPE is not a class");
  9038.       } else if (isInstanceOfExpr->classDef->typeParms != NULL) {
  9039.         error (isInstanceOfExpr, "IMPLEMENTATION RESTRICTION: The type after 'isInstanceOf' must not be parameterized");
  9040.         errorWithType ("The type after 'isInstanceOf' is", isInstanceOfExpr->type);
  9041.       }
  9042.  
  9043.       // OBSOLETE VERSION: "isExactClass" is not quite good enough...
  9044.       // if (!isExactClass (isInstanceOfExpr->type)) {
  9045.       //   error (node, "In 'expr isInstanceOf type', the 'type' must be a class name");
  9046.       //   errorWithType ("The type after 'isInstanceOf' is", isInstanceOfExpr->type);
  9047.       // }
  9048.  
  9049.       return basicBoolType;
  9050.  
  9051.     case IS_KIND_OF_EXPR:                               // in checkTypes
  9052.       isKindOfExpr = (IsKindOfExpr *) node;
  9053.       t = checkTypes (isKindOfExpr->expr);
  9054.       // If this is a ptr, insert a dereference node...
  9055.       pType = getPtrType (t);
  9056.       if (pType != NULL) {
  9057.         isKindOfExpr->expr = insertDeref (isKindOfExpr->expr);
  9058.         t = pType->baseType;
  9059.       }
  9060.  
  9061.       // Make sure the type of the expression is a class or interface...
  9062.       if (! isObjectType (t)) {
  9063.         error (node, "In 'EXPR isKindOf TYPE', EXPR is not an object; it is impossible to check its type at runtime");
  9064.         errorWithType ("The type of 'expr' is", t);
  9065.       }
  9066.  
  9067.       // Make sure the type on the right is a legal, concrete class or interface...
  9068.       checkTypes (isKindOfExpr->type);
  9069.       checkConcreteClassOrInterface (
  9070.            isKindOfExpr->type,
  9071.            isKindOfExpr->type,
  9072.            "In 'EXPR isKindOf TYPE', the TYPE must be a concrete class or interface");
  9073.       isKindOfExpr->classOrInterface = getClassDef (isKindOfExpr->type);
  9074.       if (isKindOfExpr->classOrInterface == NULL) {
  9075.         isKindOfExpr->classOrInterface = getInterface (isKindOfExpr->type);
  9076.       }
  9077.       if (isKindOfExpr->classOrInterface == NULL) {
  9078.         error (isKindOfExpr->type,
  9079.                "In 'EXPR isKindOf TYPE', the TYPE is not a class or interface");
  9080.       }
  9081.  
  9082.       return basicBoolType;
  9083.  
  9084.     case SIZE_OF_EXPR:                               // in checkTypes
  9085.       sizeOfExpr = (SizeOfExpr *) node;
  9086.       t = checkTypes (sizeOfExpr->type);
  9087.       // We should have eliminated this node by now in evalExprs.  If it still exists,
  9088.       // then there must have been a problem in determining the value...
  9089.       error (node, "Unable to determine at compile-time the size of this type of data");
  9090.       return NULL;
  9091.  
  9092.     case DYNAMIC_CHECK:
  9093.       dynamicCheck = (DynamicCheck *) node;
  9094.       return checkTypes (dynamicCheck->expr);
  9095.  
  9096.     case ARGUMENT:                               // in checkTypes
  9097.       programLogicError ("We will do each argument in a loop elsewhere");
  9098.       arg = (Argument *) node;
  9099.       t = checkTypes (arg->expr);
  9100.       t = checkTypes (arg->next);
  9101.       return NULL;
  9102.  
  9103.     case COUNT_VALUE:                               // in checkTypes
  9104.       programLogicError ("We are checking CountValues within the constructor case");
  9105.       countValue = (CountValue *) node;
  9106.       t = checkTypes (countValue->count);
  9107.       t = checkTypes (countValue->value);
  9108.       t = checkTypes (countValue->next);
  9109.       return NULL;
  9110.  
  9111.     case FIELD_INIT:                               // in checkTypes
  9112.       programLogicError ("We are checking FieldInits within the constructor case");
  9113.       fieldInit = (FieldInit *) node;
  9114.       t = checkTypes (fieldInit->expr);
  9115.       t = checkTypes (fieldInit->next);
  9116.       return NULL;
  9117.  
  9118.     default:                               // in checkTypes
  9119.  
  9120.       printf ("\nnode->op = %s\n", symbolName (node->op));
  9121.       programLogicError ("Unkown op in checkTypes");
  9122.   }
  9123.   programLogicError ("All cases should contain returns in checkTypes");
  9124. }
  9125.  
  9126.  
  9127.  
  9128. // checkConstructor (constructor)  -->  Type
  9129. //
  9130. // This routine checks the types in a constructor and returns either
  9131. // an ARRAY_TYPE, RECORD_TYPE, or CLASS_TYPE.  If any problems occur, it
  9132. // may return NULL.
  9133. //
  9134. Type * checkConstructor (Constructor * constructor) {
  9135.   Type * t;
  9136.   ClassDef * cl;
  9137.   NamedType * nType;
  9138.   ClassField * classField;
  9139.   RecordType * rType;
  9140.   RecordField * recordField;
  9141.   FieldInit * fieldInit;
  9142.   ArrayType * aType, * newAType;
  9143.   CountValue * countValue;
  9144.   Mapping <String, AstNode> * tempMap;
  9145.   AstNode * def;
  9146.   int i, count, gotExpr;
  9147.   IntConst * intConst;
  9148.  
  9149.   t = checkTypes (constructor->type);
  9150.   t = resolveNamedType2 (constructor->type);  // This won't return a constraint
  9151.   if (t == NULL) return NULL;
  9152.  
  9153.   // If this is a CLASS constructor...
  9154.   cl = getClassDef (t);
  9155.   if (cl != NULL) {
  9156.  
  9157.     // Previously, we did not allow the type to contain any Type Parameters;
  9158.     // Now it is okay to say "alloc List[T]..." or "new List[T]..."
  9159.     //    checkConcreteClass (
  9160.     //         constructor->type,
  9161.     //         constructor,
  9162.     //         "The class in a class constructor may not involve type parameters, since the exact class must be known at compile-time");
  9163.  
  9164.     // At this point, "t" points to a NamedType...
  9165.     if (t->op != NAMED_TYPE) {
  9166.       programLogicError ("resolveNamedType2(constructor->type) returns NAMED_TYPE if this is a class");
  9167.     }
  9168.  
  9169.     // Build the substitution, if we have something like "List[Person]"...
  9170.     nType = (NamedType *) t;
  9171.     if (nType->subst == NULL) {
  9172.       nType->subst = buildSubstitution (cl->typeParms, nType->typeArgs);
  9173.     }
  9174.     // printf ("  subst = \n");
  9175.     // if (nType->subst) {
  9176.     //   nType->subst->print (6);
  9177.     // } else {
  9178.     //   printf ("NULL\n");
  9179.     // }
  9180.  
  9181.     // Fill in "kind", "myClass" and "sizeInBytes".
  9182.     constructor->kind = CLASS;
  9183.     constructor->myClass = cl;
  9184.     constructor->sizeInBytes = cl->sizeInBytes;
  9185.  
  9186.     // I considered overwriting "type" with the resolved(2) type, since there
  9187.     // may have been typeDefs involved.  But this only eliminates TypeDefs
  9188.     // at the highest level.  It does nothing for "List[MyType]".
  9189.     //    constructor->type = t;
  9190.  
  9191.     // Check that there is no count-value list...
  9192.     if (constructor->countValueList) {
  9193.       error (constructor->countValueList,
  9194.         "Use count-value lists for array constructors; this is a class constructor");
  9195.     }
  9196.  
  9197.     // Run thru all FieldInits and match them to ClassFields...
  9198.     tempMap = new Mapping <String, AstNode> (5, NULL);
  9199.     for (fieldInit = constructor->fieldInits;
  9200.          fieldInit;
  9201.          fieldInit = fieldInit->next) {
  9202.       def = cl->classMapping->find (fieldInit->id);
  9203.       if (tempMap->find (fieldInit->id)) {
  9204.         error (fieldInit, "You are assigning to this field more than once");
  9205.       } else {
  9206.         tempMap->enter (fieldInit->id, fieldInit);
  9207.       }
  9208.       if (def && (def->op == CLASS_FIELD)) {
  9209.         classField = (ClassField *) def;
  9210.         fieldInit->offset = classField->offset;
  9211.         fieldInit->sizeInBytes = classField->sizeInBytes;
  9212.         fieldInit->expr = checkAssignment (
  9213.             fieldInit->expr,
  9214.             copyTypeWithSubst (classField->type, nType->subst),
  9215.             "This expression does not have the type expected by this field",
  9216.             NULL);
  9217.       } else {
  9218.         error (fieldInit, "This is not a field in this class");
  9219.       }
  9220.     }
  9221.  
  9222.     // If the are no field inits, then okay.  Else make sure that all
  9223.     // fields have initializing expressions...
  9224.     if (constructor->fieldInits != NULL) {
  9225.       // Run thru all ClassFields and match them to FieldInits; if they
  9226.       // initialize any fields, they have to initalize all fields...
  9227.       // (Do we really want to check this?  Perhaps it is better to allow
  9228.       // some fields to be automatically initialized to zero equivalents...)
  9229.       for (classField = cl->fields;
  9230.            classField;
  9231.            classField = (ClassField *) classField->next) {
  9232.         if (! tempMap->find (classField->id)) {
  9233.           error (constructor, "You have failed to provide an initial value for some field in this class");
  9234.           error2 (classField, "Here is the missing field");
  9235.         }
  9236.       }
  9237.     }
  9238.  
  9239.     delete tempMap;
  9240.  
  9241.     return t;
  9242.  
  9243.   // If this is a RECORD constructor...
  9244.   } else if (t->op == RECORD_TYPE) {
  9245.  
  9246.     // Get a pointer to the RecordType node...
  9247.     rType = (RecordType *) t;
  9248.  
  9249.     // Fill in "kind" and "sizeInBytes"...
  9250.     constructor->kind = RECORD;
  9251.     constructor->sizeInBytes = rType->sizeInBytes;
  9252.  
  9253.     // t = checkTypes (constructor->fieldInits);
  9254.  
  9255.     // Check that there is no count-value list...
  9256.     if (constructor->countValueList) {
  9257.       error (constructor->countValueList,
  9258.         "Use count-value lists for array constructors; this is a record constructor");
  9259.     }
  9260.  
  9261.     // Run thru all FieldInits and match them to RecordFields...
  9262.     tempMap = new Mapping <String, AstNode> (5, NULL);
  9263.     for (fieldInit = constructor->fieldInits;
  9264.          fieldInit;
  9265.          fieldInit = fieldInit->next) {
  9266.       def = rType->fieldMapping->find (fieldInit->id);
  9267.       if (tempMap->find (fieldInit->id)) {
  9268.         error (fieldInit, "You are assigning to this field more than once");
  9269.       } else {
  9270.         tempMap->enter (fieldInit->id, fieldInit);
  9271.       }
  9272.       if (def && (def->op == RECORD_FIELD)) {
  9273.         recordField = (RecordField *) def;
  9274.         fieldInit->offset = recordField->offset;
  9275.         fieldInit->sizeInBytes = recordField->sizeInBytes;
  9276.         fieldInit->expr = checkAssignment (
  9277.             fieldInit->expr,
  9278.             recordField->type,
  9279.             "This expression does not have the type expected by this field",
  9280.             NULL);
  9281.       } else {
  9282.         error (fieldInit, "This is not a field in this record");
  9283.       }
  9284.     }
  9285.  
  9286.     // Run thru all RecordFields and match them to FieldInits...
  9287.     // (Do we really want to check this?  Perhaps it is better to allow
  9288.     //  some fields to be automatically initialized to zero equivalents...)
  9289.     for (recordField = rType->fields;
  9290.          recordField;
  9291.          recordField = (RecordField *) recordField->next) {
  9292.       if (! tempMap->find (recordField->id)) {
  9293.         error (constructor, "You have failed to provide an initial value for some field in this record");
  9294.         error2 (recordField, "Here is the missing field");
  9295.       }
  9296.     }
  9297.  
  9298.     // Return the RecordType node...
  9299.     return rType;
  9300.  
  9301.   // If this is an ARRAY constructor...
  9302.   } else if (t->op == ARRAY_TYPE) {
  9303.  
  9304.     // Get a pointer to the ArrayType node...
  9305.     aType = (ArrayType *) t;
  9306.  
  9307.     // Fill in "kind" and "sizeInBytes"...
  9308.     constructor->kind = ARRAY;
  9309.     constructor->sizeInBytes = -1;
  9310.  
  9311.     // Check that there is no field-init list...
  9312.     if (constructor->fieldInits) {
  9313.       error (constructor->fieldInits,
  9314.              "Use field-init lists for classes or records; this is an array constructor");
  9315.     }
  9316.  
  9317.     // make sure we have a count-value list...
  9318.     if (constructor->countValueList == NULL) {
  9319.       error (constructor,
  9320.              "This is an array constructor; you must have a count-value list");
  9321.     }
  9322.  
  9323.     // Run through the count-value list and check it...
  9324.     // Also, see if we can determine statically (at this time) the
  9325.     // actual size of the array.
  9326.     count = 0;
  9327.     gotExpr = 0;
  9328.     for (countValue = constructor->countValueList;
  9329.          countValue;
  9330.          countValue = countValue->next) {
  9331.       if (countValue->count) {
  9332.         countValue->count = checkAssignment (
  9333.             countValue->count,
  9334.             basicIntType,
  9335.             "In array constructor, the count expression is not an int",
  9336.             NULL);
  9337.         if (countValue->count->op == INT_CONST) {
  9338.           i = ((IntConst *) countValue->count)->ivalue;
  9339.           if (i <= 0) {
  9340.             error (countValue->count,
  9341.                "This count expression must be greater than zero");
  9342.           } else {
  9343.             count += i;
  9344.           }
  9345.         } else {
  9346.           gotExpr = 1;
  9347.           if (aType->sizeExpr) {
  9348.             error (countValue->count, "This is an array constructor for an array with a known size but I cannot evaluate this count expression at compile-time");
  9349.           }
  9350.         }
  9351.       } else {
  9352.         count++;
  9353.       }
  9354.       countValue->value = checkAssignment (
  9355.             countValue->value,
  9356.             aType->baseType,
  9357.             "In array constructor, this value expression does not have the correct type",
  9358.             NULL);
  9359.     }
  9360.  
  9361.     // If this ArrayType is not dynamic, then make sure that the
  9362.     // number of elements provided matches the type...
  9363.     if ((aType->sizeExpr) && (aType->sizeExpr->op == INT_CONST)) {
  9364.       i = ((IntConst *) aType->sizeExpr)->ivalue;
  9365.       if (count != i) {
  9366.         error (constructor,
  9367.              "This is an array constructor for an array with a known size but the number of initial values you have provided is incorrect");
  9368.       }
  9369.     }
  9370.  
  9371.     // Fill in "sizeInBytes"...
  9372.     if (count > 0) {
  9373.       i = 4 + count * aType->sizeOfElements;
  9374.       i += 3 - ((i+3) % 4);        // Pad, if necessary
  9375.       constructor->sizeInBytes = i;
  9376.     } else {
  9377.       constructor->sizeInBytes = -1;
  9378.     }
  9379.  
  9380.     // If this is a NEW Constructor, make sure we know the array size at compile-time...
  9381.     if ((constructor->allocKind == NEW) && gotExpr) {
  9382.       error (constructor, "A NEW ARRAY constructor requires that the number of array elements be computable at compile-time");
  9383.     }
  9384.  
  9385.     // printf ("ARRAY SIZE... constructor->sizeInBytes = %d\n",
  9386.     //         constructor->sizeInBytes);
  9387.  
  9388.     // If we saw a fixed number of elements but the given type was dynamic,
  9389.     // make a copy of the type, fill in the number of elements, and return it.
  9390.     // Also, update this constructor by changing the type.
  9391.     if (!gotExpr && (aType->sizeExpr == NULL)) {
  9392.       //      printf ("Building new ArrayType for... ");
  9393.       //      pretty (aType);
  9394.       intConst = new IntConst ();
  9395.       intConst->positionAt (aType);
  9396.       intConst->ivalue = count; 
  9397.       newAType = new ArrayType ();
  9398.       newAType->positionAt (aType);
  9399.       newAType->baseType = aType->baseType;
  9400.       newAType->sizeExpr = intConst;
  9401.       newAType->sizeInBytes = constructor->sizeInBytes;
  9402.       newAType->sizeOfElements = aType->sizeOfElements;
  9403.       //     printf ("            Here it is the new thing...   ");
  9404.       //     pretty (newAType);
  9405.       constructor->type = newAType;
  9406.       return newAType;
  9407.     }
  9408.  
  9409.     // Return the ArrayType node...
  9410.     return aType;
  9411.  
  9412.   // Otherwise, we've got an error...
  9413.   } else {
  9414.     error (constructor, "The type in a constructor must be either a class, record, or array type");
  9415.     return NULL;
  9416.   }
  9417. }
  9418.  
  9419.  
  9420.  
  9421. // linkDouble (doubleConst)
  9422. //
  9423. // This routine add this doubleConst to the floatList (if not already there)
  9424. // and give it a name, such as "_FloatConst_45".
  9425. //
  9426. void linkDouble (DoubleConst * doubleConst) {
  9427.     if (doubleConst->nameOfConstant == NULL) {
  9428.       doubleConst->next = floatList;
  9429.       floatList = doubleConst;
  9430.       doubleConst->nameOfConstant = newName ("FloatConst");
  9431.       // printf ("DOUBLE = %.17g   name = %s\n",
  9432.       //         doubleConst->rvalue,
  9433.       //         doubleConst-> nameOfConstant);
  9434.     }
  9435. }
  9436.  
  9437.  
  9438.  
  9439. // checkStaticData (expr, errorNode)
  9440. //
  9441. // This routine checks that the expr is static and can be used as the
  9442. // initializing expression for a global.  If not, it prints an error.
  9443. //
  9444. void checkStaticData (Expression * expr, AstNode * errorNode) {
  9445.   AstNode * where;
  9446.   if (expr == NULL) return;
  9447.   where = isStaticData (expr);
  9448.   if (where) {
  9449.     error (errorNode, "The initializing expression for this global variable could not be evaluated at compile-time");
  9450.     error2 (where, "The problem is here");
  9451.   }
  9452. }
  9453.  
  9454.  
  9455.  
  9456. // isStaticData (expr)  --> node
  9457. //
  9458. // This routine checks that the expr is static.  If it is, it returns NULL.
  9459. // If it is not static, it returns the node causing the non-static-ness.
  9460. //
  9461. AstNode *  isStaticData (Expression * expr) {
  9462.   VariableExpr * var;
  9463.   FunctionProto * funProto;
  9464.   Constructor * constructor;
  9465.   CountValue * countValue;
  9466.   AstNode * node;
  9467.   SendExpr * sendExpr;
  9468.   Global * glob;
  9469.   FieldInit * f;
  9470.  
  9471.   // printf ("Within isStaticData, expr = ");
  9472.   // pretty (expr);
  9473.  
  9474.   switch (expr->op) {
  9475.  
  9476.     case INT_CONST:
  9477.     case DOUBLE_CONST:
  9478.     case CHAR_CONST:
  9479.     case BOOL_CONST:
  9480.     case NULL_CONST:
  9481.       return NULL;
  9482.  
  9483.     case CLOSURE_EXPR:
  9484.       return NULL;
  9485.  
  9486.     case DYNAMIC_CHECK:
  9487.       return isStaticData (((DynamicCheck *) expr)->expr);
  9488.  
  9489.     case CONSTRUCTOR:
  9490.       constructor = (Constructor *) expr;
  9491.       if (constructor->allocKind != NEW) {
  9492.         return constructor;
  9493.       }
  9494.       if (constructor->kind == ARRAY) {
  9495.         for (countValue = constructor->countValueList;
  9496.              countValue;
  9497.              countValue = countValue->next) {
  9498.           if (countValue->count != NULL) {
  9499.             if (countValue->count->op != INT_CONST) {
  9500.               return countValue->count;
  9501.             }
  9502.           }
  9503.           node = isStaticData (countValue->value);
  9504.           if (node != NULL) {
  9505.             return node;
  9506.           }
  9507.         }
  9508.         return NULL;
  9509.       } else if (constructor->kind == RECORD ||
  9510.                  constructor->kind == CLASS) {
  9511.         for (f = constructor->fieldInits; f; f = f->next) {
  9512.           node = isStaticData (f->expr);
  9513.           if (node != NULL) return node;
  9514.         }
  9515.         return NULL;
  9516.       }
  9517.       return NULL;      //  If problem with type, then skip this error
  9518.  
  9519.     case VARIABLE_EXPR:
  9520.       var = (VariableExpr *) expr;
  9521.       funProto = (FunctionProto *) var->myDef;
  9522.       if (funProto == NULL || funProto->op != FUNCTION_PROTO) {
  9523.         return expr;
  9524.       }
  9525.       return NULL;
  9526.  
  9527.     case SEND_EXPR:
  9528.       sendExpr = (SendExpr *) expr;
  9529.       if (sendExpr->primitiveSymbol != PRIMITIVE_ADDRESS_OF) {
  9530.         return expr;
  9531.       }
  9532.       var = (VariableExpr *) sendExpr->receiver;
  9533.       if (var->op != VARIABLE_EXPR) {
  9534.         return expr;
  9535.       }
  9536.       glob = (Global *) var->myDef;
  9537.       if (glob == NULL || glob->op != GLOBAL) {
  9538.         return expr;
  9539.       }
  9540.       return NULL;
  9541.   }
  9542.   return expr;
  9543. }
  9544.  
  9545.  
  9546.  
  9547. // checkArgList (argList, parmList, proto, invocation)
  9548. //
  9549. // This routine checks to make sure this arg list matches the parm list in the
  9550. // prototype.  It is used for:
  9551. //    function calls
  9552. //    throw stmts
  9553. //
  9554. // It checks that every argument is assignment compatible with the corresponding
  9555. // parameter type.  It may introduce e.g., "charToInt()".
  9556. //
  9557. // The 'proto' and 'invocation' args are used for error messages only.
  9558. //
  9559. void checkArgList (Argument * arg,
  9560.                    Parameter * parm,
  9561.                    AstNode * proto,
  9562.                    AstNode * invocation) {
  9563.  
  9564.   while (1) {
  9565.     if ((parm == NULL) && (arg == NULL)) break;
  9566.     if (arg == NULL) {
  9567.       error (invocation, "You are missing one or more arguments in this invocation");
  9568.       error2 (parm, "Here is a parameter for which there is no argument");
  9569.       break;
  9570.     }
  9571.     if (parm == NULL) {
  9572.       error (invocation, "You have supplied too many arguments in this invocation");
  9573.       error2 (proto, "Here is the prototype");
  9574.       break;
  9575.     }
  9576.     arg->expr = checkAssignment (
  9577.                     arg->expr,
  9578.                     parm->type,
  9579.                     "The type of this argument is not assignable to the type of the corresponding parameter",
  9580.                     NULL);
  9581.     arg->offset = parm->offset;
  9582.     arg->sizeInBytes = parm->sizeInBytes;
  9583.     parm = (Parameter *) parm->next;
  9584.     arg = arg->next;
  9585.   }
  9586. }
  9587.  
  9588.  
  9589.  
  9590. // checkArgList2 (argList, typeArgList, proto, invocation)
  9591. //
  9592. // This routine checks to make sure this arg list matches the parm list in the
  9593. // prototype.  It is used for:
  9594. //    function calls with FunctionTypes (i.e., closure invocations)
  9595. //
  9596. // It checks that every argument is assignment compatible with the corresponding
  9597. // parameter type.  It may introduce e.g., "charToInt()".
  9598. //
  9599. // The 'proto' and 'invocation' args are used for error messages only.
  9600. //
  9601. void checkArgList2 (Argument * arg,
  9602.                    TypeArg * typeArg,
  9603.                    AstNode * proto,
  9604.                    AstNode * invocation) {
  9605.  
  9606.   while (1) {
  9607.     if ((typeArg == NULL) && (arg == NULL)) break;
  9608.     if (arg == NULL) {
  9609.       error (invocation, "You are missing one or more arguments in this invocation");
  9610.       error2 (typeArg, "Here is a parameter for which there is no argument");
  9611.       break;
  9612.     }
  9613.     if (typeArg == NULL) {
  9614.       error (invocation, "You have supplied too many arguments in this invocation");
  9615.       error2 (proto, "Here is the prototype");
  9616.       break;
  9617.     }
  9618.     arg->expr = checkAssignment (
  9619.                   arg->expr,
  9620.                   typeArg->type,
  9621.                   "The type of this argument is not assignable the type of the corresponding parameter",
  9622.                   NULL);
  9623.     arg->offset = typeArg->offset;
  9624.     arg->sizeInBytes = typeArg->sizeInBytes;
  9625.     //   printf ("offset = %d, sizeInBytes = %d\n", arg->offset, arg->sizeInBytes);
  9626.     typeArg = typeArg->next;
  9627.     arg = arg->next;
  9628.   }
  9629. }
  9630.  
  9631.  
  9632.  
  9633. // checkTypeInstantiation (typeArgList, typeParmList, proto, invocation)
  9634. //
  9635. // This routine checks to make sure this arg list matches the parm list in the
  9636. // prototype.  It is used to check NamedTypes, like:
  9637. //    List [int]
  9638. //
  9639. // It checks that every argument is a subtype of the corresponding
  9640. // parameter type.
  9641. //
  9642. // The 'proto' and 'invocation' args are used for error messages only.
  9643. //
  9644. void checkTypeInstantiation (TypeArg * typeArg,
  9645.                              TypeParm * typeParm,
  9646.                              AstNode * proto,
  9647.                              AstNode * invocation) {
  9648.   int i;
  9649.  
  9650.   // Run thru the lists of typeParms and typeArgs in parallel.  Check each pair...
  9651.   while (1) {
  9652.     if ((typeParm == NULL) && (typeArg == NULL)) break;
  9653.     if (typeArg == NULL) {
  9654.       error (invocation, "This class or interface is parameterized but you have given too few types; please add more types in 'Type [Type, Type, ...]'");
  9655.       error2 (typeParm, "Here is a parameter for which there is no type");
  9656.       break;
  9657.     }
  9658.     if (typeParm == NULL) {
  9659.       error (invocation, "You have supplied too many type arguments in 'Type [ Type, Type, ...]'");
  9660.       error2 (proto, "Here is the interface or class definition");
  9661.       break;
  9662.     }
  9663.  
  9664.     if (!isSubType (typeArg->type, typeParm->type)) {
  9665.       error (invocation, "One of the arguments in 'Type [Type, Type, ...]' fails to match the corresponding constraint type in the interface or class definition");
  9666.       error2 (typeArg, "Here is the argument that is incorrect");
  9667.       errorWithType ("It should be equal to (or a subtype of)", typeParm->type);
  9668.     }
  9669.  
  9670.     if (typeParm->fourByteRestricted) {
  9671.       i = sizeInBytesOfWhole (typeArg->type, typeArg->type, 0);
  9672.       if ((i > 4) || (i == -1)) {
  9673.         error (invocation, "One of the arguments in 'Type [Type, Type, ...]' has a size that is not 4 bytes or smaller");
  9674.         error2 (typeArg, "Here is the argument that is causing the problem");
  9675.         error2 (typeParm, "This type parameter was used in a variable declaration somewhere within the class; this restricts it to being instantiated only with types of size 4 bytes or smaller");
  9676.       }
  9677.     }
  9678.     typeParm = typeParm->next;
  9679.     typeArg = typeArg->next;
  9680.   }
  9681. }
  9682.  
  9683.  
  9684.  
  9685. // checkForPrimitive (sendExpr, t, PRIMITIVE_I_OP, PRIMITIVE_D_OP)
  9686. //
  9687. // This routine is passed a sendExpr and the type of the receiver.  It checks
  9688. // to see if the type of the receiver and argument are correct for a binary
  9689. // operator.  If so, it sets the "primitiveSymbol" field accordingly.
  9690. //
  9691. // This routine will also insert coercions as necessary.
  9692. //
  9693. // This routine returns the type of the result, or NULL if this is not an
  9694. // instance of the primitive type.
  9695. //
  9696. // An example call (after checking that the selector is "PLUS") would be:
  9697. //       resultType = check (sendExpr, t, PRIMITIVE_I_ADD, PRIMITIVE_D_ADD);
  9698. //
  9699. Type * checkForPrimitive (SendExpr * sendExpr,
  9700.                           Type * recvrType,
  9701.                           int PRIMITIVE_I_OP,
  9702.                           int PRIMITIVE_D_OP) {
  9703.   Type * t2, * resultType;
  9704.  
  9705.   if (argCount (sendExpr->argList) == 1) {
  9706.     t2 = checkTypes (sendExpr->argList->expr);
  9707.     if (t2 == NULL) return basicVoidType;
  9708.     if (isIntType (recvrType)) {
  9709.       if (isIntType (t2)) {
  9710.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9711.         return basicIntType;
  9712.       } else if (isCharType (t2)) {
  9713.         sendExpr->argList->expr = insertCharToInt (sendExpr->argList->expr);
  9714.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9715.         return basicIntType;
  9716.       } else if (isDoubleType (t2)) {
  9717.         sendExpr->receiver = insertIntToDouble (sendExpr->receiver);
  9718.         sendExpr->primitiveSymbol = PRIMITIVE_D_OP;
  9719.         return basicDoubleType;
  9720.       } else {
  9721.         error (sendExpr, "This built-in operator expects the right operand to be char, int or double");
  9722.         return basicIntType;
  9723.       }
  9724.     } else if (isDoubleType (recvrType)) {
  9725.       if (isIntType (t2)) {
  9726.         sendExpr->argList->expr = insertIntToDouble (sendExpr->argList->expr);
  9727.         sendExpr->primitiveSymbol = PRIMITIVE_D_OP;
  9728.         return basicDoubleType;
  9729.       } else if (isDoubleType (t2)) {
  9730.         sendExpr->primitiveSymbol = PRIMITIVE_D_OP;
  9731.         return basicDoubleType;
  9732.       } else {
  9733.         error (sendExpr, "This built-in operator expects the right operand to be int or double");
  9734.         return basicDoubleType;
  9735.       }
  9736.     } else if (isCharType (recvrType)) {
  9737.       if (isIntType (t2)) {
  9738.         sendExpr->receiver = insertCharToInt (sendExpr->receiver);
  9739.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9740.         return basicIntType;
  9741.       } else if (isCharType (t2)) {
  9742.         sendExpr->receiver = insertCharToInt (sendExpr->receiver);
  9743.         sendExpr->argList->expr = insertCharToInt (sendExpr->argList->expr);
  9744.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9745.         return basicIntType;
  9746.       } else {
  9747.         error (sendExpr, "This built-in operator expects the right operand to be char or int");
  9748.         return basicIntType;
  9749.       }
  9750.     }
  9751.   }
  9752.   return NULL;
  9753. }
  9754.  
  9755.  
  9756.  
  9757. // checkForPrimitive2 (sendExpr, t, PRIMITIVE_I_OP)
  9758. //
  9759. // This routine is passed a sendExpr and the type of the receiver.  It checks
  9760. // to see if the type of the receiver and argument are correct for a binary
  9761. // operator.  If so, it sets the "primitiveSymbol" field accordingly.
  9762. //
  9763. // This routine will also insert coercions as necessary.
  9764. //
  9765. // This routine returns the type of the result, or NULL if this is not an
  9766. // instance of the primitive type.
  9767. //
  9768. // An example call (after checking that the selector is "PERCENT") would be:
  9769. //       resultType = check (sendExpr, t, PRIMITIVE_I_REM);
  9770. //
  9771. Type * checkForPrimitive2 (SendExpr * sendExpr,
  9772.                           Type * recvrType,
  9773.                           int PRIMITIVE_I_OP) {
  9774.   Type * t2, * resultType;
  9775.  
  9776.   if (argCount (sendExpr->argList) == 1) {
  9777.     t2 = checkTypes (sendExpr->argList->expr);
  9778.     if (t2 == NULL) return basicVoidType;
  9779.     if (isIntType (recvrType)) {
  9780.       if (isIntType (t2)) {
  9781.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9782.         return basicIntType;
  9783.       } else if (isCharType (t2)) {
  9784.         sendExpr->argList->expr = insertCharToInt (sendExpr->argList->expr);
  9785.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9786.         return basicIntType;
  9787.       } else {
  9788.         error (sendExpr, "This built-in operator expects the right operand to be char or int");
  9789.         return basicIntType;
  9790.       }
  9791.     } else if (isCharType (recvrType)) {
  9792.       if (isIntType (t2)) {
  9793.         sendExpr->receiver = insertCharToInt (sendExpr->receiver);
  9794.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9795.         return basicIntType;
  9796.       } else if (isCharType (t2)) {
  9797.         sendExpr->receiver = insertCharToInt (sendExpr->receiver);
  9798.         sendExpr->argList->expr = insertCharToInt (sendExpr->argList->expr);
  9799.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9800.         return basicIntType;
  9801.       } else {
  9802.         error (sendExpr, "This built-in operator expects the right operand to be char or int");
  9803.         return basicIntType;
  9804.       }
  9805.     }
  9806.   }
  9807.   return NULL;
  9808. }
  9809.  
  9810.  
  9811.  
  9812. // checkForPrimitive3 (sendExpr, t, PRIMITIVE_I_OP, PRIMITIVE_D_OP)
  9813. //
  9814. // This routine is passed a sendExpr and the type of the receiver.  It checks
  9815. // to see if the type of the receiver and argument are correct for a binary
  9816. // operator.  If so, it sets the "primitiveSymbol" field accordingly.
  9817. //
  9818. // This routine will also insert coercions as necessary.
  9819. //
  9820. // This routine returns the type of the result, or NULL if this is not an
  9821. // instance of the primitive type.
  9822. //
  9823. // An example call (after checking that the selector is "LESS") would be:
  9824. //       resultType = check (sendExpr, t, PRIMITIVE_I_LT, PRIMITIVE_D_LT);
  9825. //
  9826. Type * checkForPrimitive3 (SendExpr * sendExpr,
  9827.                           Type * recvrType,
  9828.                           int PRIMITIVE_I_OP,
  9829.                           int PRIMITIVE_D_OP) {
  9830.   Type * t2, * resultType;
  9831.  
  9832.   if (argCount (sendExpr->argList) == 1) {
  9833.     t2 = checkTypes (sendExpr->argList->expr);
  9834.     if (t2 == NULL) return basicVoidType;
  9835.     if (isIntType (recvrType)) {
  9836.       if (isIntType (t2)) {
  9837.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9838.         return basicBoolType;
  9839.       } else if (isCharType (t2)) {
  9840.         sendExpr->argList->expr = insertCharToInt (sendExpr->argList->expr);
  9841.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9842.         return basicBoolType;
  9843.       } else if (isDoubleType (t2)) {
  9844.         sendExpr->receiver = insertIntToDouble (sendExpr->receiver);
  9845.         sendExpr->primitiveSymbol = PRIMITIVE_D_OP;
  9846.         return basicBoolType;
  9847. //    Implicit ptr->int coercion is no longer allowed...
  9848. //      } else if (isPtrType (t2)) {
  9849. //        if (safe) {
  9850. //          error (sendExpr, "Comparing ints to ptrs is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  9851. //        }
  9852. //        sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9853. //        return basicBoolType;
  9854.       } else {
  9855.         error (sendExpr, "This built-in operator expects the right operand to be char, int or double");
  9856.         return basicBoolType;
  9857.       }
  9858.     } else if (isPtrType (recvrType)) {
  9859. //      if (isIntType (t2)) {
  9860. //        if (safe) {
  9861. //          error (sendExpr, "Comparing ptrs to ints is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  9862. //        }
  9863. //        sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9864. //        return basicBoolType;
  9865. //      } else
  9866.       if (isPtrType (t2)) {
  9867.         if (safe) {
  9868.           error (sendExpr, "Comparing ptrs to ptrs is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  9869.         }
  9870.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9871.         return basicBoolType;
  9872.       } else {
  9873.         error (sendExpr, "This built-in operator expects the right operand to be a ptr");
  9874.         return basicBoolType;
  9875.       }
  9876.     } else if (isDoubleType (recvrType)) {
  9877.       if (isIntType (t2)) {
  9878.         sendExpr->argList->expr = insertIntToDouble (sendExpr->argList->expr);
  9879.         sendExpr->primitiveSymbol = PRIMITIVE_D_OP;
  9880.         return basicBoolType;
  9881.       } else if (isDoubleType (t2)) {
  9882.         sendExpr->primitiveSymbol = PRIMITIVE_D_OP;
  9883.         return basicBoolType;
  9884.       } else {
  9885.         error (sendExpr, "This built-in operator expects the right operand to be int or double");
  9886.         return basicBoolType;
  9887.       }
  9888.     } else if (isCharType (recvrType)) {
  9889.       if (isIntType (t2)) {
  9890.         sendExpr->receiver = insertCharToInt (sendExpr->receiver);
  9891.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9892.         return basicBoolType;
  9893.       } else if (isCharType (t2)) {
  9894.         sendExpr->receiver = insertCharToInt (sendExpr->receiver);
  9895.         sendExpr->argList->expr = insertCharToInt (sendExpr->argList->expr);
  9896.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9897.         return basicBoolType;
  9898.       } else {
  9899.         error (sendExpr, "This built-in operator expects the right operand to be char or int");
  9900.         return basicBoolType;
  9901.       }
  9902.     }
  9903.   }
  9904.   return NULL;
  9905. }
  9906.  
  9907.  
  9908.  
  9909. // checkForPrimitive4 (sendExpr, t, PRIMITIVE_B_OP)
  9910. //
  9911. // This routine is passed a sendExpr and the type of the receiver.  It checks
  9912. // to see if the type of the receiver and argument are correct for a binary
  9913. // operator.  If so, it sets the "primitiveSymbol" field accordingly.
  9914. //
  9915. // This routine will also insert coercions as necessary.
  9916. //
  9917. // This routine returns the type of the result, or NULL if this is not an
  9918. // instance of the primitive type.
  9919. //
  9920. // An example call (after checking that the selector is "AMP") would be:
  9921. //       resultType = check (sendExpr, t, PRIMITIVE_B_AND);
  9922. //
  9923. Type * checkForPrimitive4 (SendExpr * sendExpr,
  9924.                           Type * recvrType,
  9925.                           int PRIMITIVE_B_OP) {
  9926.   Type * t2, * resultType;
  9927.  
  9928.   if (argCount (sendExpr->argList) == 1) {
  9929.     t2 = checkTypes (sendExpr->argList->expr);
  9930.     if (t2 == NULL) return basicVoidType;
  9931.     if (isBoolType (recvrType)) {
  9932.       if (isBoolType (t2)) {
  9933.         sendExpr->primitiveSymbol = PRIMITIVE_B_OP;
  9934.         return basicBoolType;
  9935.       } else if (isPtrType (t2)) {
  9936.         sendExpr->argList->expr = insertPtrToBool (sendExpr->argList->expr);
  9937.         sendExpr->primitiveSymbol = PRIMITIVE_B_OP;
  9938.         return basicBoolType;
  9939.       } else {
  9940.         error (sendExpr, "This built-in operator expects the right operand to be bool or ptr");
  9941.         return basicBoolType;
  9942.       }
  9943.     } else if (isPtrType (recvrType)) {
  9944.       if (isBoolType (t2)) {
  9945.         sendExpr->receiver = insertPtrToBool (sendExpr->receiver);
  9946.         sendExpr->primitiveSymbol = PRIMITIVE_B_OP;
  9947.         return basicBoolType;
  9948.       } else if (isPtrType (t2)) {
  9949.         sendExpr->receiver = insertPtrToBool (sendExpr->receiver);
  9950.         sendExpr->argList->expr = insertPtrToBool (sendExpr->argList->expr);
  9951.         sendExpr->primitiveSymbol = PRIMITIVE_B_OP;
  9952.         return basicBoolType;
  9953.       } else {
  9954.         error (sendExpr, "This built-in operator expects the right operand to be bool or ptr");
  9955.         return basicBoolType;
  9956.       }
  9957.     }
  9958.   }
  9959.   return NULL;
  9960. }
  9961.  
  9962.  
  9963.  
  9964. // checkForPrimitive5 (sendExpr, t, PRIMITIVE_I_OP, PRIMITIVE_D_OP,
  9965. //                                  PRIMITIVE_B_OP, PRIMITIVE_OBJ_OP)
  9966. //
  9967. // This routine is passed a sendExpr and the type of the receiver.  It checks
  9968. // to see if the type of the receiver and argument are correct for a binary
  9969. // operator.  If so, it sets the "primitiveSymbol" field accordingly.
  9970. //
  9971. // This routine will also insert coercions as necessary.
  9972. //
  9973. // This routine returns the type of the result, or NULL if this is not an
  9974. // instance of the primitive type.
  9975. //
  9976. // An example call (after checking that the selector is "EQUAL") would be:
  9977. //       resultType = check (sendExpr, t, PRIMITIVE_I_EQ, PRIMITIVE_D_EQ, PRIMITIVE_B_EQ);
  9978. //
  9979. Type * checkForPrimitive5 (SendExpr * sendExpr,
  9980.                           Type * recvrType,
  9981.                           int PRIMITIVE_I_OP,
  9982.                           int PRIMITIVE_D_OP,
  9983.                           int PRIMITIVE_B_OP,
  9984.                           int PRIMITIVE_OBJ_OP) {
  9985.   Type * t2, * resultType, * t1;
  9986.   ClassDef * cl1, * cl2;
  9987.   AstNode * def1, * def2;
  9988.  
  9989.   if (argCount (sendExpr->argList) == 1) {
  9990.     t2 = checkTypes (sendExpr->argList->expr);
  9991.     if (t2 == NULL) return basicVoidType;
  9992.     if (isIntType (recvrType)) {
  9993.       if (isIntType (t2)) {
  9994.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9995.         return basicBoolType;
  9996.       } else if (isCharType (t2)) {
  9997.         sendExpr->argList->expr = insertCharToInt (sendExpr->argList->expr);
  9998.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  9999.         return basicBoolType;
  10000.       } else if (isDoubleType (t2)) {
  10001.         sendExpr->receiver = insertIntToDouble (sendExpr->receiver);
  10002.         sendExpr->primitiveSymbol = PRIMITIVE_D_OP;
  10003.         return basicBoolType;
  10004. //    Implicit int->ptr coercion is no longer allowed
  10005. //      } else if (isPtrType (t2)) {
  10006. //        if (safe) {
  10007. //          error (sendExpr, "Comparing ints to ptrs is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  10008. //        }
  10009. //        sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  10010. //        return basicBoolType;
  10011.       } else if (isTypeOfNullType (t2)) {
  10012.         sendExpr->argList->expr = insertZero (sendExpr->argList->expr);
  10013.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  10014.         return basicBoolType;
  10015.       } else {
  10016.         error (sendExpr, "This built-in operator expects the right operand to be char, int or double");
  10017.         return basicBoolType;
  10018.       }
  10019.     } else if (isDoubleType (recvrType)) {
  10020.       if (isIntType (t2)) {
  10021.         sendExpr->argList->expr = insertIntToDouble (sendExpr->argList->expr);
  10022.         sendExpr->primitiveSymbol = PRIMITIVE_D_OP;
  10023.         return basicBoolType;
  10024.       } else if (isDoubleType (t2)) {
  10025.         sendExpr->primitiveSymbol = PRIMITIVE_D_OP;
  10026.         return basicBoolType;
  10027.       } else {
  10028.         error (sendExpr, "This built-in operator expects the right operand to be int or double");
  10029.         return basicBoolType;
  10030.       }
  10031.     } else if (isCharType (recvrType)) {
  10032.       if (isIntType (t2)) {
  10033.         sendExpr->receiver = insertCharToInt (sendExpr->receiver);
  10034.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  10035.         return basicBoolType;
  10036.       } else if (isCharType (t2)) {
  10037.         // sendExpr->receiver = insertCharToInt (sendExpr->receiver);
  10038.         // sendExpr->argList->expr = insertCharToInt (sendExpr->argList->expr);
  10039.         // sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  10040.         sendExpr->primitiveSymbol = PRIMITIVE_B_OP;
  10041.         return basicBoolType;
  10042.       } else {
  10043.         error (sendExpr, "This built-in operator expects the right operand to be char or int");
  10044.         return basicBoolType;
  10045.       }
  10046.     } else if (isBoolType (recvrType)) {
  10047.       if (isBoolType (t2)) {
  10048.         sendExpr->primitiveSymbol = PRIMITIVE_B_OP;
  10049.         return basicBoolType;
  10050.       } else if (isPtrType (t2)) {
  10051.         sendExpr->argList->expr = insertPtrToBool (sendExpr->argList->expr);
  10052.         sendExpr->primitiveSymbol = PRIMITIVE_B_OP;
  10053.         return basicBoolType;
  10054.       } else if (isTypeOfNullType (t2)) {
  10055.         sendExpr->argList->expr = insertFalse (sendExpr->argList->expr);
  10056.         sendExpr->primitiveSymbol = PRIMITIVE_B_OP;
  10057.         return basicBoolType;
  10058.       } else {
  10059.         error (sendExpr, "This built-in operator expects the right operand to be a bool or ptr");
  10060.         return basicBoolType;
  10061.       }
  10062.     } else if (isPtrType (recvrType)) {
  10063.       if (isBoolType (t2)) {
  10064.         sendExpr->receiver = insertPtrToBool (sendExpr->receiver);
  10065.         sendExpr->primitiveSymbol = PRIMITIVE_B_OP;
  10066.         return basicBoolType;
  10067. //    Implicit int->ptr coercion is no longer allowed
  10068. //      } else if (isIntType (t2)) {
  10069. //        sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  10070. //        if (safe) {
  10071. //          error (sendExpr, "Comparing ints to ptrs is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  10072. //        }
  10073. //        return basicBoolType;
  10074.       } else if (isPtrType (t2)) {
  10075.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  10076.         return basicBoolType;
  10077.       } else if (isTypeOfNullType (t2)) {
  10078.         sendExpr->argList->expr = insertZero (sendExpr->argList->expr);
  10079.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  10080.         return basicBoolType;
  10081.       } else {
  10082.         error (sendExpr, "This built-in operator expects the right operand to be a bool or ptr");
  10083.         return basicBoolType;
  10084.       }
  10085.     } else if (isTypeOfNullType (recvrType)) {
  10086.       if (isBoolType (t2)) {
  10087.         sendExpr->receiver = insertFalse (sendExpr->receiver);
  10088.         sendExpr->primitiveSymbol = PRIMITIVE_B_OP;
  10089.         return basicBoolType;
  10090.       } else if (isPtrType (t2)) {
  10091.         sendExpr->receiver = insertZero (sendExpr->receiver);
  10092.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  10093.         return basicBoolType;
  10094.       } else if (isTypeOfNullType (t2)) {
  10095.         sendExpr->receiver = insertZero (sendExpr->receiver);
  10096.         sendExpr->argList->expr = insertZero (sendExpr->argList->expr);
  10097.         sendExpr->primitiveSymbol = PRIMITIVE_I_OP;
  10098.         return basicBoolType;
  10099.       } else {
  10100.         error (sendExpr, "This built-in operator expects the right operand to be a bool or ptr");
  10101.         return basicBoolType;
  10102.       }
  10103.  
  10104.     } else if (isObjectType (recvrType)) {
  10105.       if (! isObjectType (t2)) {
  10106.         error (sendExpr, "This built-in operator expects the right operand to be an object");
  10107.         errorWithType ("The type of the right operand is", t2);
  10108.         return basicBoolType;
  10109.       }
  10110.       if ((! isSubType (recvrType, t2)) && (! isSubType (t2, recvrType))) {
  10111.         error (sendExpr, "When comparing objects, the types of the two operands must be related but are not");
  10112.         errorWithType ("The type of the left operand is", recvrType);
  10113.         errorWithType ("The type of the right operand is", t2);
  10114.         return basicBoolType;
  10115.       }
  10116.       sendExpr->primitiveSymbol = PRIMITIVE_OBJ_OP;
  10117.       return basicBoolType;
  10118.     }
  10119.   }
  10120.   return NULL;
  10121. }
  10122.  
  10123.  
  10124.  
  10125. // checkMessageSend (methodProto, sendExpr, recvrType, subst) --> retType
  10126. //
  10127. // This routine checks that this send has arguments of appropriate types for
  10128. // the given MethodProto.  It returns the return type.
  10129. //
  10130. // The substitution is applied to the methodProto.
  10131. //
  10132. Type * checkMessageSend (MethodProto * methodProto,
  10133.                          SendExpr * sendExpr,
  10134.                          Type * recvrType,
  10135.                          Mapping<TypeParm,Type> * subst) {
  10136.   Parameter * parm;
  10137.   Argument * arg;
  10138.  
  10139.   if (methodProto == NULL) {
  10140.     error (sendExpr, "This message is not understood by this type of receiver (2)");
  10141.     errorWithType ("The type of the receiver is", recvrType);
  10142.     return NULL;
  10143.   }
  10144.  
  10145.   // Put a ptr in the SendExpr back to the MethodProto...
  10146.   sendExpr->myProto = methodProto;
  10147.  
  10148.   // printf ("Looking at sendExpr = ");
  10149.   // pretty (sendExpr);
  10150.   // printf ("        methodProto = ");
  10151.   // pretty (methodProto);
  10152.  
  10153.   // Run through the arguments and make sure they are assignment compatible
  10154.   // with the expected parameter types...
  10155.  
  10156.   // They should have the same kind...
  10157.   if (sendExpr->kind != methodProto->kind) {
  10158.     programLogicError ("Kind mismatch in checkMessageSend");
  10159.   }
  10160.  
  10161.   // Make sure each arg type is assignment-compatible with the parm type...
  10162.   parm = methodProto->parmList;
  10163.   arg = sendExpr->argList;
  10164.   while (1) {
  10165.     if ((parm == NULL) && (arg == NULL)) break;
  10166.     if (arg == NULL) {
  10167.       error (sendExpr, "You are missing one or more arguments in this message-send");
  10168.       error2 (parm, "Here is a parameter for which there is no argument");
  10169.       break;
  10170.     }
  10171.     if (parm == NULL) {
  10172.       error (sendExpr, "You have supplied too many arguments in this message-send");
  10173.       error2 (methodProto, "Here is the method prototype");
  10174.       break;
  10175.     }
  10176.     arg->expr = checkAssignment (
  10177.                       arg->expr,
  10178.                       copyTypeWithSubst (parm->type, subst),
  10179.                       "The type of this argument is not assignable to the type of the corresponding parameter",
  10180.                       NULL
  10181.                                 );
  10182.     arg->offset = parm->offset;
  10183.     arg->sizeInBytes = parm->sizeInBytes;
  10184.     parm = (Parameter *) parm->next;
  10185.     arg = arg->next;
  10186.   }
  10187.  
  10188.   // Update "maxArgBytesSoFar"..
  10189.   updateMaxArgBytes (methodProto->totalParmSize);
  10190.   updateMaxArgBytes (sizeInBytesOfWhole(methodProto->retType,
  10191.                                                 methodProto->retType,
  10192.                                                 0));    // wantPrinting = 0
  10193.  
  10194.   // Return the type that this message returns...
  10195.   return copyTypeWithSubst (methodProto->retType, subst);
  10196. }
  10197.  
  10198.  
  10199.  
  10200. // checkAssignment (expr, expectedType, errorMsg, assignStmt) --> modifiedExpr
  10201. //
  10202. // This routine is passed an expression and an expected type.  It checks to make
  10203. // sure that this expression is "assignment compatible" with this type.  If not,
  10204. // it prints the given error message.
  10205. //
  10206. // If we need to insert an implicit coercion to make this expression into the
  10207. // correct type, this is done and the modified expression is returned.
  10208. //
  10209. // Here are the implicit coercions and the functions to be inserted:
  10210. //
  10211. //    int -> double         INT_TO_DOUBLE
  10212. //    char -> int           CHAR_TO_INT
  10213. //    ptr -> bool           PTR_TO_BOOL
  10214. //    nullType -> bool      false-constant
  10215. //    nullType -> ptr       nop
  10216. // ---int -> ptr            nop (unsafe)       -- No longer allowed
  10217. // ---ptr -> int            nop (unsafe)       -- No longer allowed
  10218. //
  10219. // If we are checking an Assignment statement, then "assignStmt" will point
  10220. // to the node we are checking.  When this routine is used for something besides an
  10221. // assignment statement, "assignStmt" will be null.
  10222. //
  10223. Expression * checkAssignment (Expression * expr,
  10224.                               Type * expectedType,
  10225.                               char * errorMsg,
  10226.                               AssignStmt * assignStmt) {
  10227.   Type * t;
  10228.   BoolConst * falseConst;
  10229.   int i, j;
  10230.   ClassDef * classDef;
  10231.   ArrayType * aType1, * aType2;
  10232.   DynamicCheck * dynamicCheck;
  10233.  
  10234.   // printf ("Calling checkAssignment with expr = ");
  10235.   // pretty (expr);
  10236.   // printf ("                     expectedType = ");
  10237.   // pretty (expectedType);
  10238.  
  10239.   t = checkTypes (expr);
  10240.   if (t == NULL) return expr;
  10241.  
  10242.   // Perform the implicit the int->double coercion, if necessary...
  10243.   if (isIntType (t) && isDoubleType (expectedType)) {
  10244.     return insertIntToDouble (expr);
  10245.   }
  10246.  
  10247.   // Perform the implicit the char->int coercion, if necessary...
  10248.   if (isCharType (t) && isIntType (expectedType)) {
  10249.     return insertCharToInt (expr);
  10250.   }
  10251.  
  10252.   // Perform the implicit the ptr->bool coercion, if necessary...
  10253.   if (isPtrType (t) && isBoolType (expectedType)) {
  10254.     return insertPtrToBool (expr);
  10255.   }
  10256.  
  10257.   // Perform the implicit the NullType->bool coercion, if necessary...
  10258.   if (isTypeOfNullType (t) && isBoolType (expectedType)) {
  10259.     falseConst = new BoolConst (0);    // Replace with "false"
  10260.     falseConst->positionAt (expr);
  10261.     return falseConst;
  10262.   }
  10263.  
  10264.   // For the implicit the NullType->ptr coercion, do nothing;
  10265.   // It will pass the assignable test below and we should insert nothing...
  10266.   //      if (isTypeOfNullType (t) && isPtrType (expectedType)) {
  10267.   //        return expr;             // nop coercion
  10268.   //      }
  10269.  
  10270. //  // Perform the implicit the int->ptr coercion...  No longer allowed.
  10271. //  if (isIntType (t) && isPtrType (expectedType)) {
  10272. //    if (safe) {
  10273. //      error (expr, "Using an int when a ptr is expected is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  10274. //    }
  10275. //    return expr;             // nop coercion
  10276. //  }
  10277.  
  10278. //  // Perform the implicit the ptr->int coercion...  No longer allowed.
  10279. //  if (isPtrType (t) && isIntType (expectedType)) {
  10280. //    if (safe) {
  10281. //      error (expr, "Using a ptr when an int is expected is an unsafe operation; you must compile with the 'unsafe' option if you wish to do this");
  10282. //    }
  10283. //    return expr;             // nop coercion
  10284. //  }
  10285.  
  10286.   // OBJECT ASSIGNMENT:
  10287.   //         *objPtr = *objPtr
  10288.   //         *objPtr = ...
  10289.   //         ...     = *objPtr
  10290.   if (assignStmt &&
  10291.       isObjectType (t) &&
  10292.       isObjectType (expectedType) &&
  10293.       (isDeref (expr) || isDeref (assignStmt->lvalue))) {
  10294.  
  10295.     // Case 1: OBJECT ASSIGNMENT: *objPtr = *objPtr...
  10296.     if (isDeref (expr) && isDeref (assignStmt->lvalue)) {
  10297.       //   printf ("===> OBJECT ASSIGNMENT: *objPtr = *objPtr...\n");
  10298.       if (! isSubType (expectedType, t) &&
  10299.           ! isSubType (t, expectedType)) {
  10300.         error (assignStmt->lvalue, "In this object assignment, there is no subtype relation between the left-hand side type and the right-hand side type; this object copy cannot succeed at runtime");
  10301.         errorWithType ("The type of the left-hand side is", expectedType);
  10302.         errorWithType ("The type of the right-hand side is", t);
  10303.         return expr;
  10304.       }
  10305.       // We can just check class name, e.g., List ?= List.  Since we have already
  10306.       // checked that a subtype relation holds, we can't have something
  10307.       // like "List[Person] ?= List[Student]...
  10308.       //    printf ("     Need to insert dynamic check that both point to same class of object at runtime.\n");
  10309.       //    printf ("     Will perform a 'dynamic' object copy.\n");
  10310.       assignStmt->dynamicCheck = 1;
  10311.       return expr;
  10312.  
  10313.     // Case 2: OBJECT ASSIGNMENT: *objPtr = x...
  10314.     } else if (isDeref (assignStmt->lvalue)) {
  10315.       //   printf ("===> OBJECT ASSIGNMENT: *objPtr = x...\n");
  10316.       if (! isSubType (t, expectedType)) {
  10317.         error (assignStmt->lvalue, "In this object assignment, there is a type error; the pointer on the left-hand side cannot possibly point to an object of the same class as on the right-hand side");
  10318.         errorWithType ("The type of the left-hand side is", expectedType);
  10319.         errorWithType ("The type of the right-hand side is", t);
  10320.         return expr;
  10321.       }
  10322.       // We can just check class name, e.g., List ?= List.  Since we have already
  10323.       // checked that a subtype relation holds, we can't have something
  10324.       // like "List[Person] ?= List[Student]...
  10325.       //   printf ("     Inserting dynamic class check to check that *objPtr has class: ");
  10326.       //   pretty (t);
  10327.       classDef = getClassDef (t);
  10328.       if (classDef == NULL) {
  10329.         error (expr, errorMsg);
  10330.         error2 (expr, "This object assignment calls for a dynamic class-check, but the type of this expression is not a class");
  10331.         errorWithType ("The type of the expression is", t);
  10332.         errorWithType ("The expected type is", expectedType);
  10333.         return expr;
  10334.       }
  10335.       //   printf ("     Will copy %d bytes.\n", classDef->sizeInBytes);
  10336.       assignStmt->dynamicCheck = 2;
  10337.       assignStmt->classDef = classDef;
  10338.       return expr;
  10339.  
  10340.     // Case 3: OBJECT ASSIGNMENT: x = *objPtr...
  10341.     } else {
  10342.       //   printf ("===> OBJECT ASSIGNMENT: x = *objPtr...\n");
  10343.       if (! isSubType (expectedType, t)) {
  10344.         error (assignStmt->lvalue, "In this object assignment, there is a type error; the pointer on the right-hand side cannot possibly point to an object of the same class as on the left-hand side");
  10345.         errorWithType ("The type of the left-hand side is", expectedType);
  10346.         errorWithType ("The type of the right-hand side is", t);
  10347.         return expr;
  10348.       }
  10349.       // We can just check class name, e.g., List ?= List.  Since we have already
  10350.       // checked that a subtype relation holds, we can't have something
  10351.       // like "List[Person] ?= List[Student]...
  10352.       //   printf ("     Inserting dynamic class check to check that *objPtr has class: ");
  10353.       //   pretty (expectedType);
  10354.       classDef = getClassDef (expectedType);
  10355.       if (classDef == NULL) {
  10356.         error (expr, errorMsg);
  10357.         error2 (expr, "This object assignment calls for a dynamic class-check, but the type of this expression is not a class");
  10358.         errorWithType ("The type of the expression is", t);
  10359.         errorWithType ("The expected type is", expectedType);
  10360.         return expr;
  10361.       }
  10362.       //   printf ("     Will copy %d bytes.\n", classDef->sizeInBytes);
  10363.       assignStmt->dynamicCheck = 3;
  10364.       assignStmt->classDef = classDef;
  10365.       return expr;
  10366.     }
  10367.  
  10368.   // ARRAY ASSIGNMENT: array = array
  10369.   } else if (assignStmt &&
  10370.       (aType1 = getArrayType (expectedType)) &&
  10371.       (aType2 = getArrayType (t))) {
  10372.     // Make sure the base types are type-equal...
  10373.     if (!typesEqual (aType1->baseType, aType2->baseType)) {
  10374.       error (assignStmt->lvalue, "In this array assignment statement, the types of the array elements must be the same");
  10375.       errorWithType ("The type of the left-hand side is", aType1);
  10376.       errorWithType ("The type of the right-hand side is", aType2);
  10377.       return expr;
  10378.     }
  10379.  
  10380.     // Here are the possible cases...
  10381.     //    arr[10] = arr[10]
  10382.     //    arr[10] = arr[*]
  10383.     //    arr[*] = arr[10]
  10384.     //    arr[*] = arr[*]
  10385.  
  10386.     // Case 4: ARRAY ASSIGNMENT: arr[10] = arr[10]...
  10387.     if ((aType1->sizeInBytes >= 0) && (aType2->sizeInBytes >= 0)) {
  10388.       //   printf ("===> ARRAY ASSIGNMENT: arr[10] = arr[10]...\n");
  10389.       //   printf ("     Will copy %d bytes.\n", aType1->sizeInBytes);
  10390.       // Check that the sizes are equal...
  10391.       if (aType1->sizeInBytes != aType2->sizeInBytes) {
  10392.         error (assignStmt->lvalue, "In this array assignment statement, the sizes of the array are not the same");
  10393.         errorWithType ("The type of the left-hand side is", aType1);
  10394.         errorWithType ("The type of the right-hand side is", aType2);
  10395.         return expr;
  10396.       }
  10397.       if (aType1->sizeExpr->op == INT_CONST) {
  10398.         i = ((IntConst *) (aType1->sizeExpr))->ivalue;
  10399.       } else {
  10400.         programLogicError ("Array size must be known if sizeInBytes is known (1)");
  10401.       }
  10402.       assignStmt->dynamicCheck = 4;
  10403.       assignStmt->arraySize = i;
  10404.       return expr;
  10405.  
  10406.     // Case 5: ARRAY ASSIGNMENT: arr[10] = arr[*]...
  10407.     } else if (aType1->sizeInBytes >= 0) {
  10408.       //   printf ("===> ARRAY ASSIGNMENT: arr[10] = arr[*]...\n");
  10409.       if (aType1->sizeExpr->op == INT_CONST) {
  10410.         i = ((IntConst *) (aType1->sizeExpr))->ivalue;
  10411.       } else {
  10412.         programLogicError ("Array size must be known if sizeInBytes is known (2)");
  10413.       }
  10414.       //   printf ("     Need to insert dynamic size check (that N = %d) for source array size.\n", i);
  10415.       //   printf ("     Will copy %d bytes.\n", aType1->sizeInBytes);
  10416.       assignStmt->dynamicCheck = 5;
  10417.       assignStmt->arraySize = i;
  10418.       return expr;
  10419.  
  10420.     // Case 6: ARRAY ASSIGNMENT: arr[*] = arr[10]...
  10421.     } else if (aType2->sizeInBytes >= 0) {
  10422.       //   printf ("===> ARRAY ASSIGNMENT: arr[*] = arr[10]...\n");
  10423.       if (aType2->sizeExpr->op == INT_CONST) {
  10424.         i = ((IntConst *) (aType2->sizeExpr))->ivalue;
  10425.         assignStmt->sizeInBytes = aType2->sizeInBytes;
  10426.       } else {
  10427.         programLogicError ("Array size must be known if sizeInBytes is known (3)");
  10428.       }
  10429.       //   printf ("     Need to insert dynamic size check (that N = %d) for destination array size...\n", i);
  10430.       //   printf ("     Will copy %d bytes.\n", aType2->sizeInBytes);
  10431.       assignStmt->dynamicCheck = 6;
  10432.       assignStmt->arraySize = i;
  10433.       return expr;
  10434.  
  10435.     // Case 7: ARRAY ASSIGNMENT: arr[*] = arr[*]...
  10436.     } else {
  10437.       //   printf ("===> ARRAY ASSIGNMENT: arr[*] = arr[*]...\n");
  10438.       //   printf ("     Need to insert dynamic array copy (size not known at compile time)...\n");
  10439.       //   printf ("     Must check that sizes are equal at runtime.\n");
  10440.       i = aType1->sizeOfElements;
  10441.       //   printf ("     Will copy 4 + N * %d bytes. (ok to round up to multiple of 4 at runtime)\n", i);
  10442.       assignStmt->dynamicCheck = 7;
  10443.       assignStmt->arraySize = i;         // Store the size of each element
  10444.       return expr;
  10445.     }
  10446.  
  10447.   } else {   // This is not an Assignment Statement...
  10448.  
  10449.     // Case 8: OBJECT COPY: ... := *objPtr
  10450.     if (isDeref (expr) && isObjectType (t)) {
  10451.       //   printf ("===> OBJECT COPY: ... := *objPtr\n");
  10452.       // Make sure that we are expecting a class type.
  10453.       classDef = getClassDef (expectedType);
  10454.       if (classDef == NULL) {
  10455.         error (expr, errorMsg);
  10456.         error2 (expr, "Dereferencing a ptr to an object calls for dynamic class-check, but the expected type is not a class");
  10457.         errorWithType ("The type of the expression is", t);
  10458.         errorWithType ("The expected type is", expectedType);
  10459.         return expr;
  10460.       }
  10461.       if (!isSubType (expectedType, t)) {
  10462.         error (expr, errorMsg);
  10463.         errorWithType ("This expression cannot point to the expected class of object; at runtime the class of the object will be... (or one of its subclasses)", t);
  10464.         errorWithType ("The expected class is", expectedType);
  10465.         return expr;
  10466.       }
  10467.       // We can just check class name, e.g., List ?= List.  Since we have already
  10468.       // checked that a subtype relation holds, we can't have something
  10469.       // like "List[Person] ?= List[Student]...
  10470.       // Note: the expected type may contain TypeParms, e.g., "ListImpl2[T1]"...
  10471.       //   printf ("     Need to insert dynamic check that this expr has class: ");
  10472.       //   pretty (expectedType);
  10473.       // Need to insert something...
  10474.       if (expr->op != DYNAMIC_CHECK) {
  10475.         dynamicCheck = new DynamicCheck ();
  10476.         dynamicCheck->positionAt (expr);
  10477.         dynamicCheck->expr = expr;
  10478.         dynamicCheck->kind = 8;
  10479.         dynamicCheck->expectedClassDef = classDef;
  10480.         return dynamicCheck;
  10481.       } else {
  10482.         return expr;
  10483.       }
  10484.  
  10485.  
  10486.     // ARRAY COPY: ... := array
  10487.     } else if ((aType1 = getArrayType (expectedType)) &&
  10488.                (aType2 = getArrayType (t))) {
  10489.       // Make sure the base types are type-equal...
  10490.       if (!typesEqual (aType1->baseType, aType2->baseType)) {
  10491.         error (expr, errorMsg);
  10492.         error2 (expr, "When copying an array, the types of the array elements must be the same");
  10493.         errorWithType ("The type of the expression is", aType1);
  10494.         errorWithType ("The expected type is", aType2);
  10495.         return expr;
  10496.       }
  10497.  
  10498.       // Here are the possible cases...
  10499.       //    arr[10] = arr[10]
  10500.       //    arr[10] = arr[*]
  10501.       //    arr[*] = arr[10]
  10502.       //    arr[*] = arr[*]
  10503.  
  10504.       // Case 9: ARRAY COPY: arr[10] = arr[10]...
  10505.       if ((aType1->sizeInBytes >= 0) && (aType2->sizeInBytes >= 0)) {
  10506.         //   printf ("===> ARRAY COPY: arr[10] := arr[10]...\n");
  10507.         // Check that the sizes are equal...
  10508.         if (aType1->sizeInBytes != aType2->sizeInBytes) {
  10509.           error (expr, errorMsg);
  10510.           error2 (expr, "When copying an array, the array sizes must be the same");
  10511.           errorWithType ("The type of the expression is", aType2);
  10512.           errorWithType ("The expected type is", aType1);
  10513.           return expr;
  10514.         }
  10515.         //   printf ("     Will copy %d bytes.\n", aType1->sizeInBytes);
  10516.         if (aType1->sizeExpr->op == INT_CONST) {
  10517.           i = ((IntConst *) (aType1->sizeExpr))->ivalue;
  10518.         } else {
  10519.           programLogicError ("Array size must be known if sizeInBytes is known (3)");
  10520.         }
  10521.         // Need to add something into the AST...
  10522.         if (expr->op != DYNAMIC_CHECK) {
  10523.           dynamicCheck = new DynamicCheck ();
  10524.           dynamicCheck->positionAt (expr);
  10525.           dynamicCheck->expr = expr;
  10526.           dynamicCheck->kind = 9;
  10527.           dynamicCheck->arraySizeInBytes = aType1->sizeInBytes;
  10528.           dynamicCheck->expectedArraySize = i;
  10529.           return dynamicCheck;
  10530.         } else {
  10531.           return expr;
  10532.         }
  10533.  
  10534.       // Case 10: ARRAY COPY: arr[10] = arr[*]
  10535.       } else if (aType1->sizeInBytes >= 0) {
  10536.         //   printf ("===> ARRAY COPY: arr[10] := arr[*]...\n");
  10537.         if (aType1->sizeExpr->op == INT_CONST) {
  10538.           i = ((IntConst *) (aType1->sizeExpr))->ivalue;
  10539.         } else {
  10540.           programLogicError ("Array size must be known if sizeInBytes is known (4)");
  10541.         }
  10542.         //   printf ("     Need to insert dynamic size check (that N = %d) for source array size.\n", i);
  10543.         //   printf ("     Will copy %d bytes.\n", aType1->sizeInBytes);
  10544.         // Need to add something into the AST...
  10545.         if (expr->op != DYNAMIC_CHECK) {
  10546.           dynamicCheck = new DynamicCheck ();
  10547.           dynamicCheck->positionAt (expr);
  10548.           dynamicCheck->expr = expr;
  10549.           dynamicCheck->kind = 10;
  10550.           dynamicCheck->expectedArraySize = i;
  10551.           dynamicCheck->arraySizeInBytes = aType1->sizeInBytes;
  10552.           return dynamicCheck;
  10553.         } else {
  10554.           return expr;
  10555.         }
  10556.  
  10557.       // Case 11: ARRAY COPY: arr[*] = arr[10]
  10558.       } else if (aType2->sizeInBytes >= 0) {
  10559.         //   printf ("===> ARRAY COPY: arr[*] := arr[10]...\n");
  10560.         // This case should never be possible (unless other errors), since
  10561.         // expectedType comes from, e.g., parm type, and such a type cannot
  10562.         // be a dynamic array.
  10563.         error (expr, errorMsg);
  10564.         error2 (expr, "In array copy, the target type must not be a dynamic array (1)");
  10565.         errorWithType ("The type of the expression is", aType2);
  10566.         errorWithType ("The expected type is", aType1);
  10567.         return expr;
  10568.  
  10569.       // Case 12: ARRAY COPY: arr[*] = arr[*]
  10570.       } else {
  10571.         //   printf ("===> ARRAY COPY: arr[*] := arr[*]...\n");
  10572.         // This case should never be possible (unless other errors), since
  10573.         // expectedType comes from, e.g., parm type, and such a type cannot
  10574.         // be a dynamic array.
  10575.         error (expr, errorMsg);
  10576.         error2 (expr, "In array copy, the target type must not be a dynamic array (2)");
  10577.         errorWithType ("The type of the expression is", aType2);
  10578.         errorWithType ("The expected type is", aType1);
  10579.         return expr;
  10580.       }
  10581.  
  10582.     }
  10583.   }
  10584.  
  10585.   //    if (isPtrType (expectedType)) {
  10586.   //    printf ("expectedType = ");
  10587.   //    pretty (expectedType);
  10588.   //    printf ("expr = ");
  10589.   //    pretty (expr);
  10590.   //    printf ("t = ");
  10591.   //    pretty (t);
  10592.   //    }
  10593.  
  10594.   // Check the type...
  10595.   if (! assignable (expectedType, t)) {
  10596.     error (expr, errorMsg);
  10597.     errorWithType ("The type of the expression is", t);
  10598.     errorWithType ("The expected type is", expectedType);
  10599.     return expr;
  10600.   }
  10601.  
  10602.   i = sizeInBytesOfWhole (t, expr, 1);
  10603.   if (i <= 0) {
  10604.     error (expr, errorMsg);
  10605.     errorWithType ("I cannot determine the size of the type of this expr, which is",
  10606.                    t);
  10607.   }
  10608.  
  10609.   j = sizeInBytesOfWhole (expectedType, expr, 1);
  10610.   if (j <= 0) {
  10611.     error (expr, errorMsg);
  10612.     errorWithType ("I cannot determine the size of the expected type, which is",
  10613.                    expectedType);
  10614.   }
  10615.  
  10616.   if (i>0 && j>0 && i != j) {
  10617.     printf ("expr = ");
  10618.     pretty (expr);
  10619.     printf ("t = ");
  10620.     pretty (expr);
  10621.     printf ("expectedType = ");
  10622.     pretty (expectedType);
  10623.     programLogicError ("Two types are assignable, but have different sizes");
  10624.   }
  10625.  
  10626.   return expr;
  10627. }
  10628.  
  10629.  
  10630.  
  10631. // insertIntToDouble (expr) --> expr
  10632. //
  10633. // This routine wraps an "intToDouble" node around the argument and returns it.
  10634. //
  10635. Expression * insertIntToDouble (Expression * expr) {
  10636.   CallExpr * callExpr;
  10637.   Argument * arg;
  10638.  
  10639.   arg = new Argument ();
  10640.   arg->positionAt (expr);
  10641.   arg->expr = expr;
  10642.  
  10643.   callExpr = new CallExpr ();
  10644.   callExpr->positionAt (expr);
  10645.   callExpr->id = stringIntToDouble;
  10646.   callExpr->argList = arg;
  10647.   // callExpr->myDef = 0;
  10648.   callExpr->primitiveSymbol = PRIMITIVE_INT_TO_DOUBLE;
  10649.   // updateMaxArgBytes (8); // allocate frame space, in case we insert a real call
  10650.   return callExpr;
  10651.  
  10652. }
  10653.  
  10654.  
  10655.  
  10656. // insertIntIsZero (expr) --> expr
  10657. //
  10658. // This routine wraps an "intIsZero" node around the argument and returns it.
  10659. //
  10660. Expression * insertIntIsZero (Expression * expr) {
  10661.   CallExpr * callExpr;
  10662.   Argument * arg;
  10663.  
  10664.   arg = new Argument ();
  10665.   arg->positionAt (expr);
  10666.   arg->expr = expr;
  10667.  
  10668.   callExpr = new CallExpr ();
  10669.   callExpr->positionAt (expr);
  10670.   callExpr->id = stringIIsZero;
  10671.   callExpr->argList = arg;
  10672.   // callExpr->myDef = 0;
  10673.   callExpr->primitiveSymbol = PRIMITIVE_I_IS_ZERO;
  10674.   // updateMaxArgBytes (4); // allocate frame space, in case we insert a real call
  10675.   return callExpr;
  10676.  
  10677. }
  10678.  
  10679.  
  10680.  
  10681. // insertIntNotZero (expr) --> expr
  10682. //
  10683. // This routine wraps an "intNotZero" node around the argument and returns it.
  10684. //
  10685. Expression * insertIntNotZero (Expression * expr) {
  10686.   CallExpr * callExpr;
  10687.   Argument * arg;
  10688.  
  10689.   arg = new Argument ();
  10690.   arg->positionAt (expr);
  10691.   arg->expr = expr;
  10692.  
  10693.   callExpr = new CallExpr ();
  10694.   callExpr->positionAt (expr);
  10695.   callExpr->id = stringINotZero;
  10696.   callExpr->argList = arg;
  10697.   // callExpr->myDef = 0;
  10698.   callExpr->primitiveSymbol = PRIMITIVE_I_NOT_ZERO;
  10699.   // updateMaxArgBytes (4); // allocate frame space, in case we insert a real call
  10700.   return callExpr;
  10701.  
  10702. }
  10703.  
  10704.  
  10705.  
  10706. // insertCharToInt (expr) --> expr
  10707. //
  10708. // This routine wraps an "charToInt" node around the argument and returns it.
  10709. //
  10710. Expression * insertCharToInt (Expression * expr) {
  10711.   CallExpr * callExpr;
  10712.   Argument * arg;
  10713.  
  10714.   arg = new Argument ();
  10715.   arg->positionAt (expr);
  10716.   arg->expr = expr;
  10717.  
  10718.   callExpr = new CallExpr ();
  10719.   callExpr->positionAt (expr);
  10720.   callExpr->id = stringCharToInt;
  10721.   callExpr->argList = arg;
  10722.   // callExpr->myDef = 0;
  10723.   callExpr->primitiveSymbol = PRIMITIVE_CHAR_TO_INT;
  10724.   // updateMaxArgBytes (4); // allocate frame space, in case we insert a real call
  10725.   return callExpr;
  10726.  
  10727. }
  10728.  
  10729.  
  10730.  
  10731. // insertPtrToBool (expr) --> expr
  10732. //
  10733. // This routine wraps an "ptrToBool" node around the argument and returns it.
  10734. //
  10735. Expression * insertPtrToBool (Expression * expr) {
  10736.   CallExpr * callExpr;
  10737.   Argument * arg;
  10738.  
  10739.   arg = new Argument ();
  10740.   arg->positionAt (expr);
  10741.   arg->expr = expr;
  10742.  
  10743.   callExpr = new CallExpr ();
  10744.   callExpr->positionAt (expr);
  10745.   callExpr->id = stringPtrToBool;
  10746.   callExpr->argList = arg;
  10747.   // callExpr->myDef = 0;
  10748.   callExpr->primitiveSymbol = PRIMITIVE_PTR_TO_BOOL;
  10749.   // updateMaxArgBytes (4); // allocate frame space, in case we insert a real call
  10750.   return callExpr;
  10751.  
  10752. }
  10753.  
  10754.  
  10755.  
  10756. // insertDeref (expr) --> expr
  10757. //
  10758. // This routine wraps an "deref" node around the argument and returns it.
  10759. //
  10760. Expression * insertDeref (Expression * expr) {
  10761.   SendExpr * sendExpr;
  10762.  
  10763.   sendExpr = new SendExpr ();
  10764.   sendExpr->positionAt (expr);
  10765.   sendExpr->selector = stringUnaryStar;
  10766.   sendExpr->kind = PREFIX;
  10767.   sendExpr->receiver = expr;
  10768.   // sendExpr->argList = NULL;
  10769.   sendExpr->primitiveSymbol = PRIMITIVE_DEREF;
  10770.   return sendExpr;
  10771.  
  10772. }
  10773.  
  10774.  
  10775.  
  10776. // isDeref (nade)
  10777. //
  10778. // This routine returns true if the given node is a DEREF node.  If there is
  10779. // any problem, it returns false.
  10780. //
  10781. int isDeref (AstNode * p) {
  10782.   if (p == NULL) return 0;
  10783.   if (p->op != SEND_EXPR) return 0;
  10784.   return ((SendExpr *) p) -> primitiveSymbol == PRIMITIVE_DEREF;
  10785. }
  10786.  
  10787.  
  10788.  
  10789. // isAddressOf (nade)
  10790. //
  10791. // This routine returns true if the given node is a ADDRESS_OF node.  If there is
  10792. // any problem, it returns false.
  10793. //
  10794. int isAddressOf (AstNode * p) {
  10795.   programLogicError ("Routine isAddressOf is never used");
  10796.   if (p == NULL) return 0;
  10797.   if (p->op != SEND_EXPR) return 0;
  10798.   return ((SendExpr *) p) -> primitiveSymbol == PRIMITIVE_ADDRESS_OF;
  10799. }
  10800.  
  10801.  
  10802.  
  10803. // insertFalse (expr) --> expr
  10804. //
  10805. // This routine returns a false constant.
  10806. //
  10807. Expression * insertFalse (Expression * expr) {
  10808.   BoolConst * boolConst;
  10809.  
  10810.   boolConst = new BoolConst (0);
  10811.   boolConst->positionAt (expr);
  10812.   return boolConst;
  10813.  
  10814. }
  10815.  
  10816.  
  10817.  
  10818. // insertTrue (expr) --> expr
  10819. //
  10820. // This routine returns a true constant.
  10821. //
  10822. Expression * insertTrue (Expression * expr) {
  10823.   BoolConst * boolConst;
  10824.  
  10825.   boolConst = new BoolConst (1);
  10826.   boolConst->positionAt (expr);
  10827.   return boolConst;
  10828.  
  10829. }
  10830.  
  10831.  
  10832.  
  10833. // insertZero (expr) --> expr
  10834. //
  10835. // This routine returns a zero constant.
  10836. //
  10837. Expression * insertZero (Expression * expr) {
  10838.   IntConst * intConst;
  10839.  
  10840.   intConst = new IntConst ();
  10841.   intConst->positionAt (expr);
  10842.   intConst->ivalue = 0;
  10843.   return intConst;
  10844.  
  10845. }
  10846.  
  10847.  
  10848.  
  10849. // argCount (argList)
  10850. //
  10851. // This routine returns the number of arguments in the given list.
  10852. //
  10853. int argCount (Argument * argList) {
  10854.   int n = 0;
  10855.   while (argList) {
  10856.     n++;
  10857.     argList = argList->next;
  10858.   }
  10859.   return n;
  10860. }
  10861.  
  10862.  
  10863.  
  10864. // isCharType (type)
  10865. //
  10866. // This routine returns true if the given type is "char" or if there is
  10867. // a problem.
  10868. //
  10869. // NOTE: The argument "type" may be a TypeParm, in which case we are asking
  10870. // whether the CONSTRAINT type is "char"; the actual type may be a
  10871. // subtype of this.  However, the only subtype of "char" is itself.
  10872. //
  10873. int isCharType (Type * type) {
  10874.   if ((type == NULL) || (type->op == CHAR_TYPE)) return 1;
  10875.   type = resolveNamedType (type);
  10876.   if ((type == NULL) || (type->op == CHAR_TYPE)) return 1;
  10877.   return 0;
  10878. }
  10879.  
  10880.  
  10881.  
  10882. // isIntType (type)
  10883. //
  10884. // This routine returns true if the given type is "int" or if there is
  10885. // a problem.
  10886. //
  10887. // NOTE: The argument "type" may be a TypeParm, in which case we are asking
  10888. // whether the CONSTRAINT type is "int"; the actual type may be a
  10889. // subtype of this.  However, the only subtype of "int" is itself.
  10890. //
  10891. int isIntType (Type * type) {
  10892.   if ((type == NULL) || (type->op == INT_TYPE)) return 1;
  10893.   type = resolveNamedType (type);
  10894.   if ((type == NULL) || (type->op == INT_TYPE)) return 1;
  10895.   return 0;
  10896. }
  10897.  
  10898.  
  10899.  
  10900. // isDoubleType (type)
  10901. //
  10902. // This routine returns true if the given type is "double" or if there is
  10903. // a problem.
  10904. //
  10905. // NOTE: The argument "type" may be a TypeParm, in which case we are asking
  10906. // whether the CONSTRAINT type is "double"; the actual type may be a
  10907. // subtype of this.  However, the only subtype of "double" is itself.
  10908. //
  10909. int isDoubleType (Type * type) {
  10910.   if ((type == NULL) || (type->op == DOUBLE_TYPE)) return 1;
  10911.   type = resolveNamedType (type);
  10912.   if ((type == NULL) || (type->op == DOUBLE_TYPE)) return 1;
  10913.   return 0;
  10914. }
  10915.  
  10916.  
  10917.  
  10918. // isBoolType (type)
  10919. //
  10920. // This routine returns true if the given type is "bool" or if there is
  10921. // a problem.
  10922. //
  10923. // NOTE: The argument "type" may be a TypeParm, in which case we are asking
  10924. // whether the CONSTRAINT type is "bool"; the actual type may be a
  10925. // subtype of this.  However, the only subtype of "bool" is itself.
  10926. //
  10927. int isBoolType (Type * type) {
  10928.   if ((type == NULL) || (type->op == BOOL_TYPE)) return 1;
  10929.   type = resolveNamedType (type);
  10930.   if ((type == NULL) || (type->op == BOOL_TYPE)) return 1;
  10931.   return 0;
  10932. }
  10933.  
  10934.  
  10935.  
  10936. // isVoidType (type)
  10937. //
  10938. // This routine returns true if the given type is void or if there is
  10939. // a problem.
  10940. //
  10941. // NOTE: The argument "type" may be a TypeParm, in which case we are asking
  10942. // whether the CONSTRAINT type is "void"; the actual type may be a
  10943. // subtype of this.  However, the only subtype of "void" is itself.
  10944. //
  10945. int isVoidType (Type * type) {
  10946.   if ((type == NULL) || (type->op == VOID_TYPE)) return 1;
  10947.   type = resolveNamedType (type);
  10948.   if ((type == NULL) || (type->op == VOID_TYPE)) return 1;
  10949.   return 0;
  10950. }
  10951.  
  10952.  
  10953.  
  10954. // isTypeOfNullType (type)
  10955. //
  10956. // This routine returns true if the given type is "NULL_TYPE" or if there is
  10957. // a problem.
  10958. //
  10959. // NOTE: The argument "type" may be a TypeParm, in which case we are asking
  10960. // whether the CONSTRAINT type is "typeOfNull"; the actual type may be a
  10961. // subtype of this.  However, the only subtype of "typeOfNull" is itself.
  10962. //
  10963. int isTypeOfNullType (Type * type) {
  10964.   if ((type == NULL) || (type->op == TYPE_OF_NULL_TYPE)) return 1;
  10965.   type = resolveNamedType (type);
  10966.   if ((type == NULL) || (type->op == TYPE_OF_NULL_TYPE)) return 1;
  10967.   return 0;
  10968. }
  10969.  
  10970.  
  10971.  
  10972. // isAnyType (type)
  10973. //
  10974. // This routine returns true if the given type is "ANY_TYPE" or if there is
  10975. // a problem.
  10976. //
  10977. // NOTE: The argument "type" may be a TypeParm, in which case we are asking
  10978. // whether the CONSTRAINT type is "anyType"; the actual type may be a
  10979. // subtype of this!
  10980. //
  10981. int isAnyType (Type * type) {
  10982.  
  10983.   programLogicError ("NOTE: isAnyType is never invoked");
  10984.  
  10985.   if ((type == NULL) || (type->op == ANY_TYPE)) return 1;
  10986.   type = resolveNamedType (type);
  10987.   if ((type == NULL) || (type->op == ANY_TYPE)) return 1;
  10988.   return 0;
  10989. }
  10990.  
  10991.  
  10992.  
  10993. // isPtrType (type)
  10994. //
  10995. // This routine returns true if the given type is a "PTR_TYPE" or if there is
  10996. // a problem.
  10997. //
  10998. // NOTE: The argument "type" may be a TypeParm, in which case we are asking
  10999. // whether the CONSTRAINT type is a ptr type; Since the actual type must be a
  11000. // subtype of this, we know the actual type must be a ptr type (or typeOfNull).
  11001. //
  11002. int isPtrType (Type * type) {
  11003.   if (getPtrType (type) == NULL) return 0;
  11004.   return 1;
  11005. }
  11006.  
  11007.  
  11008.  
  11009. // isPtrToVoidType (type)
  11010. //
  11011. // This routine returns true if the given type is "ptr to void" or if there is
  11012. // a problem.
  11013. //
  11014. int isPtrToVoidType (Type * type) {
  11015.   PtrType * pType;
  11016.   pType = getPtrType (type);
  11017.   if (pType == NULL) return 0;
  11018.   return isVoidType (pType->baseType);
  11019. }
  11020.  
  11021.  
  11022.  
  11023. // getPtrType (type) --> PtrType
  11024. //
  11025. // If this type is a ptr type, then we return the PTR_TYPE node.  If not, we return
  11026. // NULL.
  11027. //
  11028. // NOTE: The arg may be a TypeParm, in which case we are returning the PTR_TYPE
  11029. // describing the CONSTRAINT type; the actual type could be any subtype of this!
  11030. //
  11031. // Returns NULL if any problems.
  11032. //
  11033. PtrType * getPtrType (Type * type) {
  11034.   if ((type == NULL) || (type->op == PTR_TYPE)) return (PtrType *) type;
  11035.   type = resolveNamedType (type);
  11036.   if ((type == NULL) || (type->op != PTR_TYPE)) return NULL;
  11037.   return (PtrType *) type;
  11038. }
  11039.  
  11040.  
  11041.  
  11042. // isRecordType (type)
  11043. //
  11044. // This routine returns true if the given type is a "RECORD_TYPE" or if there is
  11045. // a problem.
  11046. //
  11047. // NOTE: The argument "type" may be a TypeParm, in which case we are asking
  11048. // whether the CONSTRAINT type is "record"; the actual type may be a
  11049. // subtype of this.  However, the only subtype of "record" is itself.
  11050. //
  11051. int isRecordType (Type * type) {
  11052.   if ((type == NULL) || (type->op == RECORD_TYPE)) return 1;
  11053.   type = resolveNamedType (type);
  11054.   if ((type == NULL) || (type->op == RECORD_TYPE)) return 1;
  11055.   return 0;
  11056. }
  11057.  
  11058.  
  11059.  
  11060. // isArrayType (type)
  11061. //
  11062. // This routine returns true if the given type is a "ARRAY_TPYE" or if there is
  11063. // a problem.
  11064. //
  11065. int isArrayType (Type * type) {
  11066.   if (getArrayType (type) == NULL) return 0;
  11067.   return 1;
  11068. }
  11069.  
  11070.  
  11071.  
  11072. // getArrayType (type) --> ArrayType
  11073. //
  11074. // If this type is a array type, then we return the ARRAY_TYPE node.  If not, we
  11075. // return NULL.
  11076. //
  11077. // NOTE: The arg may be a TypeParm, in which case we are returning the ARRAY_TYPE
  11078. // describing the CONSTRAINT type; the actual type may be a subtype of this.
  11079. //
  11080. // Returns NULL if any problems.
  11081. //
  11082. ArrayType * getArrayType (Type * type) {
  11083.   if ((type == NULL) || (type->op == ARRAY_TYPE)) return (ArrayType *) type;
  11084.   type = resolveNamedType (type);
  11085.   if ((type == NULL) || (type->op != ARRAY_TYPE)) return NULL;
  11086.   return (ArrayType *) type;
  11087. }
  11088.  
  11089.  
  11090.  
  11091. // getFunctionType (type) --> FunctionType
  11092. //
  11093. // If this type is 'ptr to function', then we return the FUNCTION_TYPE node.
  11094. // If not, we return NULL.
  11095. //
  11096. // NOTE: The arg may be a TypeParm, in which case we are returning the FUNCTION_TYPE
  11097. // describing the CONSTRAINT type; the actual type will be any subtype of this!
  11098. //
  11099. // Returns NULL if any problems.
  11100. //
  11101. FunctionType * getFunctionType (Type * type) {
  11102.   PtrType * pType;
  11103.   Type * t;
  11104.  
  11105.   pType = getPtrType (type);
  11106.   if (pType == NULL) return NULL;
  11107.   t = pType->baseType;
  11108.   if ((t == NULL) || (t->op == FUNCTION_TYPE)) return (FunctionType *) t;
  11109.   t = resolveNamedType (t);
  11110.   if ((t == NULL) || (t->op != FUNCTION_TYPE)) return NULL;
  11111.   return (FunctionType *) t;
  11112. }
  11113.  
  11114.  
  11115.  
  11116. // isExactClass (type) --> bool
  11117. //
  11118. // If this type is a class, return TRUE.
  11119. // Returns FALSE if any problems.
  11120. //
  11121. // Note: calls resolveNamedType2; constraint types are not exact.
  11122. //
  11123. int isExactClass (Type * type) {
  11124.   NamedType * nType;
  11125.  
  11126.   programLogicError ("This routine tested, no longer used. Was used for isInstanceOf");
  11127.  
  11128.   type = resolveNamedType2 (type);
  11129.   if ((type == NULL) || (type->op != NAMED_TYPE)) return 0;
  11130.   nType = (NamedType *) type;
  11131.   if (nType->myDef == NULL) return 0;
  11132.   if (nType->myDef->op == CLASS_DEF) return 1;
  11133.   return 0;
  11134. }
  11135.  
  11136.  
  11137.  
  11138. // isObjectType (type) --> bool
  11139. //
  11140. // If this type is a class or interface, return TRUE.
  11141. // Returns FALSE if any problems.
  11142. //
  11143. int isObjectType (Type * type) {
  11144.   NamedType * nType;
  11145.   type = resolveNamedType (type);
  11146.   if ((type == NULL) || (type->op != NAMED_TYPE)) return 0;
  11147.   nType = (NamedType *) type;
  11148.   if (nType->myDef == NULL) return 0;
  11149.   if (nType->myDef->op == CLASS_DEF) return 1;
  11150.   if (nType->myDef->op == INTERFACE) return 1;
  11151.   return 0;
  11152. }
  11153.  
  11154.  
  11155.  
  11156. // getClassDef (type) --> ClassDef
  11157. //
  11158. // If this type names a specific class, then return the ClassDef it names.
  11159. // Otherwise, return NULL.
  11160. //
  11161. // If this type names a type parameter, e.g.,
  11162. //      t: Person
  11163. // then return NULL, since we are looking for a specific class,
  11164. // not a constraint.
  11165. //
  11166. ClassDef * getClassDef (Type * type) {
  11167.   NamedType * nType;
  11168.   type = resolveNamedType2 (type);
  11169.   if ((type == NULL) || (type->op != NAMED_TYPE)) return NULL;
  11170.   nType = (NamedType *) type;
  11171.   if (nType->myDef == NULL) return NULL;
  11172.   if (nType->myDef->op == CLASS_DEF) return (ClassDef *) nType->myDef;
  11173.   return NULL;
  11174. }
  11175.  
  11176.  
  11177.  
  11178. // getInterface (type) --> Interface
  11179. //
  11180. // If this type names a specific class, then return the Interface it names.
  11181. // Otherwise, return NULL.
  11182. //
  11183. // If this type names a type parameter, e.g.,
  11184. //      t: Person
  11185. // then return NULL, since we are looking for a specific interface,
  11186. // not a constraint.
  11187. //
  11188. Interface * getInterface (Type * type) {
  11189.   NamedType * nType;
  11190.   type = resolveNamedType2 (type);
  11191.   if ((type == NULL) || (type->op != NAMED_TYPE)) return NULL;
  11192.   nType = (NamedType *) type;
  11193.   if (nType->myDef == NULL) return NULL;
  11194.   if (nType->myDef->op == INTERFACE) return (Interface *) nType->myDef;
  11195.   return NULL;
  11196. }
  11197.  
  11198.  
  11199.  
  11200. // resolveNamedType (type) --> type
  11201. //
  11202. // If this type is a NamedType, this routine tries to determine the underlying type.
  11203. //   If it names a Typedef (e.g., "type T = ptr to int") we return the underlying type.
  11204. //   If it names a TypeParm, then we return the constraint type.
  11205. //   If it names a ClassDef or Interface, we return a ptr to the NamedType.
  11206. //   If it is another type (IntType, PtrType, etc.), it returns that.
  11207. //
  11208. // If there are problems, it returns NULL.
  11209. //
  11210. Type * resolveNamedType (Type * type) {
  11211.   AstNode * def;
  11212.  
  11213.   if (type == NULL) return NULL;
  11214.   if (type->op != NAMED_TYPE) return type;
  11215.   def = ((NamedType *) type)->myDef;
  11216.   if (def == NULL) return NULL;
  11217.  
  11218.   switch (def->op) {
  11219.  
  11220.     case INTERFACE:
  11221.     case CLASS_DEF:
  11222.       return type;
  11223.  
  11224.     case TYPE_PARM:
  11225.       return resolveNamedType (((TypeParm *) def)->type);
  11226.  
  11227.     case TYPE_DEF:
  11228.       return resolveNamedType (((TypeDef *) def)->type);
  11229.  
  11230.     default:
  11231.       printf ("\ndef->op = %s\n", symbolName (def->op));
  11232.       programLogicError ("Unexpected myDef->op in resolveNamedType");
  11233.   }
  11234. }
  11235.  
  11236.  
  11237.  
  11238. // resolveNamedType2 (type) --> type
  11239. //
  11240. // If this type is a NamedType, this routine tries to determine the underlying type.
  11241. //   If it names a Typedef (e.g., "type T = ptr to int") we return the underlying type.
  11242. //   If it names a TypeParm, return the NamedType.
  11243. //   If it names a ClassDef or Interface, return the NamedType.
  11244. //   If it is another type (IntType, PtrType, etc.), it returns that.
  11245. //
  11246. // If there are problems, it returns NULL.
  11247. //
  11248. Type * resolveNamedType2 (Type * type) {
  11249.   AstNode * def;
  11250.  
  11251.   if (type == NULL) return NULL;
  11252.   if (type->op != NAMED_TYPE) return type;
  11253.   def = ((NamedType *) type)->myDef;
  11254.   if (def == NULL) return NULL;
  11255.  
  11256.   switch (def->op) {
  11257.  
  11258.     case INTERFACE:
  11259.     case CLASS_DEF:
  11260.     case TYPE_PARM:
  11261.       return type;
  11262.  
  11263.     case TYPE_DEF:
  11264.       return resolveNamedType2 (((TypeDef *) def)->type);
  11265.  
  11266.     default:
  11267.       printf ("\ndef->op = %s\n", symbolName (def->op));
  11268.       programLogicError ("Unexpected myDef->op in resolveNamedType2");
  11269.  
  11270.   }
  11271. }
  11272.  
  11273.  
  11274.  
  11275. // checkConcreteClass (type, errorNode, errorMsg)
  11276. //
  11277. // This routine checks to make sure that "type" does not contain
  11278. // any Type Parameters.
  11279. //
  11280. // It also ensures that "type" is a class (not an interface).
  11281. // However, it may be an instantiated class:
  11282. //
  11283. // It is used in the following contexts:
  11284. //        new <type>
  11285. //        EXPR isInstanceOf TYPE
  11286. //
  11287. // Here are some examples of what is allowed:
  11288. //                int              -- Error
  11289. //                Person           -- Okay (where Person is a class)
  11290. //                Taxable          -- Error (where Taxable is an interface)
  11291. //                List [Person]    -- Okay (where List is a class)
  11292. //                List [Taxable]   -- Okay
  11293. //                Coll [Person]    -- Error (where Coll is an interface)
  11294. //                List [T1]        -- Error
  11295. //                T1               -- Error (where T1 is a TypeParm)
  11296. //
  11297. // If the type has a problem, then the "errorMsg" is printed out.
  11298. //
  11299. void checkConcreteClass (Type * type,
  11300.                          AstNode * errorNode,
  11301.                          char * errorMsg) {
  11302.   AstNode * def;
  11303.   NamedType * namedType;
  11304.   TypeArg * typeArg;
  11305.  
  11306.   if (type == NULL) return;
  11307.   if (type->op != NAMED_TYPE) {
  11308.     error (errorNode, errorMsg);
  11309.     errorWithType ("This type is causing the problem", type);
  11310.     return;
  11311.   }
  11312.  
  11313.   namedType = (NamedType *) type;
  11314.   def = namedType->myDef;
  11315.   if (def == NULL) return;
  11316.  
  11317.   switch (def->op) {
  11318.  
  11319.     case CLASS_DEF:
  11320.       // Check the type arguments if any...
  11321.       for (typeArg = namedType->typeArgs; typeArg; typeArg = typeArg->next) {
  11322.         checkConcreteType (typeArg->type, errorNode, errorMsg);
  11323.       }
  11324.       return;
  11325.  
  11326.     case INTERFACE:
  11327.       error (errorNode, errorMsg);
  11328.       errorWithType ("This interface is causing the problem", type);
  11329.       return;
  11330.  
  11331.     case TYPE_PARM:
  11332.       error (errorNode, errorMsg);
  11333.       errorWithType ("This type parameter is causing the problem", type);
  11334.       return;
  11335.  
  11336.     case TYPE_DEF:
  11337.       checkConcreteClass (((TypeDef *) def)->type, errorNode, errorMsg);
  11338.       return;
  11339.  
  11340.     default:
  11341.       printf ("\ndef->op = %s\n", symbolName (def->op));
  11342.       programLogicError ("Unexpected myDef->op in checkConcreteClass");
  11343.  
  11344.   }
  11345. }
  11346.  
  11347.  
  11348.  
  11349. // checkConcreteClassOrInterface (type, errorNode, errorMsg)
  11350. //
  11351. // This routine checks to make sure that "type" does not contain
  11352. // any Type Parameters.
  11353. //
  11354. // It also ensures that "type" is a class or an interface.
  11355. //
  11356. // It is used to check:
  11357. //        ... isKindOf <type>
  11358. //
  11359. // Here are some examples of what is allowed:
  11360. //                int              -- Error
  11361. //                Person           -- Okay (where Person is a class)
  11362. //                Taxable          -- Okay (where Taxable is an interface)
  11363. //                List [Person]    -- Okay (where List is a class)
  11364. //                List [Taxable]   -- Okay
  11365. //                Coll [Person]    -- Okay (where Coll is an interface)
  11366. //                List [T1]        -- Error
  11367. //                T1               -- Error (where T1 is a TypeParm)
  11368. //
  11369. // If the type has a problem, then the "errorMsg" is printed out.
  11370. //
  11371. void checkConcreteClassOrInterface (Type * type,
  11372.                                     AstNode * errorNode,
  11373.                                     char * errorMsg) {
  11374.   AstNode * def;
  11375.   NamedType * namedType;
  11376.   TypeArg * typeArg;
  11377.  
  11378.   if (type == NULL) return;
  11379.   if (type->op != NAMED_TYPE) {
  11380.     error (errorNode, errorMsg);
  11381.     errorWithType ("This type is causing the problem", type);
  11382.     return;
  11383.   }
  11384.  
  11385.   namedType = (NamedType *) type;
  11386.   def = namedType->myDef;
  11387.   if (def == NULL) return;
  11388.  
  11389.   switch (def->op) {
  11390.  
  11391.     case CLASS_DEF:
  11392.       // Check the type arguments if any...
  11393.       for (typeArg = namedType->typeArgs; typeArg; typeArg = typeArg->next) {
  11394.         checkConcreteType (typeArg->type, errorNode, errorMsg);
  11395.         // IMPLEMENTATION RESTRICTION: The type must not be parameterized:
  11396.         error (errorNode, errorMsg);
  11397.         errorWithType ("IMPLEMENTATION RESTRICTION: The type in IS-KIND-OF must not be parameterized", type);
  11398.       }
  11399.       return;
  11400.  
  11401.     case INTERFACE:
  11402.       // Check the type arguments if any...
  11403.       for (typeArg = namedType->typeArgs; typeArg; typeArg = typeArg->next) {
  11404.         checkConcreteType (typeArg->type, errorNode, errorMsg);
  11405.         // IMPLEMENTATION RESTRICTION: The type must not be parameterized:
  11406.         error (errorNode, errorMsg);
  11407.         errorWithType ("IMPLEMENTATION RESTRICTION: The type in IS-KIND-OF must not be parameterized", type);
  11408.       }
  11409.       return;
  11410.  
  11411.     case TYPE_PARM:
  11412.       error (errorNode, errorMsg);
  11413.       errorWithType ("This type parameter is causing the problem", type);
  11414.       return;
  11415.  
  11416.     case TYPE_DEF:
  11417.       checkConcreteClassOrInterface (((TypeDef *) def)->type, errorNode, errorMsg);
  11418.       return;
  11419.  
  11420.     default:
  11421.       printf ("\ndef->op = %s\n", symbolName (def->op));
  11422.       programLogicError ("Unexpected myDef->op in checkConcreteClassOrInterface");
  11423.  
  11424.   }
  11425. }
  11426.  
  11427.  
  11428.  
  11429. // checkConcreteType (type, errorNode, errorMsg)
  11430. //
  11431. // This routine checks to make sure that "type" does not contain
  11432. // any Type Parameters.
  11433. //
  11434. // Here are some examples of what is allowed:
  11435. //                int              -- Okay
  11436. //                Person           -- Okay (where Person is a class)
  11437. //                Taxable          -- Okay (where Taxable is an interface)
  11438. //                List [Person]    -- Okay (where List is a class)
  11439. //                List [Taxable]   -- Okay
  11440. //                Coll [Person]    -- Okay (where Coll is an interface)
  11441. //                T1               -- Error (where T1 is a TypeParm)
  11442. //                List [T1]        -- Error
  11443. //                Coll [T1]        -- Error
  11444. //
  11445. // If the type has a problem, then the "errorMsg" is printed out.
  11446. //
  11447. void checkConcreteType (Type * type,
  11448.                         AstNode * errorNode,
  11449.                         char * errorMsg) {
  11450.   AstNode * def;
  11451.   NamedType * namedType;
  11452.   TypeArg * typeArg;
  11453.  
  11454.   if (type == NULL) return;
  11455.   if (type->op != NAMED_TYPE) return;
  11456.  
  11457.   namedType = (NamedType *) type;
  11458.   def = namedType->myDef;
  11459.   if (def == NULL) return;
  11460.  
  11461.   switch (def->op) {
  11462.  
  11463.     case CLASS_DEF:
  11464.       // Check the type arguments if any...
  11465.       for (typeArg = namedType->typeArgs; typeArg; typeArg = typeArg->next) {
  11466.         checkConcreteType (typeArg->type, errorNode, errorMsg);
  11467.       }
  11468.       return;
  11469.  
  11470.     case INTERFACE:
  11471.       // Check the type arguments if any...
  11472.       for (typeArg = namedType->typeArgs; typeArg; typeArg = typeArg->next) {
  11473.         checkConcreteType (typeArg->type, errorNode, errorMsg);
  11474.       }
  11475.       return;
  11476.  
  11477.     case TYPE_PARM:
  11478.       error (errorNode, errorMsg);
  11479.       errorWithType ("This type parameter is causing the problem", type);
  11480.       return;
  11481.  
  11482.     case TYPE_DEF:
  11483.       checkConcreteType (((TypeDef *) def)->type, errorNode, errorMsg);
  11484.       return;
  11485.  
  11486.     default:
  11487.       printf ("\ndef->op = %s\n", symbolName (def->op));
  11488.       programLogicError ("Unexpected myDef->op in checkConcreteType");
  11489.  
  11490.   }
  11491. }
  11492.  
  11493.  
  11494.  
  11495. // isLValue (expr) --> bool
  11496. //
  11497. // This routine returns true if the given expression may be used as an L-Value.
  11498. // It does not check the expression or print error messages; it is assumed that
  11499. // we will call "checkTypes" on the expression elsewhere.
  11500. //
  11501. // If there are any problems, we assume this is an L-Value, in an attempt to
  11502. // reduce other error messages.
  11503. //
  11504. // An LValue is...
  11505. //       LValue --> Expr [ Expr ]
  11506. //              --> Expr . ID
  11507. //              --> * Expr           Where the expr has type ptr
  11508. //              --> ID               Where id is either a local, global,
  11509. //                                     parameter or classField
  11510. //
  11511. int isLValue (Expression * expr) {
  11512.   VariableExpr * var;
  11513.   SendExpr * sendExpr;
  11514.   AstNode * def;
  11515.   Type * t;
  11516.  
  11517.   if (expr == NULL) return 1;    // If error, assume it is an LValue
  11518.   if (expr->op == VARIABLE_EXPR) {
  11519.     var = (VariableExpr *) expr;
  11520.     def = var->myDef;
  11521.     if (def == NULL) return 1;    // If error, assume it is an LValue
  11522.     if ((def->op == LOCAL) ||
  11523.         (def->op == GLOBAL) ||
  11524.         (def->op == PARAMETER) ||
  11525.         (def->op == CLASS_FIELD)) {
  11526.       return 1;
  11527.     }
  11528.     return 0;
  11529.   }
  11530.   if (isDeref (expr)) {
  11531.     sendExpr = (SendExpr *) expr;
  11532.     t = checkTypes (sendExpr->receiver);  // This will give redundant error messages...
  11533.     if (isPtrType (t)) return 1;
  11534.     return 0;
  11535.   }
  11536.   if (expr->op == ARRAY_ACCESS) return 1;
  11537.   if (expr->op == FIELD_ACCESS) return 1;
  11538.   return 0;
  11539. }
  11540.  
  11541.  
  11542. // updateMaxArgBytes (i)
  11543. //
  11544. // This routine updates the global variable "maxArgBytesSoFar" if a new
  11545. // maximum is found.
  11546. //
  11547. void updateMaxArgBytes (int i) {
  11548.   if (i > maxArgBytesSoFar) {
  11549.     maxArgBytesSoFar = i;
  11550.   }
  11551. }
  11552.  
  11553.  
  11554.  
  11555. // fallsThru (node)
  11556. //
  11557. // This routine is passed a pointer to a fragment of the AST.  It walks
  11558. // walks this branch of the AST.
  11559. //
  11560. // If this branch is a statement, it returns TRUE if it might possibly fall through,
  11561. // and FALSE if it will never fall through.
  11562. //
  11563. // If this branch is not a statement, it doesn't really matter what we return;
  11564. // but we will return FALSE.
  11565. //
  11566. int fallsThru (AstNode * node) {
  11567.     Header * header;
  11568.     Code * code;
  11569.     Uses * uses;
  11570.     Renaming * renaming;
  11571.     Interface * interface;
  11572.     ClassDef * cl;
  11573.     Behavior * behavior;
  11574.     TypeDef * typeDef;
  11575.     ConstDecl * constDecl;
  11576.     ErrorDecl * errorDecl;
  11577.     FunctionProto * functionProto;
  11578.     Function * fun;
  11579.     MethodProto * methodProto;
  11580.     Method * meth;
  11581.     TypeParm * typeParm;
  11582.     TypeArg * typeArg;
  11583.     CharType * charType;
  11584.     IntType * intType;
  11585.     DoubleType * doubleType;
  11586.     BoolType * boolType;
  11587.     VoidType * voidType;
  11588.     TypeOfNullType * typeOfNullType;
  11589.     AnyType * anyType;
  11590.     PtrType * pType;
  11591.     ArrayType * aType;
  11592.     RecordType * rType;
  11593.     FunctionType * fType;
  11594.     NamedType * nType;
  11595.     IfStmt * ifStmt;
  11596.     AssignStmt * assignStmt;
  11597.     CallStmt * callStmt;
  11598.     SendStmt * sendStmt;
  11599.     WhileStmt * whileStmt;
  11600.     DoStmt * doStmt;
  11601.     BreakStmt * breakStmt;
  11602.     ContinueStmt * continueStmt;
  11603.     ReturnStmt * returnStmt;
  11604.     ForStmt * forStmt;
  11605.     SwitchStmt * switchStmt;
  11606.     TryStmt * tryStmt;
  11607.     ThrowStmt * throwStmt;
  11608.     FreeStmt * freeStmt;
  11609.     DebugStmt * debugStmt;
  11610.     Case * cas;
  11611.     Catch * cat;
  11612.     Global * global;
  11613.     Local * local;
  11614.     Parameter * parm;
  11615.     ClassField * classField;
  11616.     RecordField * recordField;
  11617.     IntConst * intConst;
  11618.     DoubleConst * doubleConst;
  11619.     CharConst * charConst;
  11620.     StringConst * stringConst;
  11621.     BoolConst * boolConst;
  11622.     NullConst * nullConst;
  11623.     CallExpr * callExpr;
  11624.     SendExpr * sendExpr;
  11625.     SelfExpr * selfExpr;
  11626.     SuperExpr * superExpr;
  11627.     FieldAccess * fieldAccess;
  11628.     ArrayAccess * arrayAccess;
  11629.     Constructor * constructor;
  11630.     ClosureExpr * closureExpr;
  11631.     VariableExpr * var;
  11632.     AsPtrToExpr * asPtrToExpr;
  11633.     AsIntegerExpr * asIntegerExpr;
  11634.     ArraySizeExpr * arraySizeExpr;
  11635.     IsInstanceOfExpr * isInstanceOfExpr;
  11636.     IsKindOfExpr * isKindOfExpr;
  11637.     SizeOfExpr * sizeOfExpr;
  11638.     DynamicCheck * dynamicCheck;
  11639.     Argument * arg;
  11640.     CountValue * countValue;
  11641.     FieldInit * fieldInit;
  11642.     int falls, falls2;
  11643.     Statement * stmt;
  11644.  
  11645.   if (node == NULL) return 0;
  11646.  
  11647.   // printf ("%s...\n", symbolName (node->op));
  11648.  
  11649.   switch (node->op) {
  11650.  
  11651.     case HEADER:
  11652.       header = (Header *) node;
  11653.       // printf ("  %s\n", header->packageName->chars);
  11654.       fallsThru (header->uses);
  11655.       fallsThru (header->consts);
  11656.       fallsThru (header->errors);
  11657.       fallsThru (header->globals);
  11658.       fallsThru (header->typeDefs);
  11659.       fallsThru (header->functionProtos);
  11660.       fallsThru (header->functions);
  11661.       fallsThru (header->closures);
  11662.       fallsThru (header->interfaces);
  11663.       fallsThru (header->classes);
  11664.       // fallsThru (header->next);
  11665.       return 0;
  11666.  
  11667. //    case CODE:
  11668. //      code = (Code *) node;
  11669. //      fallsThru (code->consts);
  11670. //      fallsThru (code->errors);
  11671. //      fallsThru (code->globals);
  11672. //      fallsThru (code->typeDefs);
  11673. //      fallsThru (code->functions);
  11674. //      fallsThru (code->interfaces);
  11675. //      fallsThru (code->classes);
  11676. //      fallsThru (code->behaviors);
  11677. //      return 0;
  11678.  
  11679.     case USES:
  11680.       uses = (Uses *) node;
  11681.       fallsThru (uses->renamings);
  11682.       fallsThru (uses->next);
  11683.       return 0;
  11684.  
  11685.     case RENAMING:
  11686.       renaming = (Renaming *) node;
  11687.       fallsThru (renaming->next);
  11688.       return 0;
  11689.  
  11690.     case INTERFACE:
  11691.       interface = (Interface *) node;
  11692.       // printf ("  %s\n", interface->id->chars);
  11693.       fallsThru (interface->typeParms);
  11694.       fallsThru (interface->extends);
  11695.       fallsThru (interface->methodProtos);
  11696.       fallsThru (interface->next);
  11697.       return 0;
  11698.  
  11699.     case CLASS_DEF:
  11700.       cl = (ClassDef *) node;
  11701.       // printf ("  %s\n", cl->id->chars);
  11702.       fallsThru (cl->typeParms);
  11703.       fallsThru (cl->implements);
  11704.       fallsThru (cl->superclass);
  11705.       fallsThru (cl->fields);
  11706.       fallsThru (cl->methodProtos);
  11707.       fallsThru (cl->methods);
  11708.       fallsThru (cl->next);
  11709.       return 0;
  11710.  
  11711. //    case BEHAVIOR:
  11712. //      behavior = (Behavior *) node;
  11713. //      printf ("  %s\n", behavior->id->chars);
  11714. //      fallsThru (behavior->methods);
  11715. //      fallsThru (behavior->next);
  11716. //      return 0;
  11717.  
  11718.     case TYPE_DEF:
  11719.       typeDef = (TypeDef *) node;
  11720.       // printf ("  %s\n", typeDef->id->chars);
  11721.       fallsThru (typeDef->type);
  11722.       fallsThru (typeDef->next);
  11723.       return 0;
  11724.  
  11725.     case CONST_DECL:
  11726.       constDecl = (ConstDecl *) node;
  11727.       // printf ("  %s\n", constDecl->id->chars);
  11728.       fallsThru (constDecl->expr);
  11729.       fallsThru (constDecl->next);
  11730.       return 0;
  11731.  
  11732.     case ERROR_DECL:
  11733.       errorDecl = (ErrorDecl *) node;
  11734.       // printf ("  %s\n", errorDecl->id->chars);
  11735.       fallsThru (errorDecl->parmList);
  11736.       fallsThru (errorDecl->next);
  11737.       return 0;
  11738.  
  11739.     case FUNCTION_PROTO:
  11740.       functionProto = (FunctionProto *) node;
  11741.       // printf ("  %s\n", functionProto->id->chars);
  11742.       fallsThru (functionProto->parmList);
  11743.       fallsThru (functionProto->retType);
  11744.       fallsThru (functionProto->next);
  11745.       return 0;
  11746.  
  11747.     case FUNCTION:
  11748.       fun = (Function *) node;
  11749.       // printf ("  %s\n", fun->id->chars);
  11750.       fallsThru (fun->parmList);
  11751.       fallsThru (fun->retType);
  11752.       fallsThru (fun->locals);
  11753.       falls = fallsThruStmtList (fun->stmts);
  11754.       if (falls) {
  11755.         if (isVoidType (fun->retType)) {
  11756.           returnStmt = new ReturnStmt ();
  11757.           returnStmt->positionAt (fun);
  11758.           returnStmt->enclosingMethOrFunction = fun;
  11759.           if (fun->stmts) {
  11760.             for (stmt=fun->stmts; stmt->next; stmt = stmt->next) {
  11761.             }
  11762.             stmt->next = returnStmt;
  11763.             returnStmt->positionAt (stmt);
  11764.           } else {
  11765.             fun->stmts = returnStmt;
  11766.           }
  11767.         } else {
  11768.           error (fun, "Execution may fall through the bottom of this function; please add a RETURN statement (with return-expression)");
  11769.         }
  11770.       }
  11771.       fallsThru (fun->next);
  11772.       return 0;
  11773.  
  11774.     case METHOD_PROTO:
  11775.       methodProto = (MethodProto *) node;
  11776.       // printf ("  %s\n", methodProto->selector->chars);
  11777.       fallsThru (methodProto->parmList);
  11778.       fallsThru (methodProto->retType);
  11779.       fallsThru (methodProto->next);
  11780.       return 0;
  11781.  
  11782.     case METHOD:
  11783.       meth = (Method *) node;
  11784.       // printf ("  %s\n", meth->selector->chars);
  11785.       fallsThru (meth->parmList);
  11786.       fallsThru (meth->retType);
  11787.       fallsThru (meth->locals);
  11788.       falls = fallsThruStmtList (meth->stmts);
  11789.       if (falls) {
  11790.         if (isVoidType (meth->retType)) {
  11791.           returnStmt = new ReturnStmt ();
  11792.           returnStmt->positionAt (meth);
  11793.           returnStmt->enclosingMethOrFunction = meth;
  11794.           if (meth->stmts) {
  11795.             for (stmt= meth->stmts; stmt->next; stmt = stmt->next) {
  11796.             }
  11797.             stmt->next = returnStmt;
  11798.             returnStmt->positionAt (stmt);
  11799.           } else {
  11800.             meth->stmts = returnStmt;
  11801.           }
  11802.         } else {
  11803.           error (meth, "Execution may fall through the bottom of this method; please add a RETURN statement (with return-expression)");
  11804.         }
  11805.       }
  11806.       fallsThru (meth->next);
  11807.       return 0;
  11808.  
  11809.     case TYPE_PARM:
  11810.       typeParm = (TypeParm *) node;
  11811.       fallsThru (typeParm->type);
  11812.       fallsThru (typeParm->next);
  11813.       return 0;
  11814.  
  11815.     case TYPE_ARG:
  11816.       typeArg = (TypeArg *) node;
  11817.       fallsThru (typeArg->type);
  11818.       fallsThru (typeArg->next);
  11819.       return 0;
  11820.  
  11821.     case CHAR_TYPE:
  11822.     case INT_TYPE:
  11823.     case DOUBLE_TYPE:
  11824.     case BOOL_TYPE:
  11825.     case VOID_TYPE:
  11826.     case TYPE_OF_NULL_TYPE:
  11827.     case ANY_TYPE:
  11828.       return 0;
  11829.  
  11830.     case PTR_TYPE:
  11831.       pType = (PtrType *) node;
  11832.       fallsThru (pType->baseType);
  11833.       return 0;
  11834.  
  11835.     case ARRAY_TYPE:
  11836.       aType = (ArrayType *) node;
  11837.       fallsThru (aType->sizeExpr);
  11838.       fallsThru (aType->baseType);
  11839.       return 0;
  11840.  
  11841.     case RECORD_TYPE:
  11842.       rType = (RecordType *) node;
  11843.       fallsThru (rType->fields);
  11844.       return 0;
  11845.  
  11846.     case FUNCTION_TYPE:
  11847.       fType = (FunctionType *) node;
  11848.       fallsThru (fType->parmTypes);
  11849.       fallsThru (fType->retType);
  11850.       return 0;
  11851.  
  11852.     case NAMED_TYPE:
  11853.       nType = (NamedType *) node;
  11854.       fallsThru (nType->typeArgs);
  11855.       return 0;
  11856.  
  11857.     case IF_STMT:
  11858.       ifStmt = (IfStmt *) node;
  11859.       fallsThru (ifStmt->expr);
  11860.       falls = fallsThruStmtList (ifStmt->thenStmts);
  11861.       falls2 = fallsThruStmtList (ifStmt->elseStmts);
  11862.       return falls || falls2;
  11863.  
  11864.     case ASSIGN_STMT:
  11865.       assignStmt = (AssignStmt *) node;
  11866.       fallsThru (assignStmt->lvalue);
  11867.       fallsThru (assignStmt->expr);
  11868.       return 1;
  11869.  
  11870.     case CALL_STMT:
  11871.       callStmt = (CallStmt *) node;
  11872.       fallsThru (callStmt->expr);
  11873.       return 1;
  11874.  
  11875.     case SEND_STMT:
  11876.       sendStmt = (SendStmt *) node;
  11877.       fallsThru (sendStmt->expr);
  11878.       return 1;
  11879.  
  11880.     case WHILE_STMT:
  11881.       whileStmt = (WhileStmt *) node;
  11882.       fallsThru (whileStmt->expr);
  11883.       falls = fallsThruStmtList (whileStmt->stmts);
  11884.       if (!falls && !whileStmt->containsAnyContinues) {
  11885.         error (whileStmt, "Execution can never reach the bottom of the loop body; therefore this loop will not iterate");
  11886.       }
  11887.       if (whileStmt->expr &&
  11888.           whileStmt->expr->op == BOOL_CONST &&
  11889.           ((BoolConst *) whileStmt->expr)->ivalue == 1 &&
  11890.           !whileStmt->containsAnyBreaks) {
  11891.         return 0;
  11892.       }
  11893.       return 1;
  11894.  
  11895.     case DO_STMT:
  11896.       doStmt = (DoStmt *) node;
  11897.       falls = fallsThruStmtList (doStmt->stmts);
  11898.       fallsThru (doStmt->expr);
  11899.       if (!falls && !doStmt->containsAnyContinues) {
  11900.         error (doStmt, "Execution can never reach the bottom of the loop body; therefore this loop will not iterate");
  11901.       }
  11902.       return 1;
  11903.  
  11904.     case BREAK_STMT:
  11905.       return 0;
  11906.  
  11907.     case CONTINUE_STMT:
  11908.       return 0;
  11909.  
  11910.     case RETURN_STMT:
  11911.       returnStmt = (ReturnStmt *) node;
  11912.       fallsThru (returnStmt->expr);
  11913.       return 0;
  11914.  
  11915.     case FOR_STMT:
  11916.       forStmt = (ForStmt *) node;
  11917.       fallsThru (forStmt->lvalue);
  11918.       fallsThru (forStmt->expr1);
  11919.       fallsThru (forStmt->expr2);
  11920.       fallsThru (forStmt->expr3);
  11921.       falls = fallsThruStmtList (forStmt->stmts);
  11922.       if (!falls && !forStmt->containsAnyContinues) {
  11923.         error (forStmt, "Execution can never reach the bottom of the loop body; therefore this loop will not iterate");
  11924.       }
  11925.       return 1;
  11926.  
  11927.     case SWITCH_STMT:
  11928.       switchStmt = (SwitchStmt *) node;
  11929.       fallsThru (switchStmt->expr);
  11930.       // fallsThru (switchStmt->caseList);
  11931.       falls = 0;
  11932.       for (cas = switchStmt->caseList; cas; cas = cas->next) {
  11933.         fallsThru (cas->expr);
  11934.         falls = fallsThruStmtList (cas->stmts);
  11935.       }
  11936.       if (switchStmt->defaultIncluded) {
  11937.         falls = fallsThruStmtList (switchStmt->defaultStmts);
  11938.       }
  11939.       return falls || switchStmt->containsAnyBreaks;
  11940.  
  11941.     case TRY_STMT:
  11942.       tryStmt = (TryStmt *) node;
  11943.       falls = fallsThruStmtList (tryStmt->stmts);
  11944.       for (cat = tryStmt->catchList; cat; cat = cat->next) {
  11945.         fallsThru (cat->parmList);
  11946.         falls = falls || fallsThruStmtList (cat->stmts);
  11947.       }
  11948.       return falls;
  11949.  
  11950.     case THROW_STMT:
  11951.       throwStmt = (ThrowStmt *) node;
  11952.       fallsThru (throwStmt->argList);
  11953.       return 0;
  11954.  
  11955.     case FREE_STMT:
  11956.       freeStmt = (FreeStmt *) node;
  11957.       fallsThru (freeStmt->expr);
  11958.       return 1;
  11959.  
  11960.     case DEBUG_STMT:
  11961.       debugStmt = (DebugStmt *) node;
  11962.       return 1;
  11963.  
  11964.     case CASE:
  11965.       programLogicError ("FallsThru: CASEs done in SWITCH");
  11966.       return 0;
  11967.  
  11968.     case CATCH:
  11969.       programLogicError ("FallsThru: CATCHes done in TRY");
  11970.       return 0;
  11971.  
  11972.     case GLOBAL:
  11973.       global = (Global *) node;
  11974.       fallsThru (global->type);
  11975.       fallsThru (global->initExpr);
  11976.       fallsThru (global->next);
  11977.       return 0;
  11978.  
  11979.     case LOCAL:
  11980.       local = (Local *) node;
  11981.       fallsThru (local->type);
  11982.       fallsThru (local->initExpr);
  11983.       fallsThru (local->next);
  11984.       return 0;
  11985.  
  11986.     case PARAMETER:
  11987.       parm = (Parameter *) node;
  11988.       fallsThru (parm->type);
  11989.       fallsThru (parm->next);
  11990.       return 0;
  11991.  
  11992.     case CLASS_FIELD:
  11993.       classField = (ClassField *) node;
  11994.       fallsThru (classField->type);
  11995.       fallsThru (classField->next);
  11996.       return 0;
  11997.  
  11998.     case RECORD_FIELD:
  11999.       recordField = (RecordField *) node;
  12000.       fallsThru (recordField->type);
  12001.       fallsThru (recordField->next);
  12002.       return 0;
  12003.  
  12004.     case INT_CONST:
  12005.     case DOUBLE_CONST:
  12006.     case CHAR_CONST:
  12007.     case STRING_CONST:
  12008.     case BOOL_CONST:
  12009.     case NULL_CONST:
  12010.       return 0;
  12011.  
  12012.     case CALL_EXPR:
  12013.       callExpr = (CallExpr *) node;
  12014.       fallsThru (callExpr->argList);
  12015.       return 0;
  12016.  
  12017.     case SEND_EXPR:
  12018.       sendExpr = (SendExpr *) node;
  12019.       fallsThru (sendExpr->receiver);
  12020.       fallsThru (sendExpr->argList);
  12021.       return 0;
  12022.  
  12023.     case SELF_EXPR:
  12024.       return 0;
  12025.  
  12026.     case SUPER_EXPR:
  12027.       return 0;
  12028.  
  12029.     case FIELD_ACCESS:
  12030.       fieldAccess = (FieldAccess *) node;
  12031.       fallsThru (fieldAccess->expr);
  12032.       return 0;
  12033.  
  12034.     case ARRAY_ACCESS:
  12035.       arrayAccess = (ArrayAccess *) node;
  12036.       fallsThru (arrayAccess->arrayExpr);
  12037.       fallsThru (arrayAccess->indexExpr);
  12038.       return 0;
  12039.  
  12040.     case CONSTRUCTOR:
  12041.       constructor = (Constructor *) node;
  12042.       fallsThru (constructor->type);
  12043.       fallsThru (constructor->countValueList);
  12044.       fallsThru (constructor->fieldInits);
  12045.       return 0;
  12046.  
  12047.     case CLOSURE_EXPR:
  12048.       // closureExpr = (ClosureExpr *) node;
  12049.       // Skip this, since we'll fallsThru any functions when we do header->closures...
  12050.       // fallsThru (closureExpr->function);
  12051.       return 0;
  12052.  
  12053.     case VARIABLE_EXPR:
  12054.       return 0;
  12055.  
  12056.     case AS_PTR_TO_EXPR:
  12057.       asPtrToExpr = (AsPtrToExpr *) node;
  12058.       fallsThru (asPtrToExpr->expr);
  12059.       fallsThru (asPtrToExpr->type);
  12060.       return 0;
  12061.  
  12062.     case AS_INTEGER_EXPR:
  12063.       asIntegerExpr = (AsIntegerExpr *) node;
  12064.       fallsThru (asIntegerExpr->expr);
  12065.       return 0;
  12066.  
  12067.     case ARRAY_SIZE_EXPR:
  12068.       arraySizeExpr = (ArraySizeExpr *) node;
  12069.       fallsThru (arraySizeExpr->expr);
  12070.       return 0;
  12071.  
  12072.     case IS_INSTANCE_OF_EXPR:
  12073.       isInstanceOfExpr = (IsInstanceOfExpr *) node;
  12074.       fallsThru (isInstanceOfExpr->expr);
  12075.       fallsThru (isInstanceOfExpr->type);
  12076.       return 0;
  12077.  
  12078.     case IS_KIND_OF_EXPR:
  12079.       isKindOfExpr = (IsKindOfExpr *) node;
  12080.       fallsThru (isKindOfExpr->expr);
  12081.       fallsThru (isKindOfExpr->type);
  12082.       return 0;
  12083.  
  12084.     case SIZE_OF_EXPR:
  12085.       sizeOfExpr = (SizeOfExpr *) node;
  12086.       fallsThru (sizeOfExpr->type);
  12087.       return 0;
  12088.  
  12089.     case DYNAMIC_CHECK:
  12090.       dynamicCheck = (DynamicCheck *) node;
  12091.       fallsThru (dynamicCheck->expr);
  12092.       return 0;
  12093.  
  12094.     case ARGUMENT:
  12095.       arg = (Argument *) node;
  12096.       fallsThru (arg->expr);
  12097.       fallsThru (arg->next);
  12098.       return 0;
  12099.  
  12100.     case COUNT_VALUE:
  12101.       countValue = (CountValue *) node;
  12102.       fallsThru (countValue->count);
  12103.       fallsThru (countValue->value);
  12104.       fallsThru (countValue->next);
  12105.       return 0;
  12106.  
  12107.     case FIELD_INIT:
  12108.       fieldInit = (FieldInit *) node;
  12109.       fallsThru (fieldInit->expr);
  12110.       fallsThru (fieldInit->next);
  12111.       return 0;
  12112.  
  12113.     default:
  12114.       printf ("node->op = %s\n", symbolName (node->op));
  12115.       programLogicError ("Unkown op in fallsThru");
  12116.   }
  12117. }
  12118.  
  12119.  
  12120.  
  12121. // fallsThruStmtList (stmtList) --> bool
  12122. //
  12123. // Go through all the statements in the given statement list and make sure
  12124. // that there are no unreachable statements.  Return TRUE if execution can
  12125. // fall out the bottom of the statement list, and FALSE otherwise.
  12126. //
  12127. int fallsThruStmtList (Statement * stmtList) {
  12128.   Statement * stmt;
  12129.   int falls = 1;
  12130.  
  12131.   for (stmt = stmtList; stmt != NULL; stmt = stmt->next) {
  12132.     falls = fallsThru (stmt);
  12133.     if (!falls && (stmt->next != NULL)) {
  12134.       error (stmt->next, "This statement is unreachable (dead code) and will never be executed");
  12135.       falls = 1;
  12136.     }
  12137.   }
  12138.   return falls;
  12139. }
  12140.  
  12141.  
  12142.  
  12143. // assignLocalOffsets (hdr)
  12144. //
  12145. // This routine sets "local->offset" in
  12146. //    functions,
  12147. //    closures, and
  12148. //    methods
  12149. // It assumes all "local->sizeInBytes" have been set earlier.
  12150. //
  12151. // This routine also updates:
  12152. //    fun->frameSize
  12153. //    meth->frameSize
  12154. //
  12155. // If commandOptionS applies, this routine also prints the offset
  12156. // and frameSize info (and "parm->offset"s) for
  12157. //    functions,
  12158. //    closures,
  12159. //    methods, and
  12160. //    errors
  12161. //
  12162. void assignLocalOffsets (Header * hdr) {
  12163.   Function * fun;
  12164.   ClassDef * cl;
  12165.   Method * meth;
  12166.   ErrorDecl * errorDecl;
  12167.  
  12168.   // Run through all errors...
  12169.   if (commandOptionS) {
  12170.     for (errorDecl = hdr->errors; errorDecl; errorDecl = errorDecl->next) {
  12171.       printf ("==========  Error ");
  12172.       printString (stdout, errorDecl->id);
  12173.       printf ("  ==========\n");
  12174.       printParmOffsets (errorDecl->parmList);
  12175.     }
  12176.   }
  12177.  
  12178.   // Run through all functions...
  12179.   for (fun = hdr->functions; fun; fun = fun->next) {
  12180.     assignOffsetsInMethOrFunction (fun);
  12181.   }
  12182.  
  12183.   // Run through all closures...
  12184.   for (fun = hdr->closures; fun; fun = fun->next) {
  12185.     assignOffsetsInMethOrFunction (fun);
  12186.   }
  12187.  
  12188.   // Run through all methods in all classes...
  12189.   for (cl = hdr->classes; cl; cl = cl->next) {
  12190.     for (meth = cl->methods; meth; meth = meth->next) {
  12191.       assignOffsetsInMethOrFunction (meth);
  12192.     }
  12193.   }
  12194. }
  12195.  
  12196.  
  12197.  
  12198. // assignOffsetsInMethOrFunction (methOrFunction)
  12199. //
  12200. // This routine assigns offsets to the Locals in this method or function.
  12201. //
  12202. void assignOffsetsInMethOrFunction (MethOrFunction * methOrFunction) {
  12203.   int lastOffset, padding, incr;
  12204.   Local * local;
  12205.   Function * fun;
  12206.   Method * meth;
  12207.   Catch * cat;
  12208.   Parameter * parm;
  12209.  
  12210.   // Print the activation record layout, if desired...
  12211.   if (commandOptionS) {
  12212.     if (methOrFunction->op == FUNCTION) {
  12213.       fun = (Function *) methOrFunction;
  12214.       if (fun->id) {
  12215.         printf ("==========  Function ");
  12216.         printString (stdout, fun->id);
  12217.         printf ("  ==========\n");
  12218.       } else {
  12219.          printf ("==========  Closure on line %d in file %s  ==========\n",
  12220.                        extractLineNumber (fun->tokn),
  12221.                        extractFilename (fun->tokn));
  12222.       }
  12223.     } else {
  12224.       meth = (Method *) methOrFunction;
  12225.       printf ("==========  Method ");
  12226.       printString (stdout, meth->myClass->id);
  12227.       printf (".");
  12228.       printString (stdout, meth->selector);
  12229.       printf ("  ==========\n");
  12230.     }
  12231.     printf ("          Offset 4:\t4\tRet Addr\n");
  12232.     printf ("          Offset 0:\t4\tOld FP\n");
  12233.     printf ("          Offset -4:\t4\tOld r13\n");
  12234.     printf ("          Offset -8:\t4\tRoutine Descriptor Ptr\n");
  12235.     printf ("      Local Variables:\n");
  12236.   }
  12237.  
  12238.   // We will place variables at offsets before this offset...
  12239.   lastOffset = -8;
  12240.  
  12241.   // Look at each local.  Do only "bools" and "chars"...
  12242.   for (local = methOrFunction->locals;
  12243.        local != NULL;
  12244.        local = (Local *) local->next) {
  12245.  
  12246.     lastOffset = assignOffsetToLocal (lastOffset, local, commandOptionS, 1);
  12247.   }
  12248.  
  12249.   // Look at each parameter used in any catch clauses.  Do only "bools" and "chars"...
  12250.   for (cat = methOrFunction->catchList; cat; cat = cat->nextInMethOrFunction) {
  12251.     for (parm = cat->parmList; parm; parm = (Parameter *) parm->next) {
  12252.       lastOffset = assignOffsetToLocal (lastOffset, parm, commandOptionS, 1);
  12253.     }
  12254.   }
  12255.  
  12256.   // Insert padding bytes after the byte data, if necessary...
  12257.   padding = 3 - ((-lastOffset-1) % 4);
  12258.   lastOffset -= padding;
  12259.   if (commandOptionS && padding != 0) {
  12260.     printf ("          Offset %d:\t%d\t...padding...\n", lastOffset, padding);
  12261.   }
  12262.  
  12263.   // Look at each local.  Skip "bools" and "chars"...
  12264.   for (local = methOrFunction->locals;
  12265.        local != NULL;
  12266.        local = (Local *) local->next) {
  12267.     lastOffset = assignOffsetToLocal (lastOffset, local, commandOptionS, 0);
  12268.   }
  12269.  
  12270.   // Look at each parameter used in any catch clauses.  Skip "bools" and "chars"...
  12271.   for (cat = methOrFunction->catchList; cat; cat = cat->nextInMethOrFunction) {
  12272.     for (parm = cat->parmList; parm; parm = (Parameter *) parm->next) {
  12273.       lastOffset = assignOffsetToLocal (lastOffset, parm, commandOptionS, 0);
  12274.     } 
  12275.   }
  12276.  
  12277.   // Now add space for arguments to functions we will call from this meth or function...
  12278.   lastOffset -= methOrFunction->maxArgBytes;
  12279.   if (commandOptionS) {
  12280.     printf ("          Offset %d:\t%d\tSpace for Args\n",
  12281.             lastOffset, methOrFunction->maxArgBytes);
  12282.   }
  12283.  
  12284.   // Compute and fill-in the frame size of this method or function as...
  12285.   //       variables + args (not incl 16 bytes)
  12286.   methOrFunction->frameSize = -lastOffset - 8;
  12287.   if (commandOptionS) {
  12288.     printf ("              Total size of activation record = %d bytes\n",
  12289.             methOrFunction->frameSize);
  12290.   }
  12291.  
  12292.   // Print out the parameter offsets, if commandOptionS is set...
  12293.   printParmOffsets (methOrFunction->parmList);
  12294.  
  12295. }
  12296.  
  12297.  
  12298.  
  12299. // assignOffsetToLocal (lastOffset, varDecl, commandOptionS, doingBytes)
  12300. //                                                         --> newLastOffset
  12301. //
  12302. // This routine is passed "varDecl" (a LOCAL or Catch PARAMETER).  It is passed 
  12303. // "lastOffset" and returns the modified "lastOffset".  "LastOffset" is the
  12304. // offset assigned to the previous variable; we will place this variable at
  12305. // an offset determined by its size and where the last variable was placed.
  12306. //
  12307. // If "commandOptionS" is set, this routine will print a line on stdout.
  12308. // If "doingBytes" is set and this variable has is not a byte-sized
  12309. // variable, we just do nothing.  If "doingBytes" is not set, then we only do
  12310. // variables that are larger than 1 byte.
  12311. //
  12312. int assignOffsetToLocal (int lastOffset,
  12313.                          VarDecl * varDecl,
  12314.                          int commandOptionS,
  12315.                          int doingBytes) {
  12316.   int sz, newLastOffset;
  12317.  
  12318.   // Determine the size of this variable...
  12319.   sz = varDecl->sizeInBytes;
  12320.  
  12321.   // If we are doing byte-sized data and this is a byte, then do it.
  12322.   // If we are NOT doing byte-sized data and this is NOT a byte, then do it.
  12323.   // Otherwise, return immediately.
  12324.   if (sz == 1) {
  12325.     if (!doingBytes) return lastOffset;
  12326.   } else {
  12327.     if (doingBytes) return lastOffset;
  12328.   }
  12329.  
  12330.   // Decrement "lastOffset" and set this variable's "offset" field...
  12331.   newLastOffset = lastOffset - sz;
  12332.   varDecl->offset = newLastOffset;
  12333.  
  12334.   // If printing is desired, then print a line...
  12335.   if (commandOptionS) {
  12336.     printf ("          Offset %d:\t%d\t%s\n", varDecl->offset, sz,
  12337.                                       varDecl->id->chars);
  12338.   }
  12339.   return newLastOffset;
  12340. }
  12341.  
  12342.  
  12343.  
  12344. // printParmOffsets (parmList)
  12345. //
  12346. // This routine prints out the offsets of the parameters in the given parmList.
  12347. //
  12348. void printParmOffsets (Parameter * parmList) {
  12349.   int nextOffset, padding, incr;
  12350.   Parameter * parm;
  12351.  
  12352.   // Print the parameter offsets layout, if desired...
  12353.   if (!commandOptionS) return;
  12354.  
  12355.   if (parmList == NULL) {
  12356.     printf ("      (no parameters)\n");
  12357.     return;
  12358.   }
  12359.  
  12360.   printf ("      Parameter Offsets:\n");
  12361.   nextOffset = parmList->offset;
  12362.   for (parm = parmList;
  12363.        parm != NULL;
  12364.        parm = (Parameter *) parm->next) {
  12365.  
  12366.     // Display padding bytes, if necessary...
  12367.     if (needsAlignment (parm->type)) {
  12368.       padding = (3 - ((nextOffset+3) % 4));
  12369.       if ((parm->offset >= 0) && (padding != 0)) {
  12370.         printf ("          Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  12371.         nextOffset += padding;
  12372.       }
  12373.     }
  12374.     printf ("          Offset %d:\t%d\t",
  12375.       parm->offset,
  12376.       sizeInBytesOfWhole (parm->type, parm, 0));
  12377.     printString (stdout, parm->id);
  12378.     // printf (": ");
  12379.     // pretty (parm->type);
  12380.     printf ("\n");
  12381.     incr = sizeInBytesOfWhole (parm->type, parm, 0);
  12382.     nextOffset = nextOffset + incr;
  12383.   }
  12384.   padding = (3 - ((nextOffset+3) % 4));
  12385.   if (padding != 0) {
  12386.     printf ("          Offset %d:\t%d\t...padding...\n", nextOffset, padding);
  12387.   }
  12388. }
  12389.  
  12390.  
  12391.  
  12392. // assignDispatchTableOffsets (hdr)
  12393. //
  12394. // This routine assigns offset to all selectors in classes and interfaces.
  12395. //
  12396. // First, it fills in the following sets:
  12397. //       knownSubAbstracts
  12398. //       SuperAbstractsInThisPackage
  12399. //
  12400. // Then, it...
  12401. //
  12402. //  Message naming convention...
  12403. //    Inherited message (with no overriding):
  12404. //      The sub-abstract will have the message name, unaltered.
  12405. //    Inherited message (with overriding):
  12406. //      The sub-abstract will have the message name, unaltered; this is the new version.
  12407. //      The sub-abstract will have the _super_ version; this is the inherited method.
  12408. //    A sub-abstract of this:
  12409. //      mess  -  the new version
  12410. //      _super_mess  --  the parent's version
  12411. //      _super__super_mess  --  the grandparent's version.
  12412. //
  12413. void assignDispatchTableOffsets (Header * hdr) {
  12414.   Interface * inter;
  12415.   ClassDef * cl;
  12416.   Abstract * absList, * abs, * nextAbs, * subAbs, * other;
  12417.   Offset * offset, * prevOff;
  12418.   AbstractStack * st;
  12419.   String * sel, * otherSel;
  12420.   MethodProto * methProto;
  12421.   Mapping<Abstract,Abstract> * relatedSet, * affectedSet;
  12422.   int okay;
  12423.   MethodProto * methProto2;
  12424.  
  12425.   // Initialize the Dispatch Table offset list...
  12426.   if (firstDispatchOffset == NULL) {
  12427.     offset = new Offset;
  12428.     offset->ivalue = 4;        // This is the offset of the first message
  12429.     offset->nextOffset = NULL;
  12430.     firstDispatchOffset = offset;
  12431.   }
  12432.  
  12433.   // Build a list of all interfaces and classes, in topo-order.  All
  12434.   // Interfaces will come first followed by all classes.  Each will
  12435.   // come before is sub-classes and sub-interfaces.  Together, classes
  12436.   // and interfaces are referred to as "abstracts".
  12437.   //
  12438.   // Also initialize the per-abstract mappings.
  12439.   //
  12440.   absList = NULL;
  12441.   // Add all interfaces to the list.
  12442.   for (inter = hdr->interfaces; inter; inter = inter->next) {
  12443.     inter->nextAbstract = absList;
  12444.     absList = inter;
  12445.   }
  12446.   // Add all classes to the list.
  12447.   for (cl = hdr->classes; cl; cl = cl->next) {
  12448.     cl->nextAbstract = absList;
  12449.     absList = cl;
  12450.   }
  12451.   // Reverse the list and initialize the pre-abstract fields.
  12452.   abs = absList;
  12453.   absList = NULL;
  12454.   while (abs) {
  12455.     nextAbs = abs->nextAbstract;
  12456.     abs->knownSubAbstracts               = new Mapping <Abstract, Abstract> (10, NULL);
  12457.     abs->superAbstractsInThisPackage     = new Mapping <Abstract, Abstract> (10, NULL);
  12458.     abs->supersAbstractsInOtherPackages  = new Mapping <Abstract, Abstract> (10, NULL);
  12459.     abs->offsetToSelector                = new Mapping <Offset, String> (10, NULL);
  12460.     abs->selectorToOffset                = new Mapping <String, Offset> (10, NULL);
  12461.     abs->unavailableOffsets              = new Mapping <Offset, String> (10, NULL);
  12462.     abs->nextAbstract = absList;
  12463.     absList = abs;
  12464.     abs = nextAbs;
  12465.   }
  12466.  
  12467.   // DEBUGGING: Print a list of all Abstracts in this package...
  12468.   //    printf ("Here are all abstracts in this package:\n");
  12469.   //    for (abs = absList; abs; abs = abs->nextAbstract) {
  12470.   //      printf ("  %s\n", abs->id->chars);
  12471.   //    }
  12472.  
  12473.   // Run through all abstracts in this package and identify all super-abstracts
  12474.   // in this package, including self, direct, and indirect supers.
  12475.   // Also follow the chains up until we hit any abstract(s) in other packages,
  12476.   // but then stop and go no further.  Add all such "minimal" abstracts in 
  12477.   // pther packages to "supersAbstractsInOtherPackages".
  12478.   //
  12479.   //    printf ("Identifying Super-Abstracts...\n");
  12480.   for (abs = absList; abs; abs = abs->nextAbstract) {
  12481.     //    printf ("  Processing %s\n", abs->id->chars);
  12482.     addAllSuperAbstracts (abs,
  12483.                           hdr,
  12484.                           abs->superAbstractsInThisPackage,
  12485.                           abs->supersAbstractsInOtherPackages);
  12486.   }
  12487.  
  12488.   // Now run through the list of all abstracts and fill in all sub-abstracts
  12489.   // that are in this package...
  12490.   //
  12491.   for (abs = absList; abs; abs = abs->nextAbstract) {
  12492.     //    printf ("%s...\n", abs->id->chars);
  12493.     nextAbs = abs->superAbstractsInThisPackage->getFirst();
  12494.     while (nextAbs) {
  12495.       //    printf ("  %s is a super-abstract\n", nextAbs->id->chars);
  12496.       if (! nextAbs->knownSubAbstracts->alreadyDefined (abs)) {
  12497.         nextAbs->knownSubAbstracts->enter (abs, abs);
  12498.       }
  12499.       nextAbs = abs->superAbstractsInThisPackage->getNext();
  12500.     }
  12501.   }  
  12502.  
  12503. /*****  PRINTING FOR DEBUGGING  *****
  12504.   //
  12505.   // List all Abstracts in this package...
  12506.   printf ("Here are all abstracts in this package, with their super-Abstracts:\n");
  12507.   for (abs = absList; abs; abs = abs->nextAbstract) {
  12508.     printf ("  %s\n", abs->id->chars);
  12509.     printf ("    SUPER-ABSTRACTS:\n");
  12510.     nextAbs = abs->superAbstractsInThisPackage->getFirst();
  12511.     while (nextAbs) {
  12512.       printf ("      %s\n", nextAbs->id->chars);
  12513.       nextAbs = abs->superAbstractsInThisPackage->getNext();
  12514.     }
  12515.     printf ("    SUB-ABSTRACTS:\n");
  12516.     nextAbs = abs->knownSubAbstracts->getFirst();
  12517.     while (nextAbs) {
  12518.       printf ("      %s\n", nextAbs->id->chars);
  12519.       nextAbs = abs->knownSubAbstracts->getNext();
  12520.     }
  12521.     printf ("    MINIMAL SUPER-ABSTRACTS NOT IN THIS PACKAGE:\n");
  12522.     nextAbs = abs->supersAbstractsInOtherPackages->getFirst();
  12523.     while (nextAbs) {
  12524.       printf ("      %s\n", nextAbs->id->chars);
  12525.       nextAbs = abs->supersAbstractsInOtherPackages->getNext();
  12526.     }
  12527.   }
  12528. ***************/
  12529.  
  12530.  
  12531.  
  12532.   // **********  PASS-1: INHERIT OFFSETS FROM SUPERS IN OTHER PACKAGES  **********
  12533.   //
  12534.   // Go through all abstracts and inherit all offsets from super-abstracts
  12535.   // that are in other packages.  Watch for conflicts and print an error if
  12536.   // we run into trouble.
  12537.   //
  12538.   for (abs = absList; abs; abs = abs->nextAbstract) {
  12539.     //    printf ("=======================  %s  =======================\n",
  12540.     //            abs->id->chars);
  12541.  
  12542.     // Go through all super-abstracts in other packages...
  12543.     nextAbs = abs->supersAbstractsInOtherPackages->getFirst();
  12544.     while (nextAbs) {
  12545.       //    printf ("  Inheriting messages from %s\n", nextAbs->id->chars);
  12546.  
  12547.       // Go through all messages in this super-abstract...
  12548.       sel = nextAbs->offsetToSelector->getFirst ();
  12549.       while (sel) {
  12550.         offset = nextAbs->selectorToOffset->findInTopScope (sel);
  12551.         //    printf ("    %s: %d\n", sel->chars, offset->ivalue);
  12552.  
  12553.         // If we already have an offset for this selector...
  12554.         prevOff = abs->selectorToOffset->findInTopScope (sel);
  12555.         if (prevOff) {
  12556.           // Make sure it is the same...
  12557.           if (prevOff != offset) {      // This error occurs in "test9>>F>>mess2"
  12558.             //    printf ("***** CONFLICT (1): selector = %s\n",
  12559.             //            sel->chars);
  12560.             //    printf ("                    abs = %s        prevOff = %d\n",
  12561.             //            abs->id->chars, prevOff->ivalue);
  12562.             //    printf ("                    nextAbs = %s    offset = %d\n",
  12563.             //            nextAbs->id->chars, offset->ivalue);
  12564.             error (abs, "A problem has been encountered when laying out the dispatch table for this class or interface.  This class or interface inherits a message from two or more classes or interfaces which are in a different package from the one being compiled now.  When the other package was compiled, this message happens to have been assigned different offsets in the different super-classes or super-interfaces.  This was possible since the classes or interfaces in the other package were unrelated (e.g., had no common sub-class or sub-interface).  The class or interface in which this problem is arising inherits this message from these previously unrelated classes or interfaces.  The problem is that it is not possible now to assign this message a single offset consistent with all super-classes and super-interfaces, without changing the offset assigned to this message in the super-classes or super-interfaces.  You may resolve this problem by forcing this message to be given identical offsets in all relevant super-classes and super-interfaces.  This can be done by adding a dummy class or interface to the other package and making it extend all relevant classes or interfaces in that other package.  (Inheritance conflict type 1)");
  12565.             methProto2 = abs->selectorMapping->findInTopScope (sel);
  12566.             if (methProto2) {
  12567.               error2 (methProto2, "Here is the message that is causing the problem");
  12568.             }
  12569.             error2 (nextAbs, "Here is one of the classes or interfaces in other packages that are contributing to the problem");
  12570.  
  12571.           //    } else {      // This case occurs in "test9>>W>>mess2"
  12572.           //      printf ("      This selector already has the same offset...\n");
  12573.           }
  12574.  
  12575.         // Else if no offset yet, then assign this offset...
  12576.         } else {
  12577.           //    printf ("      Assigning offset %d to %s in %s...\n",
  12578.           //            offset->ivalue,
  12579.           //            sel->chars,
  12580.           //            abs->id->chars);
  12581.           abs->selectorToOffset->enter (sel, offset);
  12582.           abs->offsetToSelector->enter (offset, sel);
  12583.  
  12584.           // Now run through all supers of this abstract that occur in
  12585.           // in the same package and mark this offset as unavailable...
  12586.           other = abs->superAbstractsInThisPackage->getFirst();
  12587.           while (other) {
  12588.             //    printf ("        Marking this offset unavailable in %s\n",
  12589.             //            other->id->chars);
  12590.             if (! other->unavailableOffsets->findInTopScope (offset)) {
  12591.               other->unavailableOffsets->enter (offset, sel);
  12592.             }
  12593.             other = abs->superAbstractsInThisPackage->getNext();
  12594.           }
  12595.  
  12596.         } 
  12597.         sel = nextAbs->offsetToSelector->getNext ();
  12598.       }
  12599.       nextAbs = abs->supersAbstractsInOtherPackages->getNext();
  12600.     }
  12601.   }
  12602.   // ********************  END OF PASS-1  ********************
  12603.  
  12604.  
  12605.  
  12606.   // **********  PASS-2: ASSIGN OFFSETS TO ALL REMAINING MESSAGES  **********
  12607.   //
  12608.   // Go through all abstracts.  For each, go through all message selectors.
  12609.   //
  12610.   // For each selector, begin by identifying all related abstracts with this
  12611.   // selector.  (These are abstracts that are related by any chain of sub and/or
  12612.   // super and that contain the given message.  Call this the "related" set.)
  12613.   //
  12614.   // Then identify all classes that will have to block out this offset for that
  12615.   // selector.  Call this the "affected" set.  (It includes the related classes.)
  12616.   //
  12617.   // Next find an offset for this selector.  Start by looking through the "related"
  12618.   // set and see if any of them give the selector an offset.  If so, use it.
  12619.   // Otherwise, start looking through all possible offsets, one-by-one.  For
  12620.   // each offset, see if it is available for use (i.e., not in "unavailableOffsets")
  12621.   // for each of the abstracts in the "related" set.
  12622.   //
  12623.   // Once an offset has been identified, then set the offset for this selector in all
  12624.   // abstracts in the "related" set.  Watch for conflicts; this selector could be
  12625.   // given a different offset in some abstracts (due to conflicting inheritance from
  12626.   // abstracts in other packages).  Also, mark this offset as unavailable in all
  12627.   // abstracts in the "affected" set.
  12628.   //  
  12629.  
  12630.   // Look at each abstract...
  12631.   for (abs = absList; abs; abs = abs->nextAbstract) {
  12632.     //    printf ("=======================  %s  =======================\n",
  12633.     //            abs->id->chars);
  12634.  
  12635.     // Look at each message that is in this abstract...
  12636.     methProto = abs->selectorMapping->getFirst();
  12637.     while (methProto) {
  12638.       sel = methProto->selector;
  12639.       //    printf ("%s:\n", sel->chars);
  12640.  
  12641.       // If this selector already has an offset, then skip to the next selector...
  12642.       if (abs->selectorToOffset->findInTopScope (sel)) {
  12643.         offset = abs->selectorToOffset->findInTopScope (sel);
  12644.         //    printf ("    This message has already been assigned offset %d.\n",
  12645.         //            offset->ivalue);
  12646.         methProto = abs->selectorMapping->getNext();
  12647.         continue;
  12648.       }
  12649.  
  12650.       // Create the "related" set.  Begin by creating a stack of all abstracts
  12651.       // that still to be looked at and push this abstract onto it.
  12652.       st = newStack ();
  12653.       stackPush (st, abs);
  12654.       relatedSet = new Mapping <Abstract, Abstract> (10, NULL);
  12655.       // While there is another abstract to consider...
  12656.       while (!stackEmpty (st)) {
  12657.         nextAbs = stackPop (st);
  12658.         //    printf ("  Popping and considering %s...\n", nextAbs->id->chars);
  12659.         // If this abstract contains this selector, then we'll need to look at it...
  12660.         if (nextAbs->selectorMapping->findInTopScope (sel)) {
  12661.           // If it is not already in the "related" set then...
  12662.           if (! relatedSet->findInTopScope (nextAbs)) {
  12663.             // Add it...
  12664.             relatedSet->enter (nextAbs, nextAbs);
  12665.             // Run through all subs and push them...
  12666.             //    printf ("    pushing these sub-Abstracts:\n");
  12667.             other = nextAbs->knownSubAbstracts->getFirst();
  12668.             while (other) {
  12669.               //    printf ("      %s\n", other->id->chars);
  12670.               stackPush (st, other);
  12671.               other = nextAbs->knownSubAbstracts->getNext();
  12672.             }
  12673.             // Run through all supers and push them...
  12674.             //    printf ("    pushing these super-Abstracts:\n");
  12675.             other = nextAbs->superAbstractsInThisPackage->getFirst();
  12676.             while (other) {
  12677.               //    printf ("      %s\n", other->id->chars);
  12678.               stackPush (st, other);
  12679.               other = nextAbs->superAbstractsInThisPackage->getNext();
  12680.             }
  12681.           }
  12682.         }
  12683.       }
  12684.  
  12685.       // Now compute the "affected set".  This is the set of all super-abstracts
  12686.       // of all abstracts in the "related set", that are in this package.  (These
  12687.       // are abstracts which may or may not contain the message, but which will
  12688.       // need to have the offset occupied by this message reserved; they cannot
  12689.       // place any other message at this offset.)
  12690.       affectedSet = new Mapping <Abstract, Abstract> (10, NULL);
  12691.       nextAbs = relatedSet->getFirst();
  12692.       while (nextAbs) {
  12693.         // Run through all supers in this package, and add them if not
  12694.         // already in the "affected set"...
  12695.         other = nextAbs->superAbstractsInThisPackage->getFirst();
  12696.         while (other) {
  12697.           //    printf ("      %s\n", other->id->chars);
  12698.           if (! affectedSet->findInTopScope (other)) {
  12699.             affectedSet->enter (other, other);
  12700.           }
  12701.           other = nextAbs->superAbstractsInThisPackage->getNext();
  12702.         }
  12703.         nextAbs = relatedSet->getNext();
  12704.       }
  12705.  
  12706.       // DEBUGGING: Print the related set...
  12707.       //    printf ("    RELATED-SET:  ");
  12708.       //    nextAbs = relatedSet->getFirst();
  12709.       //    while (nextAbs) {
  12710.       //      printf ("%s  ", nextAbs->id->chars);
  12711.       //      nextAbs = relatedSet->getNext();
  12712.       //    }
  12713.       //    printf ("\n");
  12714.  
  12715.       // DEBUGGING: Print the affected set...
  12716.       //    printf ("    AFFECTED-SET:  ");
  12717.       //    nextAbs = affectedSet->getFirst();
  12718.       //    while (nextAbs) {
  12719.       //      printf ("%s  ", nextAbs->id->chars);
  12720.       //      nextAbs = affectedSet->getNext();
  12721.       //    }
  12722.       //    printf ("\n");
  12723.  
  12724.       // Look through all abstracts in the "related" set.  See if any one of
  12725.       // them assigns this selector an offset.  (This could occur if one of
  12726.       // the abstracts inherits an offset from a super in another package.)
  12727.       // If so, we will have to use this offset.
  12728.       // (This situation occurs in Test9>>II>>m.)
  12729.       offset = NULL;
  12730.       nextAbs = relatedSet->getFirst ();
  12731.       while (nextAbs) {
  12732.         offset = nextAbs->selectorToOffset->findInTopScope (sel);
  12733.         if (offset != NULL) {
  12734.           //    printf ("  The abstract %s in the related set gives this selector offset %d\n",
  12735.           //            nextAbs->id->chars, offset->ivalue);
  12736.           break;
  12737.         }
  12738.         nextAbs = relatedSet->getNext ();
  12739.       }
  12740.       
  12741.       // If we did not have an offset imposed by a related abstract, then
  12742.       // find an offset that will work...
  12743.       if (offset == NULL) {
  12744.         //    printf ("    Searching for a new offset for this selector...\n");
  12745.         offset = firstDispatchOffset;
  12746.         while (1) {
  12747.           if (isThisOffsetOK (sel, offset, relatedSet)) {
  12748.             break;
  12749.           }
  12750.           offset = nextDispatchOffset (offset);
  12751.         }
  12752.         //    printf ("      Offset %d is chosen\n", offset->ivalue);
  12753.       }
  12754.  
  12755.       // Assign this offset to this selector in all abstracts in the
  12756.       // "relatedSet".  Also, mark this offset as unavailable in all the
  12757.       // abstracts in the "affectedSet"...
  12758.       assignOffsetToSelector (sel, offset, relatedSet, affectedSet);
  12759.  
  12760.       // Move on to the next selector...
  12761.       methProto = abs->selectorMapping->getNext();
  12762.     }
  12763.  
  12764.     // Print "offsetToSelector", "selectorToOffset", and "unavailableOffsets"...
  12765.     //    abs->offsetToSelector->printOffsetToSelector("OFFSET-TO-SELECTOR:");
  12766.     //    abs->selectorToOffset->printSelectorToOffset();
  12767.     //    abs->unavailableOffsets->printOffsetToSelector("UNAVAILABLE-OFFSETS:");
  12768.  
  12769.  
  12770.     // Now go through all the methodProtos in this class or interface and
  12771.     // set their offsets...
  12772.     //    printf ("    %s:\n", abs->id->chars);
  12773.     methProto = abs->selectorMapping->getFirst();
  12774.     while (methProto) {
  12775.       offset = abs->selectorToOffset->findInTopScope (methProto->selector);
  12776.       if (offset == NULL) {
  12777.         programLogicError ("Offset should have been assigned for all selectors");
  12778.       }
  12779.       methProto->offset = offset->ivalue;
  12780.       //    printf ("      %s: %d\n", methProto->selector->chars, methProto->offset);
  12781.       methProto = abs->selectorMapping->getNext();
  12782.     }
  12783.   }
  12784.  
  12785. }
  12786.  
  12787.  
  12788.  
  12789. // isThisOffsetOK (sel, offset, setToCheck) --> bool
  12790. //
  12791. // This routine searches the given set to see if this offset is okay for
  12792. // use.  It checks to see if this offset is in the "unavailableOffsets" mapping
  12793. // in any of the abstracts in the "setToCheck".  If so, then if it is associated
  12794. // with the given selector ("sel") then it is okay; return true.  If it is in the
  12795. // "unavailableOffsets" mapping, but for a different selector, then return false.
  12796. //
  12797. int isThisOffsetOK (String * sel,
  12798.                     Offset * offset,
  12799.                     Mapping<Abstract,Abstract> * setToCheck) {
  12800.   Abstract * abs;
  12801.   String * otherSel;
  12802.  
  12803.   //    printf ("        Considering %s: %d...\n", sel->chars, offset->ivalue);
  12804.   abs = setToCheck->getFirst();
  12805.   while (abs) {
  12806.     //    printf ("          Checking %s...\n", abs->id->chars);
  12807.     otherSel = abs->unavailableOffsets->findInTopScope (offset);
  12808.     if (otherSel) {
  12809.       // if (otherSel == sel) {
  12810.       //   programLogicError ("This cannot occur");
  12811.       // }
  12812.       return 0;
  12813.     }
  12814.     abs = setToCheck->getNext();
  12815.   }
  12816.   return 1;
  12817. }
  12818.  
  12819.  
  12820.  
  12821. // assignOffsetToSelector (sel, offset, relatedSet, affectedSet)
  12822. //
  12823. // This routine assigns this offset to this selector in the abstracts in
  12824. // the "relatedSet".  It then marks this offset as unavailable for all
  12825. // the abstracts in the "affectedSet".
  12826. //
  12827. void assignOffsetToSelector (String * sel,
  12828.                              Offset * offset,
  12829.                              Mapping <Abstract, Abstract> * relatedSet,
  12830.                              Mapping <Abstract, Abstract> * affectedSet) {
  12831.   Abstract * abs, * superAbs;
  12832.   Offset * prevOff;
  12833.   MethodProto * methodProto;
  12834.  
  12835.   // Run through all abstracts in "related set"...
  12836.   abs = relatedSet->getFirst();
  12837.   while (abs) {
  12838.     prevOff = abs->selectorToOffset->findInTopScope (sel);
  12839.     if (prevOff) {
  12840.  
  12841.       // If we found an abstract which has this selector at a different offset...
  12842.       if (prevOff != offset) {
  12843.         //    printf ("***** CONFLICT (2): selector = %s\n",
  12844.         //            sel->chars);
  12845.         //    printf ("                    abs = %s        prevOff = %d\n",
  12846.         //            abs->id->chars, prevOff->ivalue);
  12847.         //    printf ("                    nextAbs = ?    offset = %d\n",
  12848.         //            offset->ivalue);
  12849.         error (abs, "A problem has been encountered when laying out the dispatch table for this class or interface.  This class or interface shares a message with other classes or interfaces via inheritance.  Two or more related classes or interfaces in this package inherit this message from classes or interfaces which are in a different package from the one being compiled now.  When the other package was compiled, this message happens to have been assigned different offsets in the different super-classes or super-interfaces in that package.  This was possible since the classes or interfaces in the other package were unrelated (e.g., had no common sub-class or sub-interface).  The class or interface in which this problem is arising must assign an offset to this message that is compatible with these (previously unrelated) classes or interfaces in the other package.  The problem is that it is not possible now to assign this message a single offset consistent with all related classes and interfaces, since it is not possible to change the offset assigned to this message in classes or interfaces in other packages.  You may resolve this problem by forcing this message to be given identical offsets in all relevant super-classes and super-interfaces.  This can be done by adding a dummy class or interface to the other package and making it extend all relevant classes or interfaces in that other package.  (Inheritance conflict type 2)");
  12850.         methodProto = abs->selectorMapping->findInTopScope (sel);
  12851.         if (methodProto) {
  12852.           error2 (methodProto, "Here is the message that is causing the problem");
  12853.         }
  12854.  
  12855.       // If we found another abstract which has this selector at the same offset...
  12856.       } else {
  12857.         //    printf ("        Offset in %s was found to be identical\n",
  12858.         //            abs->id->chars);
  12859.       }
  12860.  
  12861.     // Else this abstract does not have an offset for this selector...
  12862.     } else {
  12863.  
  12864.       // Assign this offset to this selector...
  12865.       //    printf ("        Setting offset to %d in %s\n",
  12866.       //            offset->ivalue, abs->id->chars);
  12867.       abs->selectorToOffset->enter (sel, offset);
  12868.       abs->offsetToSelector->enter (offset, sel);
  12869.  
  12870.       // Make sure this offset is compatible with any supers in other packages.
  12871.       // It must be, since we already inherited offsets from supers in the first pass,
  12872.       // so signal a logic error if we find any inconsistencies.
  12873.       superAbs = abs->supersAbstractsInOtherPackages->getFirst ();
  12874.       while (superAbs) {
  12875.         prevOff = superAbs->selectorToOffset->findInTopScope (sel);
  12876.         if (prevOff != NULL && prevOff != offset) {
  12877.           printf ("***** CONFLICT (3) : selector = %s\n",
  12878.                   sel->chars);
  12879.           printf ("                     abstr = %s    offset = %d\n",
  12880.                   abs->id->chars, offset->ivalue);
  12881.           printf ("                     super = %s    offset=%d\n",
  12882.                   superAbs->id->chars, prevOff->ivalue);
  12883.           programLogicError ("We have already inherited all messages from supers");
  12884.         }
  12885.         superAbs = abs->supersAbstractsInOtherPackages->getNext ();
  12886.       }
  12887.  
  12888.     }
  12889.     abs = relatedSet->getNext();
  12890.   }
  12891.  
  12892.   // Run through all Abstracts in "affected set"...
  12893.   abs = affectedSet->getFirst();
  12894.   while (abs) {
  12895.     //    printf ("      Marking offset %d unavailable in %s\n",
  12896.     //            offset->ivalue,
  12897.     //            abs->id->chars);
  12898.     // If this offset is not already marked "unavailable", then mark it as such...
  12899.     if (! abs->unavailableOffsets->findInTopScope (offset)) {
  12900.       abs->unavailableOffsets->enter (offset, sel);
  12901.     }
  12902.     abs = affectedSet->getNext();
  12903.   }
  12904.  
  12905. }
  12906.  
  12907.  
  12908.  
  12909. // addAllSuperAbstracts (abs, hdr, supersInThisPackage, supersInOtherPackages)
  12910. //
  12911. // This routine is passed an abstract "abs".  It visits each of its superclasses
  12912. // superInterfaces and adds each of them (if they are in this package) to the
  12913. // set "supersInThisPackage".  If the super is not in this package,
  12914. // then we add it to "supersInOtherPackages" and we follow the chain no
  12915. // further upward.
  12916. //
  12917. void addAllSuperAbstracts (Abstract * abs,
  12918.                            Header * hdr,
  12919.                            Mapping <Abstract, Abstract> * supersInThisPackage,
  12920.                            Mapping <Abstract, Abstract> * supersInOtherPackages) {
  12921.   ClassDef * cl, * supercl;
  12922.   Interface * inter, * superInter;
  12923.   TypeArg * typeArg;
  12924.   NamedType * nType;
  12925.  
  12926.   //    printf ("    %s: CALLED; adding this to supersInThisPackage\n", abs->id->chars);
  12927.  
  12928.   // Only consider Abstracts in this package...
  12929.   if (abs->myHeader != hdr) {
  12930.     supersInOtherPackages->enter (abs, abs);
  12931.     return;
  12932.   }
  12933.  
  12934.   // Put this abstract into the set if it is not already there...
  12935.   if (! supersInThisPackage->alreadyDefined (abs)) {
  12936.     supersInThisPackage->enter (abs, abs);
  12937.   }
  12938.  
  12939.   if (abs->op == CLASS_DEF) {
  12940.     cl = (ClassDef *) abs;
  12941.     // Identify the superclass, if any...
  12942.     //    printf ("    %s:   Looking at the superclass...\n", abs->id->chars);
  12943.     nType = cl->superclass;
  12944.     if (nType &&
  12945.         nType->myDef &&
  12946.         nType->myDef->op == CLASS_DEF) {
  12947.       supercl = (ClassDef *) nType->myDef;
  12948.       // Recursively consider adding it to the set.
  12949.       addAllSuperAbstracts (supercl,
  12950.                             hdr,
  12951.                             supersInThisPackage,
  12952.                             supersInOtherPackages);
  12953.     }
  12954.     for (typeArg = cl->implements; typeArg; typeArg = typeArg->next) {
  12955.       //    printf ("    %s:   Looking next interface in the implements clause...\n",
  12956.       //            abs->id->chars);
  12957.       nType = (NamedType *) typeArg->type;
  12958.       if (nType &&
  12959.           nType->op == NAMED_TYPE &&
  12960.           nType->myDef &&
  12961.           nType->myDef->op == INTERFACE) {
  12962.         superInter = (Interface *) nType->myDef;
  12963.         //    printf ("    %s:     Looking at interface %s...\n",
  12964.         //            abs->id->chars, nType->id->chars);
  12965.         // Recursively consider adding it to the set.
  12966.         addAllSuperAbstracts (superInter,
  12967.                               hdr,
  12968.                               supersInThisPackage,
  12969.                               supersInOtherPackages);
  12970.       }
  12971.     }
  12972.   } else if (abs->op == INTERFACE) {
  12973.     inter = (Interface *) abs;
  12974.     for (typeArg = inter->extends; typeArg; typeArg = typeArg->next) {
  12975.       //    printf ("    %s:   Looking next interface in the extends clause...\n",
  12976.       //            abs->id->chars);
  12977.       nType = (NamedType *) typeArg->type;
  12978.       if (nType &&
  12979.           nType->op == NAMED_TYPE &&
  12980.           nType->myDef &&
  12981.           nType->myDef->op == INTERFACE) {
  12982.         superInter = (Interface *) nType->myDef;
  12983.         //    printf ("    %s:     Looking at interface %s...\n",
  12984.         //            abs->id->chars, nType->id->chars);
  12985.         // Recursively consider adding it to the set.
  12986.         addAllSuperAbstracts (superInter,
  12987.                               hdr,
  12988.                               supersInThisPackage,
  12989.                               supersInOtherPackages);
  12990.       }
  12991.     }
  12992.   } else {
  12993.     programLogicError ("Unexpected node in addAllSuperAbstracts");
  12994.   }
  12995.   //    printf ("    %s: DONE\n", abs->id->chars);
  12996. }
  12997.  
  12998.  
  12999.  
  13000. // nextDispatchOffset (offset)  -->  offset
  13001. //
  13002. // This routine is passed an offset; it returns the next, successor offset.  It will
  13003. // see if we have already created this offset.  If so, it will return a pre-existing
  13004. // offset.  (This allows offsets to be compared with ==.)  If not, it will create
  13005. // a new offset and add it to the linked list as the successor of the given offset.
  13006. // Once created, an offset is never freed.
  13007. //
  13008. Offset * nextDispatchOffset (Offset * previousOffset) {
  13009.   Offset * newOff = previousOffset->nextOffset;
  13010.   if (newOff) return newOff;
  13011.   newOff = new Offset;
  13012.   // The value used here is the increment between message offsets in dispatch tables...
  13013.   newOff->ivalue = previousOffset->ivalue + 4;
  13014.   newOff->nextOffset = NULL;
  13015.   previousOffset->nextOffset = newOff;
  13016.   return newOff;
  13017. }
  13018.  
  13019.  
  13020.  
  13021. // stackPush (stack, Abstract)
  13022. //
  13023. // The routine "stackPush", "stackPop", "stackEmpty", and "newStack" are used
  13024. // to manipulate stacks of Abstracts.  A stack is represented as a pointer to
  13025. // a linked list of "AbstractStack" structs.  The top element is a dummy
  13026. // element, with "element" == NULL.  The linked list always contains this dummy
  13027. // element.
  13028. //
  13029. // This routine pushes an Abstract onto the stack given stack.
  13030. //
  13031. void stackPush (AbstractStack * st, Abstract * elt) {
  13032.   AbstractStack * n = new AbstractStack;
  13033.   n->element = elt;
  13034.   n->next = st->next;
  13035.   st->next = n;
  13036. }
  13037.  
  13038.  
  13039.  
  13040. // stackPop (stack)   -->  Abstract
  13041. //
  13042. // This routine pops the top element from a stack and returns it.
  13043. // If the stack is empty, a programLogicError will be generated.
  13044. //
  13045. Abstract * stackPop (AbstractStack * st) {
  13046.   Abstract * result;
  13047.   AbstractStack * old = st->next;
  13048.   if (old == NULL) {
  13049.     programLogicError ("Attempt to pop from an empty stack of Abstracts");
  13050.   }
  13051.   result = old->element;
  13052.   st->next = old->next;
  13053.   delete old;
  13054.   return result; 
  13055. }
  13056.  
  13057.  
  13058.  
  13059. // stackEmpty (stack)
  13060. //
  13061. // This routine returns true if the given stack is empty.
  13062. //
  13063. int stackEmpty (AbstractStack * st) {
  13064.   if (st->next == NULL) return 1;
  13065.   return 0;
  13066. }
  13067.  
  13068.  
  13069.  
  13070. // newStack ()  --> stack
  13071. //
  13072. // This routine returns a dummy element and is used to initialize the stack.
  13073. //
  13074. AbstractStack * newStack () {
  13075.   AbstractStack * n = new AbstractStack;
  13076.   n->element = NULL;
  13077.   n->next = NULL;
  13078.   return n;
  13079. }
  13080.