Polyinst.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2006, Johns Hopkins University.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or
00007  * without modification, are permitted provided that the following
00008  * conditions are met:
00009  *
00010  *   - Redistributions of source code must contain the above 
00011  *     copyright notice, this list of conditions, and the following
00012  *     disclaimer. 
00013  *
00014  *   - Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions, and the following
00016  *     disclaimer in the documentation and/or other materials 
00017  *     provided with the distribution.
00018  *
00019  *   - Neither the names of the copyright holders nor the names of any
00020  *     of any contributors may be used to endorse or promote products
00021  *     derived from this software without specific prior written
00022  *     permission. 
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00027  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  **************************************************************************/
00037 
00038 #include <stdint.h>
00039 #include <stdlib.h>
00040 #include <dirent.h>
00041 #include <fstream>
00042 #include <iostream>
00043 #include <string>
00044 #include <sstream>
00045 #include <gmp.h>
00046 #include <errno.h>
00047 #include <sstream>
00048 #include <assert.h>
00049 
00050 #include "Version.hxx"
00051 #include "UocInfo.hxx"
00052 #include "Options.hxx"
00053 #include "AST.hxx"
00054 #include "Type.hxx"
00055 #include "TypeInfer.hxx"
00056 #include "inter-pass.hxx"
00057 #include "Special.hxx"
00058 
00059 
00060 using namespace sherpa;
00061 using namespace std;
00062 
00063 //#define VERBOSE 200
00064 
00065 #ifdef VERBOSE
00066 #define STRICTLYEQUALS(x) strictlyCompatible(x, true) // verbose = true
00067 #define DEBUG if(1)
00068 #else
00069 #define STRICTLYEQUALS(x) strictlyCompatible(x)
00070 #define DEBUG if(0)
00071 #endif
00072 
00073 static bool 
00074 reRandT(std::ostream &errStream, 
00075         UocInfo *uoc, AST *ast)
00076 {
00077   stringstream ss;
00078   bool errFree = 
00079     uoc->RandTexpr(ss, ast, POLY_SYM_FLAGS, POLY_TYP_FLAGS,
00080                    "Polyinstantiation (s):\n");
00081   
00082   DEBUG if(!errFree)
00083     errStream << ss.str() << " while RandTing " << ast->asString() << std::endl;
00084   
00085   return errFree;
00086 }
00087 
00088 static bool 
00089 reRandT(std::ostream &errStream, UocInfo *uoc,
00090         unsigned long rFlags = POLY_SYM_FLAGS, 
00091         unsigned long tFlags = POLY_TYP_FLAGS,
00092         std::string mess = "FINAL Polyinstantiation (s):\n")
00093 {
00094   //   errStream << "AT " << mess << ": "
00095   //        << "Polyinstantiated AST is "
00096   //        << std::endl
00097   //        << uoc->ast->asString()
00098   //        << std::endl;
00099   
00100   bool errFree = 
00101     uoc->RandT(errStream, true, rFlags, tFlags, mess);
00102   if(!errFree)
00103     errStream << " while RandTing " 
00104               << uoc->ast->asString() 
00105               << std::endl;
00106 
00107   return errFree;
00108 }
00109 
00110 static bool
00111 removeAndReRandT(std::ostream &errStream, UocInfo *uoc, AST *ast)
00112 {
00113   bool removed = false;
00114   std::string nm = ast->getID()->s;
00115   for (size_t i = 0; i < uoc->env->bindings->size(); i++)
00116     if (uoc->env->bindings->elem(i)->nm == nm) {
00117       uoc->env->bindings->remove(i);
00118       removed = true;
00119       break;
00120     }
00121   
00122   assert(removed);
00123 
00124   removed = false;
00125   for (size_t i = 0; i < uoc->gamma->bindings->size(); i++)
00126     if (uoc->gamma->bindings->elem(i)->nm == nm) {
00127       uoc->gamma->bindings->remove(i);
00128       removed = true;
00129       break;
00130     }
00131   
00132   assert(removed);
00133   
00134   return reRandT(errStream, uoc, ast);
00135 }
00136 
00137 void
00138 sub(AST *ast, AST *tv, 
00139     AST *newAst, Type *typ,
00140     AST *parent, size_t chno)
00141 {
00142   if(ast->astType == at_ident) {
00143     assert(ast->children.size() == 0);
00144     if(ast->symbolDef == tv)
00145       parent->children[chno] = typ->asAST(ast->loc);
00146   }
00147   else {
00148     for(size_t c = 0; c < ast->children.size(); c++)
00149       sub(ast->children[c], tv, newAst->children[c], typ, newAst, c);
00150   }    
00151 }
00152 
00153 /* Namakaranam -- the ritual of giving a name */
00154 #define NAMKARAN(ast, name) do {                \
00155     ast->s = name;                              \
00156     ast->Flags2 |= IDENT_MANGLED;               \
00157   } while(0);
00158 
00159 static void
00160 substitute(AST *ast, AST *from, AST *to)
00161 {
00162   if(ast->astType == at_ident && ast->s == from->s) {
00163     ast->symbolDef = to;
00164     NAMKARAN(ast, to->s);
00165   }
00166   
00167   for(size_t c = 0; c < ast->children.size(); c++)
00168     substitute(ast->children[c], from, to);
00169 }
00170 
00171 
00172 static inline void
00173 add_todo(std::ostream &errStream, CVector<AST *> &todo,
00174          AST *copy)
00175 {
00176   // optimization for current name  
00177   DEBUG errStream << "Added to todo: " << copy->asString() << std::endl;
00178   todo.append(copy);
00179 }
00180 
00181 void
00182 add_relevant_items_todo(std::ostream &errStream, 
00183                         CVector<AST *> &todo, AST *ast)
00184 {
00185   switch(ast->astType) {
00186   case at_define: 
00187   case at_letbinding:
00188     {
00189       add_todo(errStream, todo, ast->children[1]);      
00190       if(ast->children[0]->children[1] != NULL)
00191         add_todo(errStream, todo, ast->children[0]->children[1]);      
00192       break;
00193     }
00194 
00195   case at_proclaim: 
00196     {
00197       add_todo(errStream, todo, ast->children[1]);      
00198       break;
00199     }
00200 
00201   case at_defstruct:
00202     {
00203       add_todo(errStream, todo, ast->children[4]);              
00204       break;
00205     }
00206 
00207   case at_defunion:
00208     {
00209       add_todo(errStream, todo, ast->children[4]);              
00210       break;
00211     }
00212 
00213   case at_declstruct:
00214   case at_declunion:
00215   case at_defexception:
00216     {
00217       break;
00218     }
00219 
00220   default:
00221     {
00222       assert(false);
00223       break;
00224     }
00225   }    
00226 }
00227 
00228 static inline void
00229 markReached(std::ostream &out, AST *ast)
00230 {
00231   ast->reached = true;
00232   //DEBUG out << "Marked " << ast->asString() << std::endl;
00233 }
00234 
00235 static inline void
00236 unmarkReached(std::ostream &out, AST *ast)
00237 {
00238   ast->reached = false;
00239   //DEBUG out << "    unMarked " << ast->asString() << std::endl;
00240 }
00241 
00242 
00243 std::string
00244 getNewName(AST *def, Type *typ)
00245 {
00246   stringstream ss;
00247   Type *uAdjTyp = typ;
00248   
00249   if(typ->isUcon() || typ->isUval())
00250     uAdjTyp = typ->getUnionType();
00251 
00252   assert(uAdjTyp);
00253   ss << def->s;
00254   ss << "#" << uAdjTyp->mangledString();
00255   return ss.str();      
00256 }
00257 
00258 
00259 void
00260 clearConstraints(AST *ast, AST *parent=NULL, size_t chno=0)
00261 {
00262   switch(ast->astType) {
00263   case at_constraints:
00264     ast->children.erase();
00265     break;
00266 
00267   case at_qualType:
00268     assert(parent != NULL);
00269     clearConstraints(ast->children[1], ast, 1);
00270     parent->children[chno] = ast->children[1];
00271     break;
00272     
00273   default:
00274     for(size_t c=0; c < ast->children.size(); c++)
00275       clearConstraints(ast->children[c], ast, c);
00276     break;
00277   }
00278 } 
00279 
00280 AST *
00281 Specialize(std::ostream &errStream,
00282            bool &errF,
00283            UocInfo *uoc,
00284            AST *def, 
00285            Type *typ,
00286            AST *mod, 
00287            CVector<AST *> &todo)  
00288 {
00289   if(def->symbolDef != NULL)
00290     def = NULL;
00291 
00292   assert(def->symbolDef == NULL);
00293   assert(def->astType == at_ident);
00294 
00295   typ = typ->getTheType(true, false);
00296   //typ->clearAllMaybes();
00297   
00298   if(!typ->isConcrete()) {
00299     errStream << " Specialize called with NON-concrete Type: "
00300               << typ->asString() << " For  AST " 
00301               << def->asString() << " located at " << def->loc << "."
00302               << std::endl;
00303   }    
00304   assert(typ->isConcrete());
00305   
00306   DEBUG errStream << "Special: " << def->s << ": " 
00307             << " WITH TYPE " << def->symType->asString()
00308             << " FOR " << typ->asString()
00309             << std::endl;
00310   
00311   if(def->isMethod()) {
00312     AST *typClass = def->defForm;
00313     AST *tcID = typClass->children[0];
00314     assert(tcID->astType == at_ident);
00315     //assert(typ->defAst != NULL);
00316     //assert(typ->myContainer != NULL);
00317     //assert(typ->myContainer == tcID);
00318 
00319     Typeclass *pred = tcID->scheme->type_instance_copy();
00320     size_t nthMethod = 0;
00321     bool found = false;
00322     for(size_t i = 0; i < pred->components.size(); i++) {
00323       Type *ithMethod = pred->components[i]->typ->getType();
00324       if(ithMethod->defAst == def) {
00325         nthMethod = i;
00326         found = true;
00327         break;
00328       }
00329     }
00330         
00331     if(!found) {
00332       errStream << def->loc << ": Internal compiler error. "
00333                 << "Method " << def->s 
00334                 << " could not be located within the type of "
00335                 << " its typeclass " << tcID->s 
00336                 << " by the polyinstantiator."
00337                 << std::endl;
00338       errF = false;
00339       return def;
00340     }
00341 
00342     // Unify the method with the necessary type
00343     // This should have enough information to 
00344     // uniquely identify the instance.
00345     BE_CHKERR(errF, pred->components[nthMethod]->typ->unifyWith(typ));    
00346     
00347     CVector<Instance *> *insts = 
00348       uoc->instEnv->getBinding(tcID->fqn.asString());    
00349     
00350     found = false;
00351     size_t nthInstance = 0;
00352     for(size_t j=0; j < insts->size(); j++) {
00353       Instance *currInst = (*insts)[j];
00354       if(currInst->satisfies(errStream, pred, uoc->instEnv)) {
00355         nthInstance = j;
00356         found = true;
00357         break;
00358       }
00359     }
00360     
00361     if(!found) {
00362       errStream << def->loc << ": Internal compiler error. "
00363                 << "No Instance found for " 
00364                 << pred->asString() << " while polyinstantiating "
00365                 << def->s << "."
00366                 << std::endl;
00367       errF = false;
00368       return def;
00369     }
00370 
00371     AST *instAST = (*insts)[nthInstance]->ast;
00372     AST *theMethod = instAST->children[1]->children[nthMethod];
00373 
00374     // If an immediate lambda was present, then InstLamHoist hoisted
00375     // it and left us with an ID wrapped by a THE.
00376     assert (theMethod->astType == at_ident || theMethod->astType == at_tqexpr);
00377     if (theMethod->astType == at_tqexpr)
00378       theMethod = theMethod->children[0];
00379 
00380     AST *theMethodDef = theMethod->symbolDef;
00381     // FIX: Shap inserted this to get a reliable stopping point for
00382     // debugging.
00383     assert(theMethodDef);
00384     markReached(errStream, theMethodDef->defForm); 
00385     AST *altDef = Specialize(errStream, errF, uoc, 
00386                              theMethodDef, typ, mod, todo);
00387     return altDef;
00388   }
00389   else if(def->isUnionLeg()) {
00390     assert(!(def->isDecl));
00391     Type *t = typ->getUnionType();
00392 
00393     AST *unin = def->defForm;
00394     AST *unionID = unin->children[0];
00395 
00396     //     cout << "** def = " << def->asString() << "(" <<
00397     //       def->symType->asString() << ")" << endl 
00398     //   << "** defForm = " << unin->asString() << "(" <<
00399     //       unin->symType->asString() << ")" << endl 
00400     //   << "** unionID = " << unionID->asString() << "(" <<
00401     //       unionID->symType->asString() << ")" << endl 
00402     //   << "** t = " << t->asString() << endl;    
00403     //     cout << "## Calling Specialize on " << unionID->asString() 
00404     //   << "(" << unionID->symType->asString() << ")"
00405     //   << " with " << t->asString() << endl;
00406 
00407     AST *newUnionID = Specialize(errStream, errF, uoc, unionID, 
00408                                  t, mod, todo);
00409     AST *newUnion = newUnionID->defForm;
00410     assert(newUnion->astType == at_defunion);
00411     //cout << "Obtained " << newUnion->asString() 
00412     //   << "(" << newUnion->symType->asString() << ")" << endl;
00413     AST *ctrs = unin->children[4]; // oldUnion
00414     for(size_t i = 0; i < ctrs->children.size(); i++) {
00415       AST *ctr = ctrs->children[i];
00416       if(ctr->children[0] == def)
00417         return (newUnion->children[4]->children[i]->children[0]);
00418     }
00419     // Not reached.
00420     assert(false);
00421   }
00422 
00423   /* Skipped in new Poly */
00424   if(!def->isDecl) {
00425     if(def->symType->STRICTLYEQUALS(typ)) {
00426       add_relevant_items_todo(errStream, todo, def->defForm);
00427       return def;
00428     }
00429   }
00430   
00431   if(def->special != NULL) {
00432     for(size_t i=0; i<def->special->size(); i++) {
00433       spStruct *sp = (*def->special)[i];
00434       DEBUG errStream << "Comparing existing "
00435                       << sp->typ->asString() << " for " 
00436                       << typ->asString()
00437                       << std::endl;
00438       if(sp->typ->STRICTLYEQUALS(typ)) {
00439         
00440         DEBUG errStream << "FOUND, returning "
00441                         << sp->ast->getID()->asString()
00442                         << std::endl;
00443         return sp->ast->getID();
00444       }
00445     }
00446   }
00447   else {
00448     //     errStream << "No Match found" << std::endl;
00449     def->special = new CVector <spStruct *>;    
00450   }
00451   
00452   AST *defn = def->defForm;
00453   AST *copy = defn->getDCopy();
00454   // Mark up the defForms in the copy
00455   if(defn->astType == at_letbinding) {
00456     copy->Flags2 &= ~LB_MUST_GO;
00457 
00458     AST *lbs = defn->defForm;
00459     AST *let = lbs->defForm;
00460     AST *top = let->defForm;
00461     uoc->markDefForms(copy, lbs, top); 
00462   }
00463   else if(defn->astType == at_letbindings) {
00464     AST *let = defn->defForm;
00465     AST *top = let->defForm;
00466     uoc->markDefForms(copy, let, top);
00467   }
00468   else 
00469     uoc->markDefForms(copy);
00470 
00471   assert(copy->polyinst == false);
00472   clearConstraints(copy);
00473   AST *id = copy->getID();
00474   //id->defForm = copy;
00475   
00476   def->special->append(new spStruct(copy, typ));
00477   if(def->isDecl && (def->defn != NULL)) {
00478     DEBUG std::cout << "For declaration " << def->s 
00479                     << " Calling Specialize on definition "
00480                     << def->defn->defForm->asString()
00481                     << std::endl;
00482 
00483     AST *altDef = Specialize(errStream, errF, uoc, 
00484                              def->defn, typ, mod, todo);
00485     
00486     NAMKARAN(id, altDef->s);
00487     id->defn = altDef;
00488   }
00489   else {
00490     NAMKARAN(id, getNewName(id, typ));
00491   }
00492   
00493   switch(copy->astType) {
00494   case at_letbinding:
00495     {
00496       AST *ip = copy->children[0];
00497       assert(ip->astType == at_identPattern);
00498       AST *t = typ->asAST(copy->loc);
00499       if(ip->children.size() > 1) {
00500         ip->children[1] = t;    
00501       }
00502       else {
00503         ip->children.append(t); 
00504       }
00505       
00506       substitute(copy, defn->getID(), copy->getID()); 
00507       add_relevant_items_todo(errStream, todo, copy);
00508       
00509       DEBUG errStream << "Specialized\n\t" << defn->asString() 
00510                       << "   to \n\t"
00511                       << copy->asString() << std::endl;
00512 
00513       AST *letbinds = defn->defForm;
00514       AST *let = letbinds->defForm;
00515       AST *definition = let->defForm;
00516 
00517       letbinds->children.append(copy);
00518       // No, not
00519       //BE_CHKERR(errF, removeAndReRandT(errStream, uoc, definition));
00520       // There might be errors at this stage because the entire
00521       //expression is not changed in full.
00522       removeAndReRandT(errStream, uoc, definition);
00523       return id;
00524     }
00525 
00526   case at_define: 
00527     {
00528       AST *ip = copy->children[0];
00529       assert(ip->astType == at_identPattern);
00530       AST *t = typ->asAST(copy->loc);
00531       if(ip->children.size() > 1) {
00532         ip->children[1] = t;    
00533         // This should be sufficient as the type obtained from the
00534         // type record is at least, or more precise than what the user
00535         // wrote. I was previously doing:
00536         //      AST *the = new AST(at_tqexpr, copy->loc, 
00537         //                         copy->children[1], t);
00538         //      copy->children[1] = the;
00539       }
00540       else {
00541         ip->children.append(t); 
00542       }
00543 
00544       break;
00545     }
00546 
00547   case at_proclaim: 
00548     {
00549       copy->children[1] = typ->asAST(copy->loc);
00550       break;
00551     }
00552 
00553   case at_declstruct:
00554     { 
00555       assert(typ->kind == ty_structv  ||
00556              typ->kind == ty_structr);
00557       
00558       AST *tvlist = copy->children[1];
00559       tvlist->children.erase();
00560       break;          
00561     }
00562      
00563   case at_defstruct:
00564     {
00565       assert(typ->kind == ty_structv ||
00566              typ->kind == ty_structr);
00567       
00568 
00569       AST *tvlist = copy->children[1];
00570       AST *fields = copy->children[4];
00571       AST *oldtvlist = defn->children[1];
00572       AST *oldfields = defn->children[4];
00573 
00574       assert(typ->typeArgs.size() == tvlist->children.size());
00575       assert(fields->children.size() != 0); // This is a definition
00576 
00577       for(size_t i=0; i < oldtvlist->children.size(); i++) {
00578         AST *oldtv = oldtvlist->children[i];
00579         for(size_t j=0; j < oldfields->children.size(); j++) {
00580           AST *oldfield = oldfields->children[j];
00581           AST *field = fields->children[j];
00582           if(field->astType == at_fill)
00583             continue;
00584           sub(oldfield->children[1], oldtv, field->children[1], 
00585               typ->typeArgs[i], field, 1);
00586         }
00587       }
00588 
00589       tvlist->children.erase();
00590       break;
00591     }
00592 
00593   case at_declunion:
00594     {
00595       assert(typ->kind == ty_unionv ||
00596              typ->kind == ty_unionr);
00597 
00598       AST *tvlist = copy->children[1];
00599       tvlist->children.erase();
00600       break;    
00601     }
00602     
00603   case at_defunion:
00604     {
00605       assert(typ->kind == ty_unionv ||
00606              typ->kind == ty_unionr || 
00607              typ->kind == ty_uconv  || 
00608              typ->kind == ty_uconr  ||
00609              typ->kind == ty_uvalv  ||
00610              typ->kind == ty_uvalr);
00611       
00612       AST *tvlist = copy->children[1];
00613       AST *ctrs = copy->children[4];
00614       AST *oldtvlist = defn->children[1];
00615       AST *oldctrs = defn->children[4];
00616       
00617       assert(typ->typeArgs.size() == tvlist->children.size());
00618       assert(ctrs->children.size() != 0); // This is a definition
00619       
00620       for(size_t i=0; i < oldtvlist->children.size(); i++) {
00621         AST *oldtv = oldtvlist->children[i];
00622         Type *newArg = typ->typeArgs[i];
00623         for(size_t j=0; j < oldctrs->children.size(); j++) {
00624           AST *oldctr = oldctrs->children[j];
00625           AST *ctr = ctrs->children[j];
00626           for(size_t k=0; k < oldctr->children.size(); k++) {     
00627             AST *field = oldctr->children[k];
00628             if(field->astType == at_fill)
00629               continue;     
00630             
00631             sub(oldctr->children[k], oldtv, ctr->children[k], 
00632                 newArg, ctr, k);
00633           }
00634         }
00635       }
00636       
00637       for(size_t i = 0; i < ctrs->children.size(); i++) {
00638         AST *ctr = ctrs->children[i];
00639         AST *ctrID = ctr->children[0];
00640         
00641         ctrID->defForm = copy;
00642         NAMKARAN(ctrID, getNewName(ctrID, typ));
00643       }
00644       
00645       tvlist->children.erase();
00646       break;
00647     }
00648     
00649   case at_defexception:
00650     {
00651       assert(false);
00652       return NULL;
00653     }
00654   default:
00655     {
00656       assert(false);
00657       return NULL;
00658     }
00659   }
00660 
00661   add_relevant_items_todo(errStream, todo, copy);
00662   
00663   DEBUG errStream << "Specialized\n\t" << defn->asString() 
00664                   << "   to \n\t"
00665                   << copy->asString() << std::endl;
00666   
00667   BE_CHKERR(errF, reRandT(errStream, uoc, copy));
00668   //reRandT(errStream, uoc, copy);
00669 
00670 
00671   if(!copy->isDecl)
00672     if(def->decl != NULL)
00673       Specialize(errStream, errF, uoc, def->decl, typ,
00674                  mod, todo);
00675 
00676   return id;
00677 }
00678 
00679 // Polymorphic local procedure bindings must be dropped if not
00680 // used/polyinstantiated. This is because they may polymorphically
00681 // invoke type-class methods, which must not survive after this pass.
00682 static bool 
00683 lbMustNotSurvive(const AST *lb)
00684 {
00685   assert(lb->astType == at_letbinding);
00686   AST *lhs = lb->children[0]->children[0];
00687 
00688   // This check is subtle. No expression that can cause a side-effect
00689   // must ever be dropped. I initially thought that the check must be
00690   // made as to whether the AST is a lambda (possibly wrapped in any
00691   // number of type qualifications, but this is not enough because
00692   // (define (a253 x) (+ x 1))
00693   // ... (let ((b253 a253)) ... )
00694   // will still preserve the erroneous case. Thus this check is
00695   // correct. 
00696   // Since no non-value can be polymorphic, this check will ensure
00697   // that we do not drop any state change.
00698   return (lhs->symType->isFnxn() && !lhs->symType->isConcrete());
00699 }
00700 
00701 static void
00702 setupTypApp(AST *ast) 
00703 {  
00704   AST *copy = ast->getDCopy();
00705   AST *typ = ast->symType->asAST(ast->loc);
00706   AST *the = new AST(at_tqexpr, ast->loc, copy, typ);
00707   ast->set(the);
00708   ast->polyinst = true;
00709 }
00710 
00711 // Polymorphic types to concrete types.
00712 bool
00713 polyinst(std::ostream &errStream,
00714          UocInfo *uoc,
00715          AST *ast, AST *mod, 
00716          CVector<AST *> &todo)
00717 {
00718   bool errFree = true; bool errF= true;
00719   DEBUG errStream << "polyinst: " << ast->loc << ": "
00720                   << ast->atKwd() << ": "
00721                   << ast->asString()
00722                   << std::endl;
00723   
00724   if(ast->polyinst) {
00725     DEBUG errStream << "Already processed" << endl;
00726     return true;
00727   }
00728   ast->polyinst = true;
00729 
00730   switch(ast->astType) {
00731   case at_start:
00732   case at_module:
00733   case at_interface:
00734     {
00735       assert(false);
00736       break;
00737     }
00738 
00739   case at_typeapp:
00740     {
00741       for (size_t c = 0; c < ast->children.size(); c++) {
00742         BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[c], 
00743                                  mod, todo));
00744       }
00745 
00746       ast->set(ast->children[0]);
00747       ast->polyinst = true;      
00748 
00749       break;
00750     }
00751     
00752   case at_field:
00753     {
00754       BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[1], 
00755                                mod, todo));
00756       break;
00757     }
00758 
00759   case at_select:
00760     {
00761       BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[0], 
00762                                mod, todo));
00763 
00764       if(ast->Flags2 & SEL_FROM_UN_VAL || ast->Flags2 & SEL_FROM_UN_TYPE)
00765         BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[1], 
00766                                  mod, todo));
00767       break;
00768     }
00769 
00770   case at_declare:
00771     {
00772       if(ast->children.size() > 1)
00773         BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[1], 
00774                                  mod, todo));
00775       
00776       break;
00777     }
00778 
00779   case at_bitfield:
00780     {
00781       BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[0], 
00782                                mod, todo));
00783       
00784       break;
00785     }
00786     
00787   case at_arrayType:
00788     {
00789       BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[0], 
00790                                   mod, todo));
00791       break;
00792     }
00793     
00794   case at_tqexpr:
00795     {     
00796       BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[0], 
00797                                   mod, todo));
00798       BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[1], 
00799                                   mod, todo));
00800 
00801       if(ast->children[0]->astType == at_tqexpr) {      
00802         assert(ast->children[0]->children[0]->astType == at_intLiteral ||
00803                ast->children[0]->children[0]->astType == at_floatLiteral);
00804 
00805         /* We fixed intlit's / floatlit's type twice */
00806         ast->children[1] = ast->children[0]->children[1];
00807         ast->children[0] = ast->children[0]->children[0];
00808       }
00809       break;
00810     }
00811 
00812   case at_floatLiteral:
00813   case at_intLiteral:
00814     {
00815       if(ast->symType->isConcrete())
00816         setupTypApp(ast);
00817       break;    
00818     }
00819 
00820   case at_let:
00821   case at_letrec:
00822   case at_letStar:
00823     {
00824       // First process the final expression.
00825       BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[1], 
00826                                   mod, todo));
00827       
00828       // Then process each binding.
00829       BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[0], 
00830                                   mod, todo));
00831       break;
00832     }
00833 
00834   case at_letbinding:
00835     {
00836       if(!lbMustNotSurvive(ast)) {
00837         DEBUG errStream << "LB with type " 
00838                         << ast->children[1]->symType->asString()
00839                         << " must survive." << std::endl;
00840         BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[0], 
00841                                     mod, todo));
00842         BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[1], 
00843                                     mod, todo));
00844       }
00845       else {
00846         ast->Flags2 |= LB_MUST_GO;
00847         DEBUG errStream << "Skipping LB with type " 
00848                         << ast->children[1]->symType->asString() << std::endl;
00849       }
00850       break;
00851     }
00852 
00853   case at_ident:
00854     {
00855       if(ast->symbolDef == NULL) {
00856         /* DEFINING OCCURRENCE */
00857         DEBUG errStream << "[Defining Occurence]" << std::endl;
00858         AST *defn = ast->defForm;
00859         if(defn != NULL)
00860           add_relevant_items_todo(errStream, todo, defn); 
00861         
00862         // defn will not be NULL for top level definitions
00863         // and let-bindings. It will be NULL for local definitions
00864         // and tvar definitions.
00865         // For example:
00866         // (define R (case nil (nil (the int32 10)) 
00867         //          ((cons a b) 20) (otherwise 30)))
00868         // for `a' and `b'              
00869       }
00870       else {
00871         /* USE OCCURENCE */
00872         AST *def = ast->symbolDef;
00873         DEBUG errStream << "[Use Occurence]" << std::endl;
00874 
00875         if(def->isGlobal()) {
00876           // All globals MUST have defForm set
00877           markReached(errStream, def->defForm);
00878           if(def->defn != NULL)
00879             markReached(errStream, def->defn->defForm);
00880         }         
00881 
00882         if(!ast->symType->STRICTLYEQUALS(def->symType)) {
00883           
00884           if(!ast->symType->isConcrete())
00885             ast->symType->SetTvarsToUnit();
00886         
00887           AST *altDef = Specialize(errStream, errF, uoc, def, 
00888                                    ast->symType, mod, todo);
00889           BE_CHKERR(errFree, errF);
00890          
00891           NAMKARAN(ast, altDef->s);
00892           ast->symbolDef = altDef;            
00893         }
00894         else {
00895           AST *defn = ((def->isUnionLeg()) ? 
00896                        (def->defForm->children[0]) :
00897                        (def));
00898           
00899           if(defn->defForm)
00900             add_todo(errStream, todo, defn->defForm);
00901           
00902           if((defn->isDecl) && (defn->defn != NULL))
00903             add_todo(errStream, todo, defn->defn->defForm);
00904         }
00905       }
00906       break;
00907     }
00908       
00909   case at_deftypeclass:
00910   case at_definstance:
00911     break;
00912 
00913   default:
00914     {
00915       for (size_t c = 0; c < ast->children.size(); c++) {
00916         BE_CHKERR(errFree, polyinst(errStream, uoc, ast->children[c], 
00917                                  mod, todo));
00918       } 
00919       break;
00920     }
00921   }
00922   
00923   return errFree;
00924 }
00925 
00926 void
00927 getLetintoLetStream(std::ostream &errStream, AST *ast)
00928 {
00929   switch(ast->astType) {
00930   case at_letbindings:
00931     {
00932       AST *lbs = ast;
00933       for(size_t c = 0; c < lbs->children.size(); c++) {
00934         AST *lb = lbs->children[c];     
00935         AST *id = lb->getID();
00936         if(id->special != NULL && id->special->size() > 0) {
00937           lbs->children.remove(c);
00938           c--;
00939         }
00940         else if(lb->Flags2 & LB_MUST_GO) {
00941           lbs->children.remove(c);
00942           c--;
00943         }
00944         else {
00945           getLetintoLetStream(errStream, lb->children[1]);
00946         }
00947       }
00948       break;
00949     }
00950 
00951   case at_let:
00952   case at_letrec:
00953     {
00954       AST *lbs = ast->children[0];
00955       AST *expr = ast->children[1];
00956       getLetintoLetStream(errStream, lbs);
00957       getLetintoLetStream(errStream, expr);
00958       if(lbs->children.size() == 0)
00959         ast->set(expr);
00960       break;
00961     }
00962       
00963   case at_letbinding:
00964     {
00965       assert(false);
00966       break;
00967     }
00968     
00969   default:
00970     {
00971       for(size_t c = 0; c < ast->children.size(); c++)
00972         getLetintoLetStream(errStream, ast->children[c]);
00973       break;
00974     }
00975   }
00976 }
00977 
00978 void
00979 getValuesIntoMainStream(std::ostream &errStream, AST *mod) 
00980 {
00981   for(size_t c=0; c < mod->children.size(); c++) {
00982     AST *def = mod->children[c];
00983     switch(def->astType) {
00984     case at_defstruct:
00985     case at_defunion:
00986     case at_declstruct:
00987     case at_declunion:
00988     case at_defexception:
00989     case at_deftypeclass:
00990     case at_definstance:
00991       break;
00992       
00993     case at_define:
00994     case at_proclaim:
00995       {
00996         AST *ast = def->getID();
00997         if(ast->special != NULL && ast->special->size() > 0) {
00998           unmarkReached(errStream, def);
00999           
01000           for(size_t i=0; i < ast->special->size(); i++) {
01001             spStruct *sp = (*ast->special)[i];
01002             AST *altDef = sp->ast;
01003             markReached(errStream, altDef);
01004             
01005             if(!sp->lifted) {
01006               sp->lifted = true;
01007               if(c == mod->children.size() - 1)
01008                 mod->children.append(altDef);
01009               else
01010                 mod->children.insert(c+1, altDef);
01011               c++;
01012               
01013               if(altDef->astType == at_define)
01014                 getLetintoLetStream(errStream, altDef->children[1]);
01015             } 
01016           }
01017         }
01018         else {
01019           if((def->astType == at_proclaim) &&
01020              (ast->Flags & DEF_IS_EXTERNAL) &&
01021              (!ast->symType->isConcrete()))
01022             unmarkReached(errStream, def);
01023         }
01024         
01025         if(def->astType == at_define)
01026           getLetintoLetStream(errStream, def->children[1]);
01027         break;
01028       }
01029 
01030     default:
01031       assert(false);
01032       break;
01033     }
01034   }
01035 }
01036 
01037 void
01038 getTypesIntoMainStream(std::ostream &errStream, AST *mod) 
01039 {
01040   size_t n = mod->children.size();
01041   for(size_t c=0; c < n; c++) {
01042     AST *def = mod->children[c];
01043     switch(def->astType) {
01044     case at_defstruct:
01045     case at_defunion:
01046     case at_declstruct:
01047     case at_declunion:
01048     case at_defexception:
01049       {
01050         AST *ast = def->getID();
01051         if(ast->special != NULL && ast->special->size() > 0) {
01052           unmarkReached(errStream, def);
01053 
01054           for(size_t i=0; i < ast->special->size(); i++) {
01055             spStruct *sp = (*ast->special)[i];
01056             markReached(errStream, sp->ast);
01057             
01058             if(!sp->lifted) {
01059               sp->lifted = true;
01060               mod->children.append(sp->ast);
01061             } 
01062           }
01063         }
01064         break;
01065       }
01066 
01067     case at_define:
01068     case at_proclaim:
01069     case at_deftypeclass:
01070     case at_definstance:
01071       break;      
01072 
01073     default:
01074       assert(false);
01075       break;
01076     }
01077   }
01078 }
01079  
01080 void 
01081 getIntoMainStream(std::ostream &errStream, AST *mod)
01082 {
01083   getValuesIntoMainStream(errStream, mod);
01084   getTypesIntoMainStream(errStream, mod);
01085 }
01086  
01087 void
01088 removeUnreached(AST *mod) 
01089 {
01090   size_t c = (mod->astType == at_interface)?1:0; 
01091   for(; c < mod->children.size(); c++) {
01092     AST *def = mod->children[c];
01093     switch(def->astType) {
01094     case at_deftypeclass:
01095     case at_definstance:
01096       {
01097         mod->children.remove(c); 
01098         c--;    
01099         break;
01100       }
01101 
01102     default:
01103       {
01104         if(!def->reached) {
01105           mod->children.remove(c); 
01106           c--;
01107         }
01108       }      
01109     }
01110   }
01111 }
01112 
01113 void addType(AST *def, AST *mod, CVector<AST *> &deps);
01114 
01115 void
01116 addCompType(AST *ast, AST *mod, CVector<AST *> &deps)
01117 {
01118   switch(ast->astType) {
01119   case at_ident:
01120     {
01121       AST *def = ast->symbolDef;
01122       if((def != NULL) && def->defForm) 
01123         addType(def->defForm, mod, deps);
01124       break;
01125     }
01126   default:
01127     {
01128       for(size_t c=0; c < ast->children.size(); c++)
01129         addCompType(ast->children[c], mod, deps);
01130     }
01131   }
01132 }
01133 
01134 void
01135 addType(AST *def, AST *mod, CVector<AST *> &deps)
01136 {
01137   if(!mod->children.contains(def) && !deps.contains(def)) {
01138     size_t n = deps.size();
01139     deps.append(def);
01140     switch(def->astType) {
01141     case at_defstruct:
01142     case at_defunion:
01143       addCompType(def->children[4], mod, deps);
01144       break;
01145         
01146     case at_defexception:
01147       for(size_t c = 1; c < def->children.size(); c++)
01148         addCompType(def->children[c], mod, deps);
01149       break;
01150 
01151     default:
01152       assert(false);
01153       break;
01154     }
01155     mod->children.append(def);
01156     assert(deps.size() == n + 1);
01157     deps.remove(n);
01158   }  
01159 }
01160 
01161 void
01162 moveTypesUp(AST *start)
01163 {
01164   AST *mod = start->children[0];
01165   AST *newMod = new AST(at_module, mod->loc);
01166 
01167   for(size_t c = 0; c < mod->children.size(); c++) {
01168     AST *def = mod->children[c];
01169     switch(def->astType) {
01170     case at_declstruct:
01171     case at_declunion:
01172       newMod->children.append(def);
01173       break;
01174       
01175     case at_define:
01176     case at_proclaim:
01177     case at_defstruct:
01178     case at_defunion:
01179     case at_defexception:      
01180       break;
01181       
01182     default:
01183       assert(false);
01184     }
01185   }
01186 
01187   // Types need to be added by honouring dependencies.
01188   // The original program order is NOT enough
01189   // because of type specializations.
01190   CVector<AST *> dep;
01191   for(size_t c = 0; c < mod->children.size(); c++) {
01192     AST *def = mod->children[c];
01193     switch(def->astType) {
01194     case at_defstruct:
01195     case at_defunion:
01196     case at_defexception:
01197       {
01198         assert(dep.size() == 0);
01199         addType(def, newMod, dep);
01200         break;
01201       }
01202       
01203     case at_declstruct:
01204     case at_declunion:
01205     case at_define:
01206     case at_proclaim:
01207       {
01208         break;
01209       }
01210 
01211     default:
01212       {
01213         assert(false);
01214       }
01215     }
01216   }
01217 
01218   for(size_t c = 0; c < mod->children.size(); c++) {
01219     AST *def = mod->children[c];
01220     switch(def->astType) {      
01221     case at_define:
01222     case at_proclaim:
01223       newMod->children.append(def);
01224       break;
01225     case at_defstruct:
01226     case at_defunion:
01227     case at_declstruct:
01228     case at_declunion:
01229     case at_defexception:
01230       break;
01231       
01232     default:
01233       assert(false);    
01234     }
01235   }
01236 
01237   start->children[0] = newMod;
01238 }
01239 
01240 bool 
01241 checkInfTypedValues(AST *ast, std::ostream &errStream)
01242 {
01243   bool errFree = true;
01244 
01245   
01246   switch(ast->astType) {    
01247 
01248   case at_ident:
01249     {
01250       // To the best of my knowledge, it is impossible to construct an 
01251       // infinite type without using an identifier. So, this case is
01252       // sufficiently checked within the ident case. 
01253       // Of course, I can write this check outside the case, but I am
01254       // writing it here because, if there is a counter example, I
01255       // would like to know.
01256 
01257       if(ast->symType &&
01258          ast->symType->isOfInfiniteType()) {    
01259         errStream << ast->loc << ": " 
01260                   << "This expression has an infinite Type: "
01261                   << ast->symType->asString()
01262                   << ", and cannot be instantiated."
01263                   << std::endl;
01264         errFree = false;
01265       }
01266 
01267       break;
01268     }
01269 
01270   case at_field:                               
01271     {
01272       BE_CHKERR(errFree, checkInfTypedValues(ast->children[1], 
01273                                           errStream));
01274       break;
01275     }
01276 
01277   case at_select:
01278     {
01279       BE_CHKERR(errFree, checkInfTypedValues(ast->children[0],
01280                                           errStream));
01281       break;
01282     }
01283 
01284   case at_define:
01285   case at_proclaim:
01286     {
01287       for(size_t c = 0; errFree && (c < ast->children.size()); c++)
01288         BE_CHKERR(errFree, checkInfTypedValues(ast->children[c],
01289                                             errStream));
01290       break;
01291     }
01292     
01293   case at_defstruct:
01294   case at_defunion:
01295   case at_declstruct:
01296   case at_declunion:
01297   case at_defexception:
01298     {
01299       break;
01300     }
01301 
01302   default:
01303     {
01304       for(size_t c = 0; errFree && (c < ast->children.size()); c++)
01305         BE_CHKERR(errFree, checkInfTypedValues(ast->children[c], 
01306                                             errStream));
01307       break;
01308     }    
01309   }
01310 
01311   return errFree;
01312 }
01313 
01314 void
01315 mangleIDs(AST *ast)
01316 {
01317   switch(ast->astType) {
01318   case at_ident:
01319     {
01320       ast->s = ast->mangledString();
01321       break;
01322     }
01323     
01324   case at_declares:
01325     break;
01326     
01327   default:
01328     {
01329       for(size_t c = 0; c < ast->children.size(); c++)
01330         mangleIDs(ast->children[c]);
01331       break;
01332     }    
01333   }
01334 }
01335  
01336 static void
01337 proclaimsAboveDefs(AST *ast)
01338 {
01339   // Temporary fix so that I can run test cases, introduced
01340   // because of the new proclaimation rule. 
01341 
01342   // This is a really bad implementation, fix is comming ...
01343      
01344   AST *mod = ast->children[0];
01345   AST *newMod = new AST(at_module, mod->loc);
01346 
01347   for(size_t c=0; c < mod->children.size(); c++) {
01348     AST *ast = mod->children[c];
01349     switch(ast->astType) {
01350     case at_define:
01351     case at_defexception:
01352     case at_defstruct:
01353     case at_defunion:
01354       {
01355         for(size_t j=c+1; j < mod->children.size(); j++) {
01356           AST *thisDef = mod->children[j];
01357           if(ast->getID()->s == thisDef->getID()->s) {
01358             newMod->children.append(thisDef);
01359             mod->children.remove(j); j--;
01360           }
01361         }
01362             
01363         newMod->children.append(ast);
01364         break;
01365       }
01366 
01367     case at_proclaim:
01368     case at_declstruct:
01369     case at_declunion:      
01370       {
01371         newMod->children.append(ast);
01372         break;
01373       }
01374       
01375     default:
01376       {
01377         assert(false);
01378         break;
01379       }
01380     }
01381   }
01382 }
01383 
01384 bool
01385 UocInfo::be_polyinstantiate(std::ostream &errStream, 
01386                             bool init, unsigned long flags)
01387 {
01388   bool errFree = true;
01389 
01390   UocInfo *uoc = this;
01391   assert(uoc != NULL);
01392   AST *mod = uoc->ast->children[0]; 
01393   CVector<AST *> todo;
01394   
01395 #if 0
01396   AST *main = lookForMain(uoc);
01397   if(main == NULL) 
01398     assert(Options::backEnd->flags & BK_HDR_MODE);
01399   
01400   if(main != NULL) {
01401     main = main->defForm;
01402     assert(main != NULL);
01403     markReached(errStream, main);
01404     add_todo(errStream, todo, main);
01405   }
01406 #else
01407   for (size_t ep = 0; ep < Options::entryPts->size(); ep++) {
01408     std::string& epName = (*Options::entryPts)[ep];
01409 
01410     AST *mod = uoc->ast->children[0];
01411     for(size_t c = 0; c < mod->children.size(); c++) {
01412       if(mod->children[c]->astType != at_define)
01413         continue;
01414 
01415       AST *def = mod->children[c]->getID();
01416       if (def->fqn.asString() == epName) {
01417         def = def->defForm;
01418         assert(def != NULL);
01419 
01420         if (epName == "bitc.main.main")
01421           UocInfo::mainIsDefined = true;
01422 
01423         markReached(errStream, def);
01424         add_todo(errStream, todo, def);
01425       }
01426     }
01427   }
01428 #endif
01429   
01430   BE_CHKERR(errFree, checkInfTypedValues(mod, errStream));
01431   if(!errFree)
01432     return false;
01433     
01434   mangleIDs(mod);
01435   SpecialNames::spNames.fixUpSpNames(uoc);
01436   BE_CHKERR(errFree, reRandT(errStream, uoc, 
01437                           OP_SYM_FLAGS, OP_TYP_FLAGS, 
01438                           "Post mangle"));
01439 
01440   /* Top-level side-effecting expressions must not be dropped. There
01441      is talk about dis-allowing such expressions, and an analysis pass
01442      must be performed to check all such cases. For now, we must keep
01443      everything that is concrete as roots
01444 
01445      This will add some things like main to the todo list twice, 
01446      but ... */
01447   bool INCLUDE_ALL_CONCRETE_VALUES = true;
01448 
01449   for(size_t c = 0; c < mod->children.size(); c++) {
01450     AST *ast = mod->children[c];
01451     switch(ast->astType) {
01452     case at_proclaim:
01453       if((ast->getID()->Flags & DEF_IS_EXTERNAL) || 
01454          (INCLUDE_ALL_CONCRETE_VALUES &&
01455           ast->getID()->symType->isConcrete())) {
01456         markReached(errStream, ast);
01457         add_todo(errStream, todo, ast);
01458       }      
01459       break;
01460 
01461     case at_define:      
01462       {
01463         if(INCLUDE_ALL_CONCRETE_VALUES &&
01464            ast->getID()->symType->isConcrete()) {         
01465           markReached(errStream, ast);
01466           add_todo(errStream, todo, ast);
01467         }
01468         break;
01469       }
01470       
01471     case at_defexception:
01472       {
01473         markReached(errStream, ast);
01474         add_todo(errStream, todo, ast);
01475         break;
01476       }
01477 
01478     case at_declstruct:
01479     case at_declunion:
01480     case at_defstruct:
01481     case at_defunion:
01482       break;
01483       
01484     case at_deftypeclass:
01485     case at_definstance:
01486       break;
01487 
01488     default:
01489       {
01490         assert(false);
01491         break;
01492       }
01493     }
01494   }
01495  
01496   DEBUG {
01497     uoc->ast->asString();
01498     uoc->ShowTypes(std::cout);
01499     
01500     std::cout << "_______________________________________________"
01501               << std::endl;
01502   }
01503   
01504   while(todo.size() > 0) {
01505     AST *ast = todo[todo.size() - 1];
01506     assert(ast != NULL);
01507     DEBUG std::cout << "Now Processing: " << ast->asString() << std::endl;
01508     todo.remove(todo.size() - 1);
01509 
01510     BE_CHKERR(errFree, polyinst(errStream, uoc, ast, mod, todo)); 
01511     DEBUG if(!errFree) {
01512       errStream << "Breaking because of an error " << std::endl;
01513       break;            
01514     }      
01515     
01516     DEBUG {
01517       std::cout << "- - - - - - - - - - - - - - - - - - - - - - - -"
01518                 << std::endl;
01519       
01520       uoc->ast->asString();
01521       uoc->ShowTypes(std::cout);
01522     
01523       std::cout << "_______________________________________________"
01524                 << std::endl;
01525     }
01526   }
01527 
01528   getIntoMainStream(errStream, mod);
01529   removeUnreached(mod);
01530   /* mod changes in this area, pointer may be stale, use uoc->ast */
01531   moveTypesUp(uoc->ast);  
01532   clearConstraints(uoc->ast);
01533   proclaimsAboveDefs(uoc->ast);  
01534   if(errFree) 
01535     BE_CHKERR(errFree, reRandT(errStream, uoc));
01536   //DisplayTypes(std::cout, uoc);
01537   
01538   return errFree;
01539 }
01540 
01541 
01542  

Generated on Thu May 17 23:59:16 2012 for BitC Compiler by  doxygen 1.4.7