home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Language / Compiler / copyTree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-16  |  6.4 KB  |  225 lines

  1. /*
  2.  * @(#)copyTree.c    1.2  1/20/89
  3.  */
  4. #include "assert.h"
  5. #include "nodes.h"
  6. #include "sequence.h"
  7. #include "system.h"
  8. #include "map.h"
  9. #include "semantics.h"
  10. #include "trace.h"
  11.  
  12. static Map copyMap;
  13. static NodePtr *swith;
  14. static Symbol *sfor;
  15. static int slength;
  16. static NodePtr gRoot, gNewRoot;
  17.  
  18. NodePtr cTree(), _cTree();
  19. #define CTREE(T) ((int)(T) <= 0x200 ? (T) : _cTree(T))
  20.  
  21. void cSymbol(new, old)
  22. NodePtr new, old;
  23.   register Symbol s = old->b.symdef.symbol;
  24.   register Symbol newS;
  25.   register NodePtr r;
  26.   NodePtr list;
  27.   register int mapResult;
  28.  
  29.   mapResult = Map_Lookup(copyMap, (int)s);
  30.   if (old->tag == P_SYMDEF) {
  31.     newS = (Symbol) malloc(sizeof(STEntry));
  32.     *newS = *s;
  33.     Map_Insert(copyMap, (int)s, (int)newS);
  34.     if (mapResult == NIL) {
  35.       /* this is the first time we saw the symbol */
  36.     } else {
  37.       /* we need to fix previously seen symrefs */
  38.       assert(mapResult < 0);
  39.       list = (NodePtr) (-mapResult);
  40.       assert(list->tag == T_SEQUENCE);
  41.       Sequence_For(r, list)
  42.     assert(r->tag == P_SYMREF);
  43.     r->b.symref.symbol = newS;
  44.       Sequence_Next
  45.       free((char *) list);
  46.     }
  47.     newS->value.ATinfo = NULL;
  48.     newS->value.CTinfo = NULL;
  49.     newS->value.value = NULL;
  50.     newS->isManifest = FALSE;
  51.     newS->hasValue = FALSE;
  52.     new->b.symdef.symbol = newS;
  53.   } else {
  54.     assert(old->tag == P_SYMREF);
  55.     if (mapResult != NIL && mapResult > 0) {
  56.       new->b.symref.symbol = (Symbol) mapResult;
  57.     } else {
  58.       if (mapResult == NIL) {
  59.     list = F_NewNode(T_SEQUENCE, 4);
  60.     Map_Insert(copyMap, (int)s, -(int)list);
  61.       } else {
  62.     list = (NodePtr) (-mapResult);
  63.       }
  64.       Sequence_Add(&list, new);
  65.       new->b.symref.symbol = old->b.symref.symbol;
  66.     }
  67.   }
  68. }
  69.  
  70. /*
  71.  * We need to copy all nodes making this object.
  72.  */
  73.  
  74. NodePtr _cTree(p)
  75. register NodePtr p;
  76. {
  77.   register NodePtr newNode;
  78.   register int i, nRealChildren;
  79.   register Symbol st;
  80.   if ((int) p <= 0x200) {
  81.     newNode = p;
  82.   } else if ((newNode = (NodePtr) Map_Lookup(copyMap, (int)p)) != (NodePtr) NIL) {
  83.     /* do nothing, newNode is the right thing to return */
  84.   } else if ((p->tag == P_ATLIT || p->tag == P_OBLIT) && p->b.atlit.f.writeSeparately) {
  85.     assert(p->b.atlit.id != 0);
  86.     newNode = Construct(P_GLOBALREF, 0);
  87.     newNode->b.globalref.id = p->b.atlit.id;
  88.     newNode->b.globalref.value = p;
  89.   } else if (p->tag == P_SYMREF || p->tag == P_SYMDEF) {
  90.     st = p->b.symref.symbol;
  91.     for (i = 0; i < slength && sfor[i] != st; i++) ;
  92.     if (i < slength) {
  93.       /*
  94.        * We found it.  Return a pointer to the thing in swith[i].
  95.        */
  96.       newNode = swith[i];
  97.     } else {
  98.       goto regular;
  99.     }
  100.   } else {
  101. regular:
  102.     nRealChildren = p->nChildren - p->firstChild;
  103.     if (p == gRoot) {
  104.       newNode = gNewRoot;
  105.     } else {
  106.       newNode = F_NewNode(p->tag, nRealChildren);
  107.       newNode->nChildren += nRealChildren;
  108.     }
  109.     newNode->lineNumber = p->lineNumber;
  110.     Map_Insert(copyMap, (int)p, (int)newNode);
  111.     for (i = 0; i < newNode->firstChild; i++)
  112.       newNode->b.children[i] = p->b.children[i];
  113.  
  114.     switch (p->tag) {
  115.       case P_SYMDEF:
  116.       case P_SYMREF:
  117.     cSymbol(newNode, p);
  118.     break;
  119.       case P_INVOC:
  120.     newNode->b.invoc.resultTypeOID = 0;
  121.     for (i = newNode->firstChild; i < newNode->nChildren; i++)
  122.       newNode->b.children[i] = CTREE(p->b.children[i]);
  123.     break;
  124.       case P_VECTORLIT:
  125.     newNode->b.vectorlit.vectorType = NN;
  126.     for (i = newNode->firstChild; i < newNode->nChildren; i++)
  127.       newNode->b.children[i] = CTREE(p->b.children[i]);
  128.     break;
  129.       case P_OBLIT:
  130.       case P_ATLIT:
  131.     TRACE4(copy, 1, "Copying %s %s 0x%08x -> 0x%08x", 
  132.       tagNames[(int)p->tag],
  133.       p->b.oblit.name == NN ? "unknown" : 
  134.         ST_SymbolName(p->b.oblit.name->b.symdef.symbol),
  135.       p,
  136.       newNode);
  137.     newNode->b.oblit.sfname = p->b.oblit.sfname;
  138.     newNode->b.oblit.setq = CTREE(p->b.oblit.setq);
  139.     newNode->b.oblit.name = CTREE(p->b.oblit.name);
  140.     newNode->b.oblit.name->b.symdef.symbol->isSelf = TRUE;
  141.     newNode->b.oblit.name->b.symdef.symbol->value.value = newNode;
  142.     newNode->b.oblit.id = 0;
  143.     newNode->b.oblit.codeOID = 0;
  144.     newNode->b.oblit.f.isManifest = FALSE;
  145.     newNode->b.oblit.f.writeSeparately = FALSE;
  146.     newNode->b.oblit.f.isTypeVariable = FALSE;
  147.     newNode->b.oblit.f.inExecutableConstruct = FALSE;
  148.     newNode->b.oblit.f.dependsOnTypeVariable = FALSE;
  149.     newNode->b.oblit.f.typesAreAssigned = FALSE;
  150.     newNode->b.oblit.f.typesHaveBeenChecked = FALSE;
  151.     if (p->tag == P_ATLIT) {
  152.       newNode->b.atlit.ops = CTREE(p->b.atlit.ops);
  153.     } else {
  154.       newNode->b.oblit.myat = NULL;
  155.       newNode->b.oblit.instat = NULL;
  156.       newNode->b.oblit.export = CTREE(p->b.oblit.export);      
  157.       newNode->b.oblit.decls = CTREE(p->b.oblit.decls);      
  158.       newNode->b.oblit.monitor = CTREE(p->b.oblit.monitor);      
  159.       newNode->b.oblit.ops = CTREE(p->b.oblit.ops);      
  160.       newNode->b.oblit.process = CTREE(p->b.oblit.process);      
  161.     }
  162.     break;
  163.       default:
  164.     for (i = newNode->firstChild; i < newNode->nChildren; i++)
  165.       newNode->b.children[i] = CTREE(p->b.children[i]);
  166.     break;
  167.     }
  168.   }
  169.   return(newNode);
  170. }
  171.  
  172. /*
  173.  * This routine returns a copy of the tree, with symbols resolved, but no
  174.  * type checking or assignment done.  Each occurance of a symref node in the 
  175.  * tree that refers to one of the symbols in subfor is replaced with a
  176.  * reference to the corresponding thing from subwith.
  177.  */
  178.  
  179. NodePtr cTree(p, newRoot, subfor, subwith)
  180. NodePtr p, newRoot, subfor, subwith;
  181. {
  182.   NodePtr result;
  183.   register int i;
  184.  
  185.   if ((p->tag == P_ATLIT || p->tag == P_OBLIT) && p->b.atlit.f.writeSeparately) {
  186.     if (newRoot == NN) {
  187.       assert(p->b.atlit.id != 0);
  188.       result = Construct(P_GLOBALREF, 0);
  189.       result->b.globalref.id = p->b.atlit.id;
  190.       result->b.globalref.value = p;
  191.     } else {
  192.       assert(newRoot->tag == P_GLOBALREF);
  193.       assert(newRoot->b.globalref.value == p);
  194.       result = newRoot;
  195.     }
  196.     return(result);
  197.   }
  198.   if (newRoot == NN) {
  199.     /*
  200.      * Just allocate and return the root.
  201.      */
  202.     result = F_NewNode(p->tag, p->nChildren - p->firstChild);
  203.     result->nChildren = p->nChildren;
  204.   } else {
  205.     slength = Sequence_Length(subfor);
  206.     assert(Sequence_Length(subwith) == slength);
  207.     sfor = (Symbol *) calloc((unsigned)slength, sizeof(Symbol));
  208.     swith = (NodePtr *) calloc((unsigned)slength, sizeof(NodePtr));
  209.     for (i = 0; i < slength; i++) {
  210.       sfor[i] = subfor->b.children[i]->b.symdef.symbol;
  211.       swith[i] = subwith->b.children[i];
  212.     }
  213.     copyMap = Map_Create();
  214.     gRoot = p;
  215.     gNewRoot = newRoot;
  216.     result = CTREE(p);
  217.     assert(result == gNewRoot);
  218.     Map_Destroy(copyMap);
  219.     free((char *)sfor);
  220.     free((char *)swith);
  221.   }
  222.   return(result);
  223. }
  224.