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

  1. /*
  2.  * @(#)depManifest.c    1.8  1/15/88
  3.  */
  4. #include "assert.h"
  5. #include "nodes.h"
  6. #include "map.h"
  7. #include "sequence.h"
  8. #include "trace.h"
  9. #include "semantics.h"
  10. #include "builtins.h"
  11. #include "MyParser.h"
  12. #include "flags.h"
  13. #include "error.h"
  14. #include "environment.h"
  15. #include "system.h"
  16. #include "typecheck.h"
  17.  
  18. /*
  19.  * Imported routines.
  20.  */
  21.  
  22. extern NodePtr 
  23.     buildATOfObject(),
  24.     buildOpName(),
  25.     cTree(), 
  26.     checkInvocCache(),
  27.     copyTree(),
  28.     evaluateForAT(),
  29.     figureOutAT(),
  30.     findObjectOperation(),
  31.     getExportedATOfObject();
  32.  
  33. extern void 
  34.     resolveGlobal(),
  35.     tryToSetCTInfo(),
  36.     updateInvocCache();
  37. extern Boolean 
  38.     conforms();
  39. extern OID
  40.     AllocateOID(),
  41.     OIDOf();
  42.  
  43. /*
  44.  * Imported variables.
  45.  */
  46.  
  47. extern Map manifestMap;
  48.  
  49. /*
  50.  * Private types.
  51.  */
  52.  
  53. typedef enum { IS_Step1, IS_Step2, IS_Step3, IS_Step4 } IS_Step;
  54.  
  55. typedef struct sManifestSE {
  56.   Map             candidates;
  57.   Set             manifestThings;
  58.   NodePtr         SCstack;
  59.   struct sManifestSE    *next;
  60. } ManifestSE, *ManifestStack;
  61.  
  62. /*
  63.  * Private variables.
  64.  */
  65.  
  66. Map dependManifestMap;
  67. DelayedCheckPtr delayedChecks = NULL;
  68. static NodePtr objectStack;
  69. static NodePtr getSignatureOpName = NULL, createOpName = NULL;
  70. static int count = 0;
  71. static ManifestStack manStack = NULL;
  72.  
  73. /*
  74.  * Private definitions
  75.  */
  76.  
  77. #define literalHasValue(p) ( (p)->b.oblit.f.isManifest || \
  78.                  (p)->b.oblit.f.isTypeVariable || \
  79.                  (p)->b.oblit.f.dependsOnTypeVariable )
  80.  
  81. #define symbolHasValue(s) ((s)->isManifest || (s)->hasValue)
  82. #define NAMEOF(N) (ST_SymbolName((N)->b.symdef.symbol))
  83. #define min(A, B) ((A) < (B) ? (A) : (B))
  84. #define TOPOF(S) ((S)->b.children[(S)->nChildren-1])
  85. #define ATTOPLEVEL (manStack->next == NULL)
  86. #define OBOIDAssigned(p) ((p)->b.oblit.id != 0 || (p)->b.oblit.codeOID != 0)
  87. #define ATOIDAssigned(p) ((p)->b.atlit.id != 0)
  88.  
  89. /*
  90.  * Forward declarations of routines.
  91.  */
  92. static void
  93.     newFigureObjectTypes();
  94. void
  95.     doKnowManifests(),
  96.     newAssignTypes();
  97.  
  98. NodePtr findManifestValue(),
  99.     findTheResultExpression(),
  100.     newExecuteAsAT();
  101.  
  102. /*
  103.  * fetchMan finds the knowmanifest record for the given node.  If isParent
  104.  * is true, then the record must be found in the top entry on the manifest
  105.  * stack, else it can be found anywhere.  If it is not found, it is created 
  106.  * in the top map.
  107.  */
  108.  
  109. NodePtr fetchMan(p, isParent)
  110. NodePtr p;
  111. Boolean isParent;
  112. {
  113.   NodePtr answer, lookup;
  114.   register ManifestStack s;
  115.  
  116.   switch (p->tag) {
  117.     case P_GLOBALREF:
  118.       resolveGlobal(p, (ValuePtr)NULL);
  119.       assert(p->b.globalref.value != NN);
  120.       lookup = p->b.globalref.value;
  121.       break;
  122.     case P_SYMREF:
  123.     case P_SYMDEF:
  124.       lookup = (NodePtr) p->b.symref.symbol;
  125.       break;
  126.     default:
  127.       lookup = p;
  128.       break;
  129.   }
  130.   if (isParent) {
  131.     for (s = manStack->next; s != NULL; s = s->next) {
  132.       assert(Map_Lookup(s->candidates, (int)lookup) == NIL);
  133.     }
  134.   }
  135.   answer = (NodePtr) Map_Lookup(dependManifestMap, (int)lookup);
  136.   if ((int) answer != NIL) return(answer);
  137.   answer = Construct(P_KNOWMANIFEST, 3, NN, NN, NN);
  138.   answer->b.knowmanifest.tag = lookup->tag;
  139.   answer->b.knowmanifest.definingThing = lookup;
  140.   Map_Insert(dependManifestMap, (int)lookup, (int)answer);
  141.   Map_Insert(manStack->candidates, (int)lookup, (int)answer);
  142.   return(answer);
  143. }
  144.  
  145. static void MAN_AddPrereq(p, c)
  146. NodePtr p, c;
  147. {
  148.   NodePtr childStruct, parentStruct;
  149.   assert(c != NN && p != NN);
  150.  
  151.   parentStruct = fetchMan(p, TRUE);
  152.   childStruct =  fetchMan(c, FALSE);
  153.   SET_INSERT(parentStruct->b.knowmanifest.dependsOn, childStruct);
  154. }
  155.  
  156. NodePtr getGetSignatureResult(p, wantLit)
  157. NodePtr p;
  158. Boolean wantLit;
  159. {
  160.   register NodePtr opdef, opsig, r;
  161.  
  162.   if (getSignatureOpName == NULL)
  163.     getSignatureOpName = buildOpName("getsignature", -1);
  164.   assert(p->tag == P_OBLIT);
  165.   opdef = findObjectOperation(p, getSignatureOpName);
  166.   if (opdef == NULL) return(NULL);
  167.   opsig = opdef->b.opdef.sig;
  168.   if (! opsig->b.opsig.isFunction) return(NULL);
  169.   if (Sequence_Length(opsig->b.opsig.params) != 0) return(NULL);
  170.   if (Sequence_Length(opsig->b.opsig.results) != 1) return(NULL);
  171.   r = opsig->b.opsig.results->b.children[0]->b.param.type;
  172.   if (r->tag != P_BUILTINLIT) return(NULL);
  173.   if (r->b.builtinlit.whichType != KSIGNATURE) return(NULL);
  174.   return(findTheResultExpression(opdef, wantLit));
  175. }
  176.  
  177. NodePtr getCreateResult(p, wantLit)
  178. NodePtr p;
  179. Boolean wantLit;
  180. {
  181.   register NodePtr opdef, opsig;
  182.  
  183.   if (createOpName == NULL)
  184.     createOpName = buildOpName("create", -1);
  185.   assert(p->tag == P_OBLIT);
  186.   opdef = findObjectOperation(p, createOpName);
  187.   if (opdef == NULL) return(NULL);
  188.   opsig = opdef->b.opdef.sig;
  189.   if (Sequence_Length(opsig->b.opsig.results) != 1) return(NULL);
  190.   return(findTheResultExpression(opdef, wantLit));
  191. }
  192.  
  193. static Boolean isAlwaysTheSame(p)
  194. NodePtr p;
  195. {
  196.   if (bflag) {
  197.     return(FALSE);
  198.   }
  199.   return(p->b.oblit.f.immutable);
  200. }
  201.  
  202. void MAN_SetImport(p)
  203. NodePtr p;
  204. {
  205.   NodePtr q;
  206.   q = fetchMan(p, FALSE);
  207.   assert((int)q != NIL);
  208.   q->b.knowmanifest.isImport = TRUE;
  209. }
  210.  
  211. void buildKnowManifestGraph(p, inExecutable)
  212. register NodePtr p;
  213. Boolean inExecutable;
  214. {
  215.   register NodePtr q;
  216.   Boolean doPop = FALSE;
  217.   register NodePtr inhibitedChild = NULL;
  218.   register NodePtr gsr;
  219.   Boolean childInExecutable = inExecutable, childrenDone = FALSE;
  220.  
  221.   if (ISTOKEN(p)) return;
  222.   switch (p->tag) {
  223.     case P_BLOCK:
  224.       childInExecutable = TRUE;
  225.       break;
  226.     case P_SETQ:
  227.       childrenDone = TRUE;
  228.       break;
  229.     case P_OBLIT:
  230.     case P_ATLIT:
  231.       Sequence_Add(&objectStack, p);
  232.       doPop = TRUE;
  233.       inhibitedChild = p->b.oblit.name;
  234.       break;
  235.     default:
  236.       break;
  237.   }
  238.   if (!childrenDone) {
  239.     Sequence_For(q, p)
  240.       if (!ISTOKEN(q) && q != inhibitedChild)
  241.     buildKnowManifestGraph(q, childInExecutable);
  242.     Sequence_Next
  243.   }
  244.   switch (p->tag) {
  245.     case P_INVOC:
  246.       MAN_AddPrereq(p, p->b.invoc.target);
  247.       Sequence_For(q, p->b.invoc.args)
  248.     assert(q->tag == P_ARG);
  249.     q = q->b.arg.exp;
  250.     MAN_AddPrereq(p, q);
  251.       Sequence_Next
  252.       break;
  253.     case P_CONSTDECL:
  254.       if (p->b.constdecl.value != NN)
  255.     MAN_AddPrereq(p->b.constdecl.sym, p->b.constdecl.value);
  256.       if (Sequence_Length(objectStack) != 0 && p->b.constdecl.type != NN)
  257.     MAN_AddPrereq(TOPOF(objectStack), p->b.constdecl.type);
  258.       break;
  259.     case P_VARDECL:
  260.       MAN_AddPrereq(TOPOF(objectStack), p->b.vardecl.type);
  261.       break;
  262.     case P_WHEREWIDGIT:
  263.       MAN_AddPrereq(p->b.wherewidgit.sym, p->b.wherewidgit.type);
  264.       MAN_AddPrereq(TOPOF(objectStack), p->b.wherewidgit.sym);
  265.       break;
  266.     case P_VIEW:
  267.       MAN_AddPrereq(TOPOF(objectStack), p->b.view.type);
  268.       break;
  269.     case P_RESTRICT:
  270.       MAN_AddPrereq(TOPOF(objectStack), p->b.restrict.type);
  271.       break;
  272.     case P_PARAM:
  273.       MAN_AddPrereq(TOPOF(objectStack), p->b.param.type);
  274.       if (p->b.param.constraint != NN) {
  275.     MAN_AddPrereq(p, p->b.param.constraint);
  276.     MAN_AddPrereq(p->b.param.sym, p);
  277.     MAN_AddPrereq(TOPOF(objectStack), p);
  278.       }
  279.       break;
  280.     case P_OBLIT:
  281.       gsr = getGetSignatureResult(p, FALSE);
  282.       if (gsr != NULL) MAN_AddPrereq(p, gsr);
  283.       if (inExecutable && ! isAlwaysTheSame(p)) {
  284.     MAN_AddPrereq(p, Construct(T_NONE, 0));
  285.       }
  286.       /* fall through */
  287.     case P_ATLIT:
  288.       Sequence_For(q, p->b.oblit.setq)
  289.     assert(q->b.setq.inner->tag == P_SYMDEF);
  290.     MAN_AddPrereq(q->b.setq.inner, q->b.setq.outer);
  291.     MAN_AddPrereq(p, q->b.setq.inner);
  292.     MAN_SetImport(q->b.setq.inner);
  293.       Sequence_Next
  294.       MAN_AddPrereq(p->b.oblit.name, p);
  295.       break;
  296.     default:
  297.       break;
  298.   }
  299.   if (doPop) objectStack->nChildren --;
  300. }
  301.  
  302. void initializeKnowManifest()
  303. {
  304.   dependManifestMap = Map_Create();
  305. }
  306.  
  307. static char *thingName(t)
  308. NodePtr t;
  309. {
  310.   static char buffer[128];
  311.   Tag tag = t->b.knowmanifest.tag;
  312.   NodePtr d = t->b.knowmanifest.definingThing;
  313.  
  314.   if (tag == P_SYMBOL) {
  315.     sprintf(buffer, "0x%08x Symbol %s (0x%08x)", t, ST_SymbolName((Symbol)(d)), d);
  316.   } else if (tag == P_OBLIT || tag == P_ATLIT) {
  317.     sprintf(buffer, "0x%08x %s %s (0x%08x) on line %d",
  318.       t,
  319.       tagNames[(int)tag],
  320.       ST_SymbolName(d->b.oblit.name->b.symdef.symbol),
  321.       d,
  322.       d->lineNumber);
  323.   } else {
  324.     sprintf(buffer, "0x%08x %s (0x%08x) on line %d", t, tagNames[(int)tag],
  325.       d, d->lineNumber);
  326.   }
  327.   return(buffer);
  328. }
  329.  
  330. void displayKnowManifestGraph()
  331. {
  332.   NodePtr thing, theStruct, q;
  333.   IFTRACE(knowmanifest, 4) {
  334.     Map_For(manStack->candidates, thing, theStruct)
  335.       printf("struct %s", thingName(theStruct));
  336.       if (theStruct->b.knowmanifest.isDone) printf(" isDone");
  337.       if (theStruct->b.knowmanifest.isOK) printf(" isOK");
  338.       printf(" depends on:\n");
  339.       Set_For(q, theStruct->b.knowmanifest.dependsOn)
  340.     printf("\t\tstruct %s\n", thingName(q));
  341.       Set_Next
  342.     Map_Next
  343.   }
  344. }
  345.  
  346. void fleshOutValue(value)
  347. Value *value;
  348. {
  349.   NodePtr p = value->value;
  350.   if (p->tag == P_GLOBALREF) {
  351.     resolveGlobal(p, (ValuePtr)NULL);
  352.     p = p->b.globalref.value;
  353.   }
  354.   if (p->tag == P_ATLIT) {
  355.     value->ATinfo = refToBuiltin(B_INSTAT, SIGNATUREINDEX);
  356.     value->CTinfo = refToBuiltin(B_INSTCT, SIGNATUREINDEX);
  357.   } else if (p->tag == P_OBLIT) {
  358.     assert(p->b.oblit.myat != NN);
  359.     value->ATinfo = p->b.oblit.myat;
  360.     value->CTinfo = p;
  361.   } else {
  362.     assert(FALSE);
  363.   }
  364. }
  365.  
  366. NodePtr findManifestValue(p)
  367. NodePtr p;
  368. {
  369.   NodePtr result, lookup = p;
  370.   Symbol st;
  371.   if (p->tag == P_SYMREF || p->tag == P_SYMDEF) {
  372.     lookup = (NodePtr) p->b.symref.symbol;
  373.   }
  374.   result = (NodePtr) Map_Lookup(dependManifestMap, (int)lookup);
  375.   if ((int) result != NIL) {
  376.     assert(result->tag == P_KNOWMANIFEST);
  377.     if (result->b.knowmanifest.isOK) {
  378.       assert(result->b.knowmanifest.answer != NULL);
  379.       result = result->b.knowmanifest.answer;
  380.     } else {
  381.       result = NULL;
  382.     }
  383.   } else {
  384.     result = NULL;
  385.   }
  386.   if (result == NULL) {
  387.     switch (p->tag) {
  388.       case P_ATLIT:
  389.     if (literalHasValue(p)) result = p;
  390.     break;
  391.       case P_OBLIT:
  392.     if (literalHasValue(p)) result = p;
  393.     break;
  394.       case P_GLOBALREF:
  395.     resolveGlobal(p, (ValuePtr) NULL);
  396.     result = p->b.globalref.value;
  397.     break;
  398.       case P_BUILTINLIT:
  399.     result = refToBuiltinFromToken(B_IT, p->b.builtinlit.whichType);
  400.     break;
  401.       case P_SYMREF:
  402.     st = p->b.symref.symbol;
  403.     if (symbolHasValue(st)) result = st->value.value;
  404.     break;
  405.       default:
  406.     break;
  407.     }
  408.   }
  409.   return(result);
  410. }
  411.  
  412. NodePtr findTheResultExpression(opdef, wantLit)
  413. NodePtr opdef;
  414. Boolean wantLit;
  415. {
  416.   register NodePtr q, r, answer;
  417.   register Symbol resultSym, st;
  418.  
  419.   assert(opdef->tag == P_OPDEF);
  420.   q = opdef->b.opdef.sig;
  421.   assert(q->tag == P_OPSIG);
  422.   if (Sequence_Length(q->b.opsig.results) != 1) return(NN);
  423.   q = q->b.opsig.results->b.children[0];
  424.   assert(q->tag == P_PARAM);
  425.   q = q ->b.param.sym;
  426.   assert(q->tag == P_SYMDEF);
  427.   resultSym = q->b.symdef.symbol;
  428.  
  429.   q = opdef->b.opdef.body;
  430.   assert(q->tag == P_BLOCK);
  431.   if (q->b.block.unavailablehandler != NN) return(NN);
  432.   if (q->b.block.failurehandler != NN) return(NN);
  433.   q = q->b.block.stats;
  434.   if (Sequence_Length(q) != 1) return(NN);
  435.   q = q->b.children[0];
  436.   if (q->tag != P_ASSIGNSTAT) return(NN);
  437.   if (Sequence_Length(q->b.assignstat.left) != 1) return(NN);
  438.   if (Sequence_Length(q->b.assignstat.right) != 1) return(NN);
  439.   r = q->b.assignstat.left->b.children[0];
  440.   if (r->tag != P_SYMREF) return(NN);
  441.   if (r->b.symref.symbol != resultSym) return(NN);
  442.   q = GETVALUE(q->b.assignstat.right->b.children[0]);
  443.   switch (q->tag) {
  444.     case P_OBLIT:
  445.     case P_ATLIT:
  446.       answer = q;
  447.       break;
  448.     case P_SYMREF:
  449.       if (wantLit) {
  450.     st = q->b.symref.symbol;
  451.     if (symbolHasValue(st)) {
  452.       answer = GETVALUE(st->value.value);
  453.     } else {
  454.       answer = NN;
  455.     }
  456.       } else {
  457.     answer = q;
  458.       }
  459.       break;
  460.     default:
  461.       answer = NN;
  462.       break;
  463.   }
  464.   return(answer);
  465. }
  466.  
  467. void executeAnInvocation(anElement, whichStep, theNewManifests)
  468. NodePtr anElement, *theNewManifests;
  469. IS_Step whichStep;
  470. {
  471.   NodePtr target, opName, actuals, opdef, formals, actual, formal,
  472.     formalType, dt, result, paramSyms, argValues, aSR, wheres, where,
  473.     newSyms, newValues, q;
  474.   Symbol st;
  475.   DelayedCheckPtr dc;
  476.  
  477.   assert(anElement->tag == P_KNOWMANIFEST);
  478.   assert(anElement->b.knowmanifest.tag == P_INVOC);
  479.   dt = anElement->b.knowmanifest.definingThing;
  480.  
  481.   /*
  482.    * Do the right stuff for this step of the invocation.  We should have
  483.    * checked already that it can be done, so assert false if things go
  484.    * wrong.
  485.    */
  486.   target = dt->b.invoc.target;
  487.   opName = dt->b.invoc.opname;
  488.   actuals = dt->b.invoc.args;
  489.   target = findManifestValue(target);
  490.   assert(target != NULL);
  491.   assert(target->tag == P_OBLIT);
  492.   assert(target->b.oblit.f.immutable);
  493.   opdef = findObjectOperation(target, opName);
  494.   assert(opdef != NULL);
  495.   assert(opdef->b.opdef.sig->b.opsig.isFunction);
  496.   formals = opdef->b.opdef.sig->b.opsig.params;
  497.   assert(Sequence_Length(formals) == Sequence_Length(actuals));
  498.   result = findTheResultExpression(opdef, TRUE);
  499.   assert(result->tag == P_ATLIT || result->tag == P_OBLIT);
  500.   switch (whichStep) {
  501.     case IS_Step2:
  502.       /*
  503.        * Allocate the answer node and stick it in anElement.answer.
  504.        */
  505.       anElement->b.knowmanifest.answer = cTree(result, NN, NN, NN);
  506.       break;
  507.     case IS_Step3:
  508.       assert(FALSE);
  509.       break;
  510.     case IS_Step4:
  511.       /*
  512.        * Go into the bodies of the invocations.  Record the type checks that
  513.        * we will have to make, and figure out the substitutions that will
  514.        * need to be performed on the result expression.  Then copy the tree.
  515.        */
  516.  
  517.       paramSyms = F_NewNode(T_SEQUENCE, Sequence_Length(actuals));
  518.       argValues = F_NewNode(T_SEQUENCE, Sequence_Length(actuals));
  519.       Sequence_For(actual, actuals)
  520.     formal = formals->b.children[z__z];
  521.     assert(actual->tag == P_ARG);
  522.     assert(formal->tag == P_PARAM);
  523.     actual = actual->b.arg.exp;
  524.     actual = findManifestValue(actual);
  525.     assert(actual != NULL);
  526.     formalType = findManifestValue(formal->b.param.type);
  527.     assert(formalType != NULL);
  528.     dc = (DelayedCheckPtr) malloc(sizeof(DelayedCheck));
  529.     dc->invoc = dt;
  530.     dc->expression = actual;
  531.     dc->kind = DC_Conform;
  532.     dc->type = formalType;
  533.     dc->next = delayedChecks;
  534.     delayedChecks = dc;
  535.  
  536.     if (formal->b.param.constraint != NULL) {
  537.       /* we need to do matching */
  538.       st = ST_Fetch(formal->b.param.sym->b.symdef.symbol);
  539.       assert(symbolHasValue(st));
  540.       assert(st->value.value != NULL);
  541.       formalType = figureOutAT(st->value.value);
  542.       assert(formalType != NULL);
  543.       assert(formalType->tag == P_ATLIT);
  544.       assert(formalType->b.atlit.f.isTypeVariable);
  545.       dc = (DelayedCheckPtr) malloc(sizeof(DelayedCheck));
  546.       dc->invoc = dt;
  547.       dc->expression = actual;
  548.       dc->kind = DC_Match;
  549.       dc->type = formalType;
  550.       dc->next = delayedChecks;
  551.       delayedChecks = dc;
  552.     }
  553.     /*
  554.      * Now, figure out the substitutions.
  555.      */
  556.     aSR = formal->b.param.sym;
  557.     assert(aSR != NULL);
  558.     assert(aSR->tag == P_SYMDEF);
  559.     Sequence_Add(¶mSyms, aSR);
  560.     Sequence_Add(&argValues, actual);
  561.       Sequence_Next
  562.       /*
  563.        * We need to deal with the constants declared in the where clause.
  564.        * These should be turned into constants in the body of the newly
  565.        * created thing.  We need to do the two pass thing on these, too.
  566.        */
  567.       newSyms = NN;
  568.       newValues = NN;
  569.       wheres = opdef->b.opdef.sig->b.opsig.where;
  570.       Sequence_For(where, wheres)
  571.     assert(where->tag == P_WHEREWIDGIT);
  572.     if (where->b.wherewidgit.op == OCONFORMSTO) {
  573.       /* do nothing */
  574.     } else if (where->b.wherewidgit.op == OIDENTITY) {
  575.       aSR = where->b.wherewidgit.sym;
  576.       assert(aSR->tag == P_SYMDEF);
  577.       Sequence_Add(&newSyms, aSR);
  578.       q = where->b.wherewidgit.type;
  579.       Sequence_Add(&newValues, cTree(q, NN, NN, NN));
  580.     } else {
  581.       assert(FALSE);
  582.     }
  583.       Sequence_Next
  584.  
  585.       paramSyms = RAPPEND(newSyms, paramSyms);
  586.       argValues = RAPPEND(newValues, argValues);
  587.  
  588.       Sequence_For(where, wheres)
  589.     assert(where->tag == P_WHEREWIDGIT);
  590.     if (where->b.wherewidgit.op == OCONFORMSTO) {
  591.       /* do nothing */
  592.     } else if (where->b.wherewidgit.op == OIDENTITY) {
  593.       aSR = where->b.wherewidgit.sym;
  594.       assert(aSR->tag == P_SYMDEF);
  595.       q = where->b.wherewidgit.type;
  596.       argValues->b.children[z__z] = 
  597.         cTree(q, argValues->b.children[z__z], paramSyms, argValues);
  598.       Sequence_Add(theNewManifests, argValues->b.children[z__z]);
  599.     } else {
  600.       assert(FALSE);
  601.     }
  602.       Sequence_Next
  603.  
  604.       /*
  605.        * Now that the substitutions have been done, we can flesh out the
  606.        * copy of the resulting expression.
  607.        */
  608.       anElement->b.knowmanifest.answer =
  609.     cTree(result, anElement->b.knowmanifest.answer, paramSyms, argValues);
  610.       Sequence_Add(theNewManifests, anElement->b.knowmanifest.answer);
  611.       break;
  612.     default:
  613.       assert(FALSE);
  614.       break;
  615.   }
  616. }
  617.  
  618. void checkDelayedChecks()
  619. {
  620.   register DelayedCheckPtr dc, tc;
  621.   NodePtr itsType;
  622.   for (dc = delayedChecks; dc; tc = dc->next, free((char *)dc), dc = tc) {
  623.     TRACE3(knowmanifest, 4, "Delayed check (%s) of 0x%08x and 0x%08x",
  624.       dc->kind == DC_Conform ? "conform" : "match",
  625.       dc->expression,
  626.       dc->type);
  627.     if (dc->kind == DC_Conform) {
  628.       itsType = evaluateForAT(dc->expression, TRUE);
  629.       if (!conforms(itsType, dc->type)) {
  630.     ErrorMessage(dc->invoc, "Types do not conform (delayed)");
  631.       }
  632.     } else if (dc->kind == DC_Match) {
  633.       if (!conforms(dc->expression, dc->type)) {
  634.     ErrorMessage(dc->invoc, "Argument does not satisfy constraint (delayed)");
  635.       }
  636.     } else {
  637.       assert(FALSE);
  638.     }
  639.   }
  640.   delayedChecks = NULL;
  641. }
  642.  
  643. void assignOIDs(p)
  644. register NodePtr p;
  645. {
  646.   register NodePtr gsr, cr;
  647.  
  648.   if (ISTOKEN(p)) return;
  649.   switch (p->tag) {
  650.     case P_KNOWMANIFEST:
  651.       assert(p->b.knowmanifest.answer != p);
  652.       assignOIDs(p->b.knowmanifest.answer);
  653.       break;
  654.     case P_ATLIT:
  655.       if (ATOIDAssigned(p)) {
  656.     TRACE1(knowmanifest, 7, "atlit %s already has a value",
  657.       p->b.atlit.name == NN ? "unknown" :
  658.       ST_SymbolName(p->b.atlit.name->b.symdef.symbol));
  659.       } else {
  660.     p->b.atlit.f.isManifest = 
  661.       !(p->b.atlit.f.isTypeVariable || p->b.atlit.f.dependsOnTypeVariable);
  662.     p->b.atlit.f.writeSeparately = p->b.atlit.f.isManifest;
  663.     if (p->b.atlit.f.isManifest) {
  664.       defineGlobal(p, 0);
  665.     } else {
  666.       p->b.atlit.id = AllocateOID();
  667.       OTInsert(p, p->b.atlit.id);
  668.     } 
  669.       }
  670.       break;
  671.     case P_OBLIT:
  672.       if (OBOIDAssigned(p)) {
  673.     TRACE1(knowmanifest, 7, "oblit %s already has a value",
  674.       p->b.oblit.name == NN ? "unknown" :
  675.       ST_SymbolName(p->b.oblit.name->b.symdef.symbol));
  676.       } else {
  677.     p->b.oblit.f.isManifest = 
  678.       !(p->b.oblit.f.isTypeVariable || p->b.oblit.f.dependsOnTypeVariable);
  679.     p->b.oblit.f.writeSeparately = p->b.oblit.f.isManifest;
  680.     gsr = getGetSignatureResult(p, TRUE);
  681.     if (gsr != NN) {
  682.       p->b.oblit.instat = gsr;
  683.       if (gsr->tag == P_ATLIT && gsr->b.atlit.f.cannotBeConformedTo &&
  684.           gsr->b.atlit.codeOID == 0) {
  685.         TRACE0(knowmanifest, 1, "Found ATLIT that cannotBeConformedTo");
  686.         assert(gsr->b.atlit.f.isVector);
  687.         cr = getCreateResult(p, TRUE);
  688.         assert(cr != NN);
  689.         assert(cr->tag == P_OBLIT);
  690.         if (cr->b.oblit.codeOID == 0) {
  691.           TRACE0(knowmanifest, 3, "Have to assignOIDs to the create result");
  692.           assignOIDs(cr);
  693.         }
  694.         gsr->b.atlit.codeOID = cr->b.oblit.codeOID;
  695.       }
  696.     }
  697.     p->b.oblit.id = AllocateOID();
  698.     if (p->b.oblit.f.isManifest && !p->b.oblit.f.immutable) {
  699.       assert(Zflag);
  700.       p->b.oblit.id &= 0xfeffffff;
  701.     }
  702.     OTInsert(p, p->b.oblit.id);
  703.     if (p->b.oblit.f.isManifest) {
  704.       p->b.oblit.codeOID = AllocateOID();
  705.       OTInsert(p, p->b.oblit.codeOID);
  706.     }
  707.       }
  708.       break;
  709.     default:
  710.       break;
  711.   }
  712. }
  713.     
  714. static void newFigureObjectTypes(p)
  715. register NodePtr p;
  716. {
  717.   Symbol st;
  718.  
  719.   if (ISTOKEN(p)) return;
  720.   switch (p->tag) {
  721.     case P_KNOWMANIFEST:
  722.       newFigureObjectTypes(p->b.knowmanifest.answer);
  723.       break;
  724.     case P_OBLIT:
  725.       if (p->b.oblit.name == NN) {
  726.     assert(bflag || loadedDummyBuiltins);
  727.       } else if (p->b.oblit.myat == NULL) {
  728.     st = ST_Fetch(p->b.oblit.name->b.symdef.symbol);
  729.     st->value.value  = p;
  730.     st->value.CTinfo = p;
  731.     st->value.ATinfo = buildATOfObject(p);
  732.     assert(st->value.ATinfo != NN);
  733.     p->b.oblit.myat = getExportedATOfObject(p, st->value.ATinfo);
  734.     assert(p->b.oblit.myat != NN);
  735.       }
  736.       break;
  737.     default:
  738.       break;
  739.   }
  740. }
  741.  
  742. void fleshOutAllSymbols(p)
  743. NodePtr p;
  744. {
  745.   NodePtr inhibitedChild = NN, q;
  746.   Boolean done = FALSE;
  747.   Symbol st;
  748.   if (ISTOKEN(p)) return;
  749.   switch (p->tag) {
  750.     case P_SYMBOL:
  751.       st = (Symbol) p;
  752.       if (st->value.ATinfo == NULL && st->value.value != NN) {
  753.     fleshOutValue(&st->value);
  754.       }
  755.       done = TRUE;
  756.       break;
  757.     case P_SYMDEF:
  758.     case P_SYMREF:
  759.       st = p->b.symref.symbol;
  760.       if (st->value.ATinfo == NULL && symbolHasValue(st)) {
  761.     
  762.     fleshOutValue(&st->value);
  763.       }
  764.       break;
  765.     default:
  766.       break;
  767.   }
  768.   if (!done) Sequence_For(q, p)
  769.     if (!ISTOKEN(q) && q != inhibitedChild) fleshOutAllSymbols(q);
  770.   Sequence_Next
  771. }
  772.  
  773. void doPropagate(p, secondTime)
  774. register Set p;
  775. Boolean secondTime;
  776. {
  777.   NodePtr anElement, value = NULL, myPrereq, oldValue, dt, km;
  778.   NodePtr oldAT, newAT;
  779.   register Symbol st;
  780.   Boolean doItAgain, madeProgress;
  781.   int nPass3s = 0;
  782.   OID savedID;
  783.   Boolean savedWriteSeparately;
  784.   do {
  785.     nPass3s++;
  786.     TRACE1(knowmanifest, 4, "Doing step 3, pass %d", nPass3s);
  787.     doItAgain = FALSE;
  788.     madeProgress = FALSE;
  789.     Set_For(anElement, p)
  790.       anElement->b.knowmanifest.isDone = TRUE;
  791.       anElement->b.knowmanifest.isOK = TRUE;
  792.       if (anElement->b.knowmanifest.answer != NN) continue;
  793.       dt = anElement->b.knowmanifest.definingThing;
  794.       switch (dt->tag) {
  795.     case P_INVOC:
  796.       executeAnInvocation(anElement, IS_Step2, (NodePtr *)NULL);
  797.       madeProgress = TRUE;
  798.       break;
  799.     case P_BUILTINLIT:
  800.       anElement->b.knowmanifest.answer =
  801.         refToBuiltinFromToken(B_IT, dt->b.builtinlit.whichType);
  802.       madeProgress = TRUE;
  803.       break;
  804.     case P_ATLIT:
  805.       if (!secondTime) {
  806.         assert(! dt->b.atlit.f.dependsOnTypeVariable);
  807.         assert(! dt->b.atlit.f.typesAreAssigned);
  808.         assert(! dt->b.atlit.f.typesHaveBeenChecked);
  809.         assert(! dt->b.atlit.f.isManifest);
  810.         assert(! dt->b.atlit.f.writeSeparately);
  811.         dt->b.atlit.f.dependsOnTypeVariable = 
  812.           anElement->b.knowmanifest.dependsOnTypeVariable;
  813.       }
  814.       anElement->b.knowmanifest.answer = dt;
  815.       madeProgress = TRUE;
  816.       break;
  817.     case P_OBLIT:
  818.       if (!secondTime) {
  819.         assert(! dt->b.oblit.f.dependsOnTypeVariable);
  820.         assert(! dt->b.oblit.f.typesAreAssigned);
  821.         assert(! dt->b.oblit.f.typesHaveBeenChecked);
  822.         assert(! dt->b.oblit.f.isManifest);
  823.         assert(! dt->b.oblit.f.writeSeparately);
  824.         dt->b.oblit.f.dependsOnTypeVariable = 
  825.           anElement->b.knowmanifest.dependsOnTypeVariable;
  826.       }
  827.       anElement->b.knowmanifest.answer = dt;
  828.       madeProgress = TRUE;
  829.       break;
  830.     case P_SYMBOL:
  831.       if (Set_Size(anElement->b.knowmanifest.dependsOn) == 1) {
  832.         st = (Symbol) dt;
  833.         Set_GetFirst(anElement->b.knowmanifest.dependsOn, myPrereq); 
  834.          if (myPrereq->b.knowmanifest.answer == NN) {
  835.           /* this has not been done yet, so arrange another pass 3 */
  836.           doItAgain = TRUE;
  837.         } else {
  838.           anElement->b.knowmanifest.answer = myPrereq->b.knowmanifest.answer;
  839.           st->isManifest = TRUE;
  840.           st->value.value = anElement->b.knowmanifest.answer;
  841.           madeProgress = TRUE;
  842.         }
  843.       } else {
  844.         st = (Symbol) dt;
  845.         assert(symbolHasValue(st));
  846.         assert(st->value.value != NN);
  847.         anElement->b.knowmanifest.answer = st->value.value;
  848.         madeProgress = TRUE;
  849.       }
  850.       break;
  851.     case P_PARAM:
  852.       /*
  853.        * We care if the value is an atlit or a something else.  If it is an
  854.        * atlit we modify it to be a typeVariable, otherwise we copy it and
  855.        * then modify the copy.
  856.        */
  857.       assert(Set_Size(anElement->b.knowmanifest.dependsOn) == 1);
  858.       
  859.       Set_GetFirst(anElement->b.knowmanifest.dependsOn, oldValue);
  860.       oldValue = oldValue->b.knowmanifest.answer;
  861.       value = dt->b.param.constraint;
  862.       st = dt->b.param.sym->b.symdef.symbol;
  863.       assert(value != NN && oldValue != NN);
  864.       if (value->tag != P_ATLIT) {
  865.         /* we need to copy it */
  866.         oldAT = newExecuteAsAT(oldValue);
  867.         if (oldAT == NULL) {
  868.           ErrorMessage(value, "Parameter constraints must be types");
  869.           oldAT = refToBuiltin(B_INSTAT, ABSTRACTTYPEINDEX);
  870.         }
  871.         TRACE3(knowmanifest, 3, "copying literal \"%s\" on line %d %s",
  872.           NAMEOF(oldAT->b.atlit.name), value->lineNumber, "");
  873.         savedID = oldAT->b.atlit.id;
  874.         savedWriteSeparately = oldAT->b.atlit.f.writeSeparately;
  875.         oldAT->b.atlit.f.writeSeparately = 0;
  876.         oldAT->b.atlit.id = 0;
  877.         newAT = copyTree(oldAT, TRUE);
  878.         oldAT->b.atlit.f.writeSeparately = savedWriteSeparately;
  879.         oldAT->b.atlit.id = savedID;
  880.       } else {
  881.         assert(oldValue->tag == P_ATLIT);
  882.         assert(oldValue == value);
  883.         newAT = oldValue;
  884.       }
  885.       newAT->b.atlit.f.isTypeVariable = TRUE;
  886.       km = (NodePtr) Map_Lookup(dependManifestMap, (int)newAT);
  887.       if ((int) km == NIL) {
  888.         km = Construct(P_KNOWMANIFEST, 3, NN, NN, NN);
  889.         km->b.knowmanifest.tag = newAT->tag;
  890.         km->b.knowmanifest.definingThing = newAT;
  891.         Map_Insert(dependManifestMap, (int)newAT, (int)km);
  892.       }
  893.       km->b.knowmanifest.isTypeVariable = TRUE;
  894.       km->b.knowmanifest.isDone = TRUE;
  895.       km->b.knowmanifest.isOK = TRUE;
  896.       if (km->b.knowmanifest.answer == NN)
  897.         km->b.knowmanifest.answer = newAT;
  898.       anElement->b.knowmanifest.isTypeVariable = TRUE;
  899.       newAT->b.atlit.f.isManifest = FALSE;
  900.       newAT->b.atlit.f.writeSeparately = FALSE;
  901.       newAT->b.atlit.id = AllocateOID();
  902.       OTInsert(newAT, newAT->b.atlit.id);
  903.       newAT->b.atlit.name->b.symdef.symbol->isManifest = FALSE;
  904.       newAT->b.atlit.name->b.symdef.symbol->hasValue = TRUE;
  905.       st->isManifest = FALSE;
  906.       st->hasValue = TRUE;
  907.       st->value.value = newAT;
  908.       TRACE3(knowmanifest, 2, "made literal \"%s\" on line %d %s",
  909.         NAMEOF(newAT->b.atlit.name), newAT->lineNumber,
  910.         "isTypeVariable");
  911.       anElement->b.knowmanifest.answer = newAT;
  912.       madeProgress = TRUE;
  913.       break;
  914.     default:
  915.       assert(FALSE);
  916.       break;
  917.       }
  918.     Set_Next
  919.     if (!madeProgress) {
  920.       TRACE0(knowmanifest, 1, "Didn't make progress, dying");
  921.       assert(FALSE);
  922.     }
  923.   } while (doItAgain);
  924. }
  925.  
  926. void propagateMANInfo()
  927. {
  928.   register Set p = manStack->manifestThings;
  929.   NodePtr q, anElement, dt, theNewManifests;
  930.   NodePtr an;
  931.   register Symbol st;
  932.   Boolean isManifest = TRUE, isImport;
  933.   Boolean dependsOnTypeVariable = FALSE,
  934.     typeDependsOnTypeVariable = FALSE;
  935.   int             setSize, nInvocs, nParams;
  936.  
  937.   nInvocs = 0;
  938.   nParams = 0;
  939.   setSize = Set_Size(p);
  940.  
  941.   if (setSize == 1) {
  942.     TRACE0(knowmanifest, 1, "Progagating to a single element");
  943.   } else {
  944.     TRACE1(knowmanifest, 1, "Progagating to a set of size %d",
  945.       setSize);
  946.   }
  947.   Set_For(anElement, p)
  948.     TRACE1(knowmanifest, 2, "Looking at pre-reqs of %s", thingName(anElement));
  949.     switch (anElement->b.knowmanifest.tag) {
  950.       case P_ATLIT:
  951.     break;
  952.       case P_PARAM:
  953.     nParams++;
  954.     break;
  955.       case P_SYMBOL:
  956.     if (Set_Size(anElement->b.knowmanifest.dependsOn) <= 0) {
  957.       st = (Symbol) anElement->b.knowmanifest.definingThing;
  958.       if (!symbolHasValue(st)) {
  959.         TRACE1(knowmanifest, 3, 
  960.           "Symbol %s has no dependents, is not manifest",
  961.           thingName(anElement));
  962.         isManifest = FALSE;
  963.         continue;
  964.       }
  965.     }
  966.     break;
  967.       case P_OBLIT:
  968.       case P_BUILTINLIT:
  969.     break;
  970.       case P_INVOC:
  971.     nInvocs++;
  972.     break;
  973.       default:
  974.     isManifest = FALSE;
  975.     continue;
  976.     /* break; */
  977.     }
  978.     Set_For(q, anElement->b.knowmanifest.dependsOn)
  979.       TRACE1(knowmanifest, 3, "Looking at %s", thingName(q));
  980.       assert(q->tag == P_KNOWMANIFEST);
  981.       if (! q->b.knowmanifest.isDone) continue; /* it is in this set */
  982.       if (!q->b.knowmanifest.isOK) {
  983.     isManifest = FALSE;
  984.     TRACE1(knowmanifest, 4, "%s not ok, give up", thingName(q));
  985.     break;
  986.       }
  987.       switch (anElement->b.knowmanifest.tag) {
  988.     case P_OBLIT:
  989.     case P_ATLIT:
  990.       isImport = q->b.knowmanifest.isImport;
  991.       break;
  992.     default:
  993.       isImport = TRUE;
  994.       break;
  995.       }
  996.       switch(q->b.knowmanifest.tag) {
  997.     case P_ATLIT:
  998.     case P_OBLIT:
  999.     case P_INVOC:
  1000.     case P_BUILTINLIT:
  1001.     case P_PARAM:
  1002.     case P_SYMBOL:
  1003.       break;
  1004.     case P_SELFLIT:
  1005.       assert(FALSE);
  1006.       break;
  1007.     case P_VECTORLIT:
  1008.     case P_BOOLLIT:
  1009.     case P_CHARLIT:
  1010.     case P_INTLIT:
  1011.     case P_REALLIT:
  1012.     case P_STRINGLIT:
  1013.     case T_NONE:
  1014.     default:
  1015.       isManifest = FALSE;
  1016.       break;
  1017.       }
  1018.       if (isImport &&
  1019.       (q->b.knowmanifest.dependsOnTypeVariable ||
  1020.        q->b.knowmanifest.isTypeVariable)) {
  1021.     TRACE1(knowmanifest, 3, "%s iTV or dOTV", thingName(q));
  1022.       dependsOnTypeVariable =
  1023.     dependsOnTypeVariable ||
  1024.     isImport && (
  1025.       q->b.knowmanifest.dependsOnTypeVariable ||
  1026.       q->b.knowmanifest.isTypeVariable);
  1027.       typeDependsOnTypeVariable =
  1028.     typeDependsOnTypeVariable ||
  1029.     q->b.knowmanifest.dependsOnTypeVariable ||
  1030.     q->b.knowmanifest.isTypeVariable;
  1031.     Set_Next
  1032.     }
  1033.     if (isManifest && anElement->b.knowmanifest.tag == P_INVOC) {
  1034. #define BAILOUT {isManifest = FALSE; goto bailout; }
  1035.       NodePtr target, opName, opdef, formals, actuals, result;
  1036.   
  1037.       q = anElement->b.knowmanifest.definingThing;
  1038.       assert(Map_Lookup(manifestMap, (int) q) == NIL);
  1039.   
  1040.       /* see if the invocation can be done */
  1041.       target = q->b.invoc.target;
  1042.       if (target->tag == P_SYMREF) target = (NodePtr) target->b.symref.symbol;
  1043.       opName = q->b.invoc.opname;
  1044.       actuals = q->b.invoc.args;
  1045.       target = findManifestValue(target);
  1046.       if (target->tag != P_OBLIT) BAILOUT;
  1047.       if (! target->b.oblit.f.immutable) BAILOUT;
  1048.       opdef = findObjectOperation(target, opName);
  1049.       if (opdef == NULL) BAILOUT;
  1050.       if (!opdef->b.opdef.sig->b.opsig.isFunction) BAILOUT;
  1051.       formals = opdef->b.opdef.sig->b.opsig.params;
  1052.       if (Sequence_Length(formals) != Sequence_Length(actuals)) BAILOUT;
  1053.       result = findTheResultExpression(opdef, TRUE);
  1054.       if (result == NN) BAILOUT;
  1055.   
  1056. bailout: ;
  1057. #undef BAILOUT
  1058.     }
  1059.   Set_Next
  1060.   if (nParams > 0 && setSize != 1) {
  1061.     isManifest = FALSE;
  1062.     TRACE0(knowmanifest, 1, "I do not know how to deal with params in sets.");
  1063.     assert(FALSE);
  1064.   }
  1065.   if (!isManifest) {
  1066.     TRACE0(knowmanifest, 1, "The set is not manifest");
  1067.     Set_For(anElement, p)
  1068.       anElement->b.knowmanifest.isDone = TRUE;
  1069.       anElement->b.knowmanifest.isOK = FALSE;
  1070.       anElement->b.knowmanifest.answer = NULL;
  1071.       anElement->b.knowmanifest.dependsOnTypeVariable = dependsOnTypeVariable;
  1072.       dt = anElement->b.knowmanifest.definingThing;
  1073.       switch (dt->tag) {
  1074.     case P_OBLIT:
  1075.       dt->b.oblit.f.typeDependsOnTypeVariable = typeDependsOnTypeVariable;
  1076.       dt->b.oblit.f.dependsOnTypeVariable = dependsOnTypeVariable;
  1077.       if (dt->b.oblit.f.dependsOnTypeVariable) {
  1078.         dt->b.oblit.codeOID = 0;
  1079.       } else {
  1080.         assert(dt->b.oblit.codeOID == 0);
  1081.         dt->b.oblit.codeOID = AllocateOID();
  1082.         OTInsert(dt, dt->b.oblit.codeOID);
  1083.       }
  1084.       if (dt->b.oblit.name == NN) {
  1085.         assert(bflag || loadedDummyBuiltins);
  1086.       } else {
  1087.         st = dt->b.oblit.name->b.symdef.symbol;
  1088.         assert(st->isSelf);
  1089.         assert(dt->b.oblit.myat == NULL);
  1090.         st->value.value  = dt;
  1091.         st->value.CTinfo = dt;
  1092.         st->value.ATinfo = buildATOfObject(dt);
  1093.         dt->b.oblit.myat = getExportedATOfObject(dt, st->value.ATinfo);
  1094.       }
  1095.       break;
  1096.     case P_ATLIT:
  1097.       WarningMessage(dt, "This abstract type is not manifest");
  1098.       break;
  1099.     default:
  1100.       break;
  1101.       }
  1102.     Set_Next
  1103.   } else {
  1104.     TRACE0(knowmanifest, 1, "The entire set is manifest");
  1105.  
  1106.     if (setSize == 1) {
  1107.       Set_GetFirst(p, anElement);
  1108.       assert(anElement->tag == P_KNOWMANIFEST);
  1109.       anElement->b.knowmanifest.dependsOnTypeVariable = dependsOnTypeVariable;
  1110.       dt = anElement->b.knowmanifest.definingThing;
  1111.       if (dt->tag == P_SYMBOL) {
  1112.     if (symbolHasValue((Symbol)dt)) {
  1113.       TRACE1(knowmanifest, 7, "%s is already manifest", thingName(anElement));
  1114.       anElement->b.knowmanifest.isOK = TRUE;
  1115.       anElement->b.knowmanifest.isDone = TRUE;
  1116.       assert(((Symbol)dt)->value.value != NN);
  1117.       anElement->b.knowmanifest.answer = ((Symbol)dt)->value.value;
  1118.       return;
  1119.     }
  1120.       } else if (dt->tag == P_ATLIT || dt->tag == P_OBLIT) {
  1121.     if (literalHasValue(dt)) {
  1122.       TRACE1(knowmanifest, 7, "%s is already manifest", thingName(anElement));
  1123.       anElement->b.knowmanifest.isOK = TRUE;
  1124.       anElement->b.knowmanifest.isDone = TRUE;
  1125.       anElement->b.knowmanifest.answer = dt;
  1126.       return;
  1127.     }
  1128.       } else if (dt->tag == P_INVOC) {
  1129.     NodePtr result;
  1130.     /*
  1131.      * There is a possibility that we have done this invocation before.
  1132.      * Check it out.  If we have, just get me the answer, and return.
  1133.      */
  1134.     result = checkInvocCache(dt);
  1135.     if (result != NN) {
  1136.       Value value;
  1137.       TRACE1(knowmanifest, 7, "%s by previous compilation",
  1138.         thingName(anElement));
  1139.       anElement->b.knowmanifest.isOK = TRUE;
  1140.       anElement->b.knowmanifest.isDone = TRUE;
  1141.       anElement->b.knowmanifest.answer = result;
  1142.       value.value = anElement->b.knowmanifest.answer;
  1143.       fleshOutValue(&value);
  1144.       Map_Insert(manifestMap, (int)dt, (int)value.ATinfo);
  1145.       Map_Insert(manifestMap, (int)dt+1, (int)value.CTinfo);
  1146.       Map_Insert(manifestMap, (int)dt+2, (int)value.value);
  1147.       dt->b.invoc.resultTypeOID = OIDOf(value.ATinfo);
  1148.       return;
  1149.     }
  1150.       }
  1151.     }
  1152.  
  1153.     /*
  1154.      * Now, we must figure out what all these manifest things are.
  1155.      *
  1156.      * 1)  Merge invocations that are the same.  Invocations are the same if
  1157.      * they have the same target, operationName, and if their arguments are
  1158.      * the same.  We only need to do this if the arguments to 2 of the
  1159.      * invocations are within this same set, bu they must be or the invocation
  1160.      * itself wouldn't be.  This is an optimization that attempts to only copy
  1161.      * the result tree once.  It is currently not done.
  1162.      *
  1163.      * 2)  Create the result nodes for each invocation, storing them in the
  1164.      * knowManifest node as the answer.  We need to allocate these roots before
  1165.      * we do any copying, as the argument to one invocation could be the result
  1166.      * of another one.
  1167.      *
  1168.      * 3)  Go through the entire set of manifest things, and set their result
  1169.      * pointers, instATs of object literals, values of symbols.  Note that
  1170.      * this includes the results of invocations, and all the types contained
  1171.      * inside of there.
  1172.      *
  1173.      * 4)  Record the need to check the types of each invocation.
  1174.      * Fill in the answer roots that were allocated in step 2.  Note that
  1175.      * this is just for invocation nodes.  We copy the tree that is the answer
  1176.      * in the invocation, performing substitutions as indicated by the
  1177.      * parameter passing and imports.  The answer is not the final tree, but
  1178.      * type assignment and checking has not yet been done.
  1179.      *
  1180.      * After this point, no further copying will need to be done.
  1181.      *
  1182.      * 5)  Assign OIDs to the literals.  This probably doesn't need to be a
  1183.      * separate pass, but what the heck.
  1184.      *
  1185.      * 6)  Assign types.
  1186.      *
  1187.      * 7)  Figure out the ownATs of object literals.
  1188.      *
  1189.      * 8)  Make sure that all manifest symbols have complete information.
  1190.      *
  1191.      * 9)  Type check.  Also, check the types that we
  1192.      * needed to do in order to do the invocations in the first place.
  1193.      */
  1194.  
  1195.     /*
  1196.      * Step 1.  Currently not done.
  1197.      */
  1198.     TRACE0(knowmanifest, 2, "!!NOT!! Doing step 1");
  1199.  
  1200.     /*
  1201.      * Step 2.
  1202.      */
  1203.     TRACE0(knowmanifest, 2, "Doing step 2 (set type variable info)");
  1204.     Set_For(anElement, p)
  1205.       anElement->b.knowmanifest.dependsOnTypeVariable = dependsOnTypeVariable;
  1206.       dt = anElement->b.knowmanifest.definingThing;
  1207.       switch (dt->tag) {
  1208.     case P_OBLIT:
  1209.       dt->b.oblit.f.typeDependsOnTypeVariable = typeDependsOnTypeVariable;
  1210.       break;
  1211.     default:
  1212.       break;
  1213.       }
  1214.     Set_Next
  1215.  
  1216.     /*
  1217.      * Step 3.
  1218.      */
  1219.     TRACE0(knowmanifest, 2, "Doing step 3 (propagating info through symbols)");
  1220.     doPropagate(p, FALSE);
  1221.  
  1222.     Set_For(anElement, p)
  1223.       dt = anElement->b.knowmanifest.definingThing;
  1224.       if (dt->tag == P_OBLIT) {
  1225.     NodePtr gsr;
  1226.     gsr = getGetSignatureResult(dt, TRUE);
  1227.     if (gsr != NN) {
  1228.       dt->b.oblit.instat = gsr;
  1229.     }
  1230.       }
  1231.     Set_Next
  1232.  
  1233.     /*
  1234.      * Step 4.
  1235.      */
  1236.     TRACE0(knowmanifest, 2, "Doing step 4 (finalizing invocations)");
  1237.     theNewManifests = NN;
  1238.     Set_For(anElement, p)
  1239.       dt = anElement->b.knowmanifest.definingThing;
  1240.       if (dt->tag == P_INVOC) {
  1241.     executeAnInvocation(anElement, IS_Step4, &theNewManifests);
  1242.       }
  1243.     Set_Next
  1244.     /*
  1245.      * We now have the stuff that we need to call doKnowManifests on
  1246.      */
  1247.     if (theNewManifests != NN) {
  1248.       TRACE0(knowmanifest, 1,
  1249.     "Calling doKnowManifests to figure the invoc results");
  1250.       doKnowManifests(theNewManifests);
  1251.       TRACE0(knowmanifest, 1,
  1252.     "DoKnowManifests finished figuring the invoc results");
  1253.     }
  1254.     if (!ATTOPLEVEL) {
  1255.       /*
  1256.        * If we are not at the top level, we need to merge our answers into
  1257.        * the thing at the next level down.  We also update the counters.
  1258.        */
  1259.       ManifestStack next = manStack->next;
  1260.       Set_Merge(manStack->manifestThings, next->manifestThings);
  1261.       return;
  1262.     }
  1263.  
  1264.     if (nInvocs > 0) {
  1265.       TRACE0(knowmanifest, 2, "Finalizing invocations added some new things");
  1266.     }
  1267. #ifdef XXXXXX
  1268.     Set_For(anElement, p)
  1269.       dt = anElement->b.knowmanifest.definingThing;
  1270.       if (dt->tag == P_OBLIT) {
  1271.     NodePtr gsr;
  1272.     if (!dt->b.oblit.f.isTypeVariable &&
  1273.         !dt->b.oblit.f.dependsOnTypeVariable) {
  1274.       gsr = getGetSignatureResult(dt, TRUE);
  1275.       if (gsr != NN) {
  1276.         dt->b.oblit.instat = gsr;
  1277.       }
  1278.     }
  1279.       }
  1280.     Set_Next
  1281. #endif
  1282.  
  1283.     /*
  1284.      * Step 5.  Traverse the manifest things, assigning OIDs to the atlits
  1285.      * and oblits.  Also, set the isManifest bit in atlits and oblits.
  1286.      * Always, isTypeVariable or dependsOnTypeVariable implies not
  1287.      * isManifest.  Also, set instat's of oblits.
  1288.      */
  1289.     TRACE0(knowmanifest, 2, "Doing step 5 (assigning OIDs)");
  1290.     Set_For(anElement, p)
  1291.       assignOIDs(anElement);
  1292.     Set_Next
  1293.  
  1294.     /*
  1295.      * Step 7.
  1296.      */
  1297.  
  1298.     TRACE0(knowmanifest, 2, "Doing step 7 (Figuring object types)");
  1299.     Set_For(anElement, p)
  1300.       an = anElement->b.knowmanifest.answer;
  1301.       assert(an != NULL);
  1302.       newFigureObjectTypes(an);
  1303.     Set_Next
  1304.  
  1305.     /*
  1306.      * Step 8.
  1307.      */
  1308.     TRACE0(knowmanifest, 2, "Doing step 8 (Finalizing AT and CT info in symbols)");
  1309.     Set_For(anElement, p)
  1310.       dt = anElement->b.knowmanifest.definingThing;
  1311.       fleshOutAllSymbols(dt);
  1312.     Set_Next
  1313.     
  1314. #ifdef XXXXXX
  1315.     TRACE0(knowmanifest, 2, "Doing step 9 (assigning Types)");
  1316.     Set_For(anElement, p)
  1317.       an = anElement->b.knowmanifest.answer;
  1318.       if (an->tag == P_ATLIT || an->tag == P_OBLIT) {
  1319.     newAssignTypes(an, 1);
  1320.       }
  1321.     Set_Next
  1322. #endif
  1323.  
  1324. #ifdef XXXXXX
  1325.     TRACE0(knowmanifest, 2, "Doing step 9 (checking Types)");
  1326.     Set_For(anElement, p)
  1327.       an = anElement->b.knowmanifest.answer;
  1328.       if (an->tag == P_ATLIT || an->tag == P_OBLIT) {
  1329.     typeCheck(an);
  1330.       }
  1331.     Set_Next
  1332. #endif
  1333.   }
  1334.  
  1335.   Set_For(anElement, p)
  1336.     assert(anElement->tag == P_KNOWMANIFEST);
  1337.     TRACE5(knowmanifest, 2, "Finalizing %s: %s %s%s0x%08x", 
  1338.       thingName(anElement),
  1339.       anElement->b.knowmanifest.isOK ? "is OK" : "is notOK",
  1340.       anElement->b.knowmanifest.isTypeVariable ? "iTV " : "" ,
  1341.       anElement->b.knowmanifest.dependsOnTypeVariable ? "dOTV " : "",
  1342.       anElement->b.knowmanifest.answer);
  1343.     dt = anElement->b.knowmanifest.definingThing;
  1344.     if (anElement->b.knowmanifest.isOK && dt->tag == P_INVOC) {
  1345.       Value value;
  1346.       assert(anElement->b.knowmanifest.answer != NN);
  1347.       updateInvocCache(dt, anElement->b.knowmanifest.answer);
  1348.       value.value = anElement->b.knowmanifest.answer;
  1349.       fleshOutValue(&value);
  1350.       Map_Insert(manifestMap, (int)dt, (int)value.ATinfo);
  1351.       Map_Insert(manifestMap, (int)dt+1, (int)value.CTinfo);
  1352.       Map_Insert(manifestMap, (int)dt+2, (int)value.value);
  1353.       dt->b.invoc.resultTypeOID = OIDOf(value.ATinfo);
  1354.     }
  1355.   Set_Next
  1356. }
  1357.  
  1358. static void MAN_SearchC(v)
  1359. register NodePtr v;
  1360. {
  1361.   register NodePtr x;
  1362.   NodePtr w;
  1363.   register Set SCComponent;
  1364.  
  1365.   v->b.knowmanifest.marked = TRUE;
  1366.   v->b.knowmanifest.number = count++;
  1367.   v->b.knowmanifest.lowLink = v->b.knowmanifest.number;
  1368.   Sequence_Add(&manStack->SCstack, v);
  1369.   v->b.knowmanifest.onStack = TRUE;
  1370.   Set_For(w, v->b.knowmanifest.dependsOn)
  1371.     if (! w->b.knowmanifest.marked) {
  1372.       MAN_SearchC(w);
  1373.       v->b.knowmanifest.lowLink = min(v->b.knowmanifest.lowLink, w->b.knowmanifest.lowLink);
  1374.     } else {
  1375.       if (w->b.knowmanifest.number < v->b.knowmanifest.number && w->b.knowmanifest.onStack) {
  1376.     v->b.knowmanifest.lowLink = min(w->b.knowmanifest.number, v->b.knowmanifest.lowLink);
  1377.       }
  1378.     }
  1379.   Sequence_Next
  1380.   if (v->b.knowmanifest.lowLink == v->b.knowmanifest.number) {
  1381.     SCComponent = Set_Create();
  1382.     TRACE0(knowmanifest, 1, "------");
  1383.     Sequence_ReverseFor(x, manStack->SCstack)
  1384.       manStack->SCstack->nChildren --;
  1385.       assert(x->b.knowmanifest.onStack);
  1386.       x->b.knowmanifest.onStack = FALSE;
  1387.       Set_Insert(SCComponent, (int)x);
  1388.       TRACE1(knowmanifest, 1, "struct %s", thingName(x));
  1389.       if (x == v) break;
  1390.     Sequence_Next
  1391.     manStack->manifestThings = SCComponent;
  1392.     propagateMANInfo();
  1393.     assert(SCComponent == manStack->manifestThings);
  1394.     Set_Destroy(manStack->manifestThings);
  1395.     manStack->manifestThings = NULL;
  1396.   }
  1397. }
  1398.  
  1399. NodePtr newExecuteAsAT(p)
  1400. register NodePtr p;
  1401. {
  1402.   NodePtr exp, type;
  1403.  
  1404.   exp = findManifestValue(p);
  1405.   if (exp == NULL) {
  1406.     ErrorMessage(p, "Abstract types must be manifest");
  1407.   } else {
  1408.     type = figureOutAT(exp);
  1409.     if (type == NULL) {
  1410.       ErrorMessage(p, "This expression is not a type");
  1411.     } else {
  1412.       assert(type->tag == P_ATLIT);
  1413.       return(type);
  1414.     }
  1415.   }
  1416.   return(refToBuiltin(B_INSTAT, ANYINDEX));
  1417. }
  1418.  
  1419. NodePtr tryToExecuteAsAT(p)
  1420. register NodePtr p;
  1421. {
  1422.   NodePtr type, value;
  1423.  
  1424.   value = findManifestValue(p);
  1425.   if (value == NULL) {
  1426.     return(NULL);
  1427.   } else {
  1428.     type = figureOutAT(value);
  1429.     if (type == NULL) {
  1430.       return(NULL);
  1431.     } else {
  1432.       assert(type->tag == P_ATLIT);
  1433.       return(type);
  1434.     }
  1435.   }
  1436. }
  1437.  
  1438. /*
  1439.  * newAssignTypes jobs is to traverse the tree in order, and assign types to
  1440.  * every identifier.  It uses newExecuteAsAT to return the type of an expression
  1441.  * in a type position.  It stops when it discovers an atlit or oblit that is
  1442.  * not manifest.
  1443.  */
  1444.  
  1445. static void doNewAssignTypes();
  1446.  
  1447. void newAssignTypes(p, dL)
  1448. register NodePtr p;
  1449. int dL;
  1450. {
  1451.   NodePtr thing, km;
  1452.   doNewAssignTypes(p, dL);
  1453.   if (p->tag == P_COMP) {
  1454.     Map_For(dependManifestMap, thing, km)
  1455.       if (km->b.knowmanifest.isOK) {
  1456.     doNewAssignTypes(km->b.knowmanifest.answer, dL);
  1457.       }
  1458.     Map_Next
  1459.   }
  1460. }
  1461.  
  1462. static void doNewAssignTypes(p, dL)
  1463. register NodePtr p;
  1464. int dL;
  1465. {
  1466.   register NodePtr q;
  1467.   register Symbol st;
  1468.   register NodePtr inhibitedChild = NULL;
  1469.   Boolean done = FALSE;
  1470.  
  1471.   if (ISTOKEN(p)) return;
  1472.   switch (p->tag) {
  1473.     case P_ATLIT:
  1474.       if (p->b.atlit.f.typesAreAssigned) return;
  1475.       if (dL <= 0) return;
  1476.       dL --;
  1477.       p->b.atlit.f.typesAreAssigned = TRUE;
  1478.       break;
  1479.     case P_OBLIT:
  1480.       if (p->b.oblit.f.typesAreAssigned) return;
  1481.       if (dL <= 0) return;
  1482.       dL --;
  1483.       p->b.oblit.f.typesAreAssigned = TRUE;
  1484.       if (p->b.oblit.f.isManifest) {
  1485.     assert(p->b.oblit.id != 0);
  1486.     assert(bflag || p->b.oblit.codeOID != 0);
  1487.       } else if (p->b.oblit.f.dependsOnTypeVariable) {
  1488.     assert(p->b.oblit.codeOID == 0);
  1489.       } else {
  1490.     /* just plain not manifest */
  1491.     assert(p->b.oblit.id == 0);
  1492.     if (p->b.oblit.codeOID == 0) {
  1493.       p->b.oblit.codeOID = AllocateOID();
  1494.       OTInsert(p, p->b.oblit.codeOID);
  1495.     }
  1496.       }
  1497.       if (p->b.oblit.name == NN) {
  1498.     assert(bflag || loadedDummyBuiltins);
  1499.       } else {
  1500.     assert(p->b.oblit.name->b.symdef.symbol->isSelf);
  1501.     p->b.oblit.name->b.symdef.symbol->value.value = p;
  1502.       }
  1503.       break;
  1504.     case P_CONSTDECL:
  1505.       q = p->b.constdecl.sym;
  1506.       assert(q->tag == P_SYMDEF);
  1507.       st = ST_Fetch(q->b.symdef.symbol);
  1508.       if (st->isManifest) {
  1509.     /*
  1510.      * Its type has already been assigned, but we need to assign types to
  1511.      * its value, which is not the same as its p->b.constdecl.value.
  1512.      */
  1513.     doNewAssignTypes(st->value.value, dL);
  1514.     done = TRUE;
  1515.       } else {
  1516.     if (p->b.constdecl.type != NN) {
  1517.       st->value.ATinfo = newExecuteAsAT(p->b.constdecl.type);
  1518.     } else {
  1519.       assert(st->value.value == NULL);
  1520.       /*
  1521.        * This is not a manifest constant. If we dont have a type field,
  1522.        * then we need to figure out the type of the value field.
  1523.        */
  1524.       st->value.ATinfo = evaluateForAT(p->b.constdecl.value, FALSE);
  1525.       if (st->value.ATinfo->tag == T_SEQUENCE) {
  1526.         assert(st->value.ATinfo->nChildren == 1);
  1527.         st->value.ATinfo = st->value.ATinfo->b.children[0];
  1528.       }
  1529.     }
  1530.     tryToSetCTInfo(st);
  1531.       }
  1532.       break;
  1533.     case P_PARAM:
  1534.       q = p->b.param.sym;
  1535.       assert(q->tag == P_SYMDEF);
  1536.       st = ST_Fetch(q->b.symdef.symbol);
  1537.       if (p->b.param.constraint != NN) {
  1538.     /*
  1539.      * This is a parameter whose type is abstract type and whose value
  1540.      * should be a type variable.
  1541.      */
  1542.     assert(symbolHasValue(st));
  1543.     assert(st->value.value != NULL);
  1544.     assert(st->value.value->tag == P_ATLIT);
  1545.     assert(st->value.value->b.atlit.f.isTypeVariable);
  1546.     st->value.ATinfo = refToBuiltin(B_INSTAT, SIGNATUREINDEX);
  1547.     st->value.CTinfo = refToBuiltin(B_INSTCT, SIGNATUREINDEX);
  1548.       } else {
  1549.     st->value.ATinfo = newExecuteAsAT(p->b.param.type);
  1550.     tryToSetCTInfo(st);
  1551.       }
  1552.       break;
  1553.     case P_VARDECL:
  1554.       q = p->b.vardecl.sym;
  1555.       assert(q->tag == P_SYMDEF);
  1556.       st = ST_Fetch(q->b.symdef.symbol);
  1557.       st->value.ATinfo = newExecuteAsAT(p->b.vardecl.type);
  1558.       tryToSetCTInfo(st);
  1559.       break;
  1560.     case P_WHEREWIDGIT:
  1561.       assert(p->b.wherewidgit.op == OIDENTITY);
  1562.       q = p->b.wherewidgit.sym;
  1563.       assert(q->tag == P_SYMDEF);
  1564.       st = ST_Fetch(q->b.symdef.symbol);
  1565.       if (!symbolHasValue(st)) {
  1566.     ErrorMessage(q,
  1567.       "Identifiers introduced in where clauses must have values");
  1568.       }
  1569.       break;
  1570.     case P_SETQ:
  1571.       st = p->b.setq.inner->b.symdef.symbol;
  1572.       if (symbolHasValue(st)) break;
  1573.       q = p->b.setq.outer;
  1574.       if (q->tag == P_SYMREF) {
  1575.     if (q->b.symref.symbol->value.ATinfo == NULL) {
  1576.       ErrorMessage(p, "Imported symbol %s has no type",
  1577.         ST_SymbolName(q->b.symref.symbol));
  1578.     }
  1579.     st->value = q->b.symref.symbol->value;
  1580.       } else {
  1581.     st->value.value = q;
  1582.     fleshOutValue(&st->value);
  1583.       }
  1584.       break;
  1585. #ifdef COPYSIGS
  1586.     case P_SYMDEF:
  1587.     case P_SYMREF:
  1588.       st = p->b.symdef.symbol;
  1589.       if (st->value.ATinfo == NN && symbolHasValue(st)) {
  1590.     doNewAssignTypes(st->value.value);
  1591.     fleshOutValue(&st->value);
  1592.       }
  1593.       break;
  1594. #endif
  1595.     default:
  1596.       break;
  1597.   }
  1598.   if (!done) Sequence_For(q, p)
  1599.     if (!ISTOKEN(q) && q != inhibitedChild) doNewAssignTypes(q, dL);
  1600.   Sequence_Next
  1601. }
  1602.  
  1603. void MAN_FindAll()
  1604. {
  1605.   NodePtr theThing, theStruct;
  1606.   Map_For(manStack->candidates, theThing, theStruct)
  1607.     if (! theStruct->b.knowmanifest.marked) MAN_SearchC(theStruct);
  1608.   Map_Next
  1609. }
  1610.  
  1611. void doKnowManifests(p)
  1612. NodePtr p;
  1613. {
  1614.   register ManifestStack m;
  1615.   m = (ManifestStack) calloc(1, sizeof(ManifestSE));
  1616.   m->candidates = Map_Create();
  1617.   m->SCstack = NULL;
  1618.   m->next = manStack;
  1619.   manStack = m;
  1620.   buildKnowManifestGraph(p, (Boolean)(bflag ? FALSE : (Zflag ? FALSE : TRUE)));
  1621.   displayKnowManifestGraph();
  1622.   MAN_FindAll();
  1623.   assert(m == manStack);
  1624.   manStack = m->next;
  1625.   Map_Destroy(m->candidates);
  1626.   free((char *)m);
  1627. }
  1628.  
  1629. void newEvaluateManifest(p, value)
  1630. NodePtr p;
  1631. Value *value;
  1632. {
  1633.   NodePtr answer;
  1634.   NodePtr thing, km;
  1635.   extern Boolean checkingTypes;
  1636.  
  1637.   answer = findManifestValue(p);
  1638.   if (answer == NN) {
  1639.     doKnowManifests(p);
  1640.     if (manStack == NULL) {
  1641.       /* we called doKnowManifest later */
  1642.       newAssignTypes(p);
  1643.       Map_For(dependManifestMap, thing, km)
  1644.     if (km->b.knowmanifest.isOK) {
  1645.       doNewAssignTypes(km->b.knowmanifest.answer, 999);
  1646.     }
  1647.       Map_Next
  1648.     }
  1649.     answer = findManifestValue(p);
  1650.   }
  1651.   if (answer == NN) {
  1652.     value->value = NN;
  1653.     value->ATinfo = NN;
  1654.     value->CTinfo = NN;
  1655.   } else {
  1656.     value->value = answer;
  1657.     fleshOutValue(value);
  1658.   }
  1659. }
  1660.