home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)copyTree.c 1.2 1/20/89
- */
- #include "assert.h"
- #include "nodes.h"
- #include "sequence.h"
- #include "system.h"
- #include "map.h"
- #include "semantics.h"
- #include "trace.h"
-
- static Map copyMap;
- static NodePtr *swith;
- static Symbol *sfor;
- static int slength;
- static NodePtr gRoot, gNewRoot;
-
- NodePtr cTree(), _cTree();
- #define CTREE(T) ((int)(T) <= 0x200 ? (T) : _cTree(T))
-
- void cSymbol(new, old)
- NodePtr new, old;
- {
- register Symbol s = old->b.symdef.symbol;
- register Symbol newS;
- register NodePtr r;
- NodePtr list;
- register int mapResult;
-
- mapResult = Map_Lookup(copyMap, (int)s);
- if (old->tag == P_SYMDEF) {
- newS = (Symbol) malloc(sizeof(STEntry));
- *newS = *s;
- Map_Insert(copyMap, (int)s, (int)newS);
- if (mapResult == NIL) {
- /* this is the first time we saw the symbol */
- } else {
- /* we need to fix previously seen symrefs */
- assert(mapResult < 0);
- list = (NodePtr) (-mapResult);
- assert(list->tag == T_SEQUENCE);
- Sequence_For(r, list)
- assert(r->tag == P_SYMREF);
- r->b.symref.symbol = newS;
- Sequence_Next
- free((char *) list);
- }
- newS->value.ATinfo = NULL;
- newS->value.CTinfo = NULL;
- newS->value.value = NULL;
- newS->isManifest = FALSE;
- newS->hasValue = FALSE;
- new->b.symdef.symbol = newS;
- } else {
- assert(old->tag == P_SYMREF);
- if (mapResult != NIL && mapResult > 0) {
- new->b.symref.symbol = (Symbol) mapResult;
- } else {
- if (mapResult == NIL) {
- list = F_NewNode(T_SEQUENCE, 4);
- Map_Insert(copyMap, (int)s, -(int)list);
- } else {
- list = (NodePtr) (-mapResult);
- }
- Sequence_Add(&list, new);
- new->b.symref.symbol = old->b.symref.symbol;
- }
- }
- }
-
- /*
- * We need to copy all nodes making this object.
- */
-
- NodePtr _cTree(p)
- register NodePtr p;
- {
- register NodePtr newNode;
- register int i, nRealChildren;
- register Symbol st;
- if ((int) p <= 0x200) {
- newNode = p;
- } else if ((newNode = (NodePtr) Map_Lookup(copyMap, (int)p)) != (NodePtr) NIL) {
- /* do nothing, newNode is the right thing to return */
- } else if ((p->tag == P_ATLIT || p->tag == P_OBLIT) && p->b.atlit.f.writeSeparately) {
- assert(p->b.atlit.id != 0);
- newNode = Construct(P_GLOBALREF, 0);
- newNode->b.globalref.id = p->b.atlit.id;
- newNode->b.globalref.value = p;
- } else if (p->tag == P_SYMREF || p->tag == P_SYMDEF) {
- st = p->b.symref.symbol;
- for (i = 0; i < slength && sfor[i] != st; i++) ;
- if (i < slength) {
- /*
- * We found it. Return a pointer to the thing in swith[i].
- */
- newNode = swith[i];
- } else {
- goto regular;
- }
- } else {
- regular:
- nRealChildren = p->nChildren - p->firstChild;
- if (p == gRoot) {
- newNode = gNewRoot;
- } else {
- newNode = F_NewNode(p->tag, nRealChildren);
- newNode->nChildren += nRealChildren;
- }
- newNode->lineNumber = p->lineNumber;
- Map_Insert(copyMap, (int)p, (int)newNode);
- for (i = 0; i < newNode->firstChild; i++)
- newNode->b.children[i] = p->b.children[i];
-
- switch (p->tag) {
- case P_SYMDEF:
- case P_SYMREF:
- cSymbol(newNode, p);
- break;
- case P_INVOC:
- newNode->b.invoc.resultTypeOID = 0;
- for (i = newNode->firstChild; i < newNode->nChildren; i++)
- newNode->b.children[i] = CTREE(p->b.children[i]);
- break;
- case P_VECTORLIT:
- newNode->b.vectorlit.vectorType = NN;
- for (i = newNode->firstChild; i < newNode->nChildren; i++)
- newNode->b.children[i] = CTREE(p->b.children[i]);
- break;
- case P_OBLIT:
- case P_ATLIT:
- TRACE4(copy, 1, "Copying %s %s 0x%08x -> 0x%08x",
- tagNames[(int)p->tag],
- p->b.oblit.name == NN ? "unknown" :
- ST_SymbolName(p->b.oblit.name->b.symdef.symbol),
- p,
- newNode);
- newNode->b.oblit.sfname = p->b.oblit.sfname;
- newNode->b.oblit.setq = CTREE(p->b.oblit.setq);
- newNode->b.oblit.name = CTREE(p->b.oblit.name);
- newNode->b.oblit.name->b.symdef.symbol->isSelf = TRUE;
- newNode->b.oblit.name->b.symdef.symbol->value.value = newNode;
- newNode->b.oblit.id = 0;
- newNode->b.oblit.codeOID = 0;
- newNode->b.oblit.f.isManifest = FALSE;
- newNode->b.oblit.f.writeSeparately = FALSE;
- newNode->b.oblit.f.isTypeVariable = FALSE;
- newNode->b.oblit.f.inExecutableConstruct = FALSE;
- newNode->b.oblit.f.dependsOnTypeVariable = FALSE;
- newNode->b.oblit.f.typesAreAssigned = FALSE;
- newNode->b.oblit.f.typesHaveBeenChecked = FALSE;
- if (p->tag == P_ATLIT) {
- newNode->b.atlit.ops = CTREE(p->b.atlit.ops);
- } else {
- newNode->b.oblit.myat = NULL;
- newNode->b.oblit.instat = NULL;
- newNode->b.oblit.export = CTREE(p->b.oblit.export);
- newNode->b.oblit.decls = CTREE(p->b.oblit.decls);
- newNode->b.oblit.monitor = CTREE(p->b.oblit.monitor);
- newNode->b.oblit.ops = CTREE(p->b.oblit.ops);
- newNode->b.oblit.process = CTREE(p->b.oblit.process);
- }
- break;
- default:
- for (i = newNode->firstChild; i < newNode->nChildren; i++)
- newNode->b.children[i] = CTREE(p->b.children[i]);
- break;
- }
- }
- return(newNode);
- }
-
- /*
- * This routine returns a copy of the tree, with symbols resolved, but no
- * type checking or assignment done. Each occurance of a symref node in the
- * tree that refers to one of the symbols in subfor is replaced with a
- * reference to the corresponding thing from subwith.
- */
-
- NodePtr cTree(p, newRoot, subfor, subwith)
- NodePtr p, newRoot, subfor, subwith;
- {
- NodePtr result;
- register int i;
-
- if ((p->tag == P_ATLIT || p->tag == P_OBLIT) && p->b.atlit.f.writeSeparately) {
- if (newRoot == NN) {
- assert(p->b.atlit.id != 0);
- result = Construct(P_GLOBALREF, 0);
- result->b.globalref.id = p->b.atlit.id;
- result->b.globalref.value = p;
- } else {
- assert(newRoot->tag == P_GLOBALREF);
- assert(newRoot->b.globalref.value == p);
- result = newRoot;
- }
- return(result);
- }
- if (newRoot == NN) {
- /*
- * Just allocate and return the root.
- */
- result = F_NewNode(p->tag, p->nChildren - p->firstChild);
- result->nChildren = p->nChildren;
- } else {
- slength = Sequence_Length(subfor);
- assert(Sequence_Length(subwith) == slength);
- sfor = (Symbol *) calloc((unsigned)slength, sizeof(Symbol));
- swith = (NodePtr *) calloc((unsigned)slength, sizeof(NodePtr));
- for (i = 0; i < slength; i++) {
- sfor[i] = subfor->b.children[i]->b.symdef.symbol;
- swith[i] = subwith->b.children[i];
- }
- copyMap = Map_Create();
- gRoot = p;
- gNewRoot = newRoot;
- result = CTREE(p);
- assert(result == gNewRoot);
- Map_Destroy(copyMap);
- free((char *)sfor);
- free((char *)swith);
- }
- return(result);
- }
-