TypeInferUtil.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2008, 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 <iostream>
00041 #include <string>
00042 #include <sstream>
00043 #include <libsherpa/UExcept.hxx>
00044 #include "UocInfo.hxx"
00045 #include "AST.hxx"
00046 #include "Type.hxx"
00047 #include "TypeScheme.hxx"
00048 #include "TypeMut.hxx"
00049 #include "Typeclass.hxx"
00050 #include "inter-pass.hxx"
00051 #include "TypeInfer.hxx"
00052 #include "TypeInferUtil.hxx"
00053 
00054 using namespace boost;
00055 using namespace sherpa;
00056 using namespace std;
00057 
00058 /**************************************************************/
00059 /*                     Some Helper Functions                  */
00060 /**************************************************************/
00061 
00062 shared_ptr<Type> 
00063 obtainFullUnionType(shared_ptr<Type> t)
00064 {  
00065   t = t->getBareType();  
00066   assert(t->isUType());
00067   shared_ptr<AST> unin = t->myContainer;  
00068   shared_ptr<TypeScheme> uScheme = unin->scheme;
00069   shared_ptr<Type> uType = uScheme->type_instance()->getType();
00070 
00071   assert(uType->typeTag == ty_unionv || uType->typeTag == ty_unionr);
00072   assert(uType->typeArgs.size() == t->typeArgs.size());
00073 
00074   for (size_t c=0; c < uType->typeArgs.size(); c++)
00075     t->TypeArg(c)->unifyWith(uType->TypeArg(c));
00076   
00077   return uType;
00078 }
00079 
00080 size_t
00081 nCtArgs(shared_ptr<Type> t)
00082 {
00083   assert(t->isUType() || t->isException());
00084   t = t->getBareType();
00085   
00086   size_t cnt=0;
00087   for (size_t i=0; i < t->components.size(); i++)
00088     if ((t->CompFlags(i) & COMP_UNIN_DISCM) == 0)
00089       cnt++;
00090 
00091   return cnt;
00092 }
00093 
00094 
00095 
00096 /**************************************************************/
00097 /*                    Environment handling                    */
00098 /**************************************************************/
00099 
00100 /* Use all bindings in the some other environment */
00101 void
00102 useIFGamma(const std::string& idName,
00103            shared_ptr<TSEnvironment > fromEnv, 
00104            shared_ptr<TSEnvironment > toEnv)
00105 {
00106   for (TSEnvironment::iterator itr = fromEnv->begin();
00107       itr != fromEnv->end(); ++itr) {
00108     std::string s = itr->first;
00109     shared_ptr<Binding<TypeScheme> > bdng = itr->second;
00110 
00111     if (bdng->flags & BF_PRIVATE)
00112       continue;
00113 
00114     shared_ptr<TypeScheme> ts = bdng->val;
00115 
00116     if (idName.size())
00117       s = idName + FQName::LocalBindingSep + s;
00118 
00119     toEnv->addBinding(s, ts);
00120     toEnv->setFlags(s, BF_PRIVATE|BF_COMPLETE);
00121   }  
00122 }
00123 
00124 
00125 void
00126 useIFInsts(const std::string& idName,
00127            shared_ptr<InstEnvironment >fromEnv, 
00128            shared_ptr<InstEnvironment >toEnv)
00129 {
00130   for (InstEnvironment::iterator itr = fromEnv->begin();
00131       itr != fromEnv->end(); ++itr) {
00132     std::string s = itr->first;
00133     shared_ptr<Binding<InstanceSet> > bdng = itr->second;
00134     
00135     if (bdng->flags & BF_PRIVATE)
00136       continue;
00137     
00138     shared_ptr<InstanceSet> insts = bdng->val;
00139     
00140     if (idName.size())
00141       s = idName + FQName::LocalBindingSep + s;
00142     
00143     toEnv->addBinding(s, insts);
00144     toEnv->setFlags(s, BF_PRIVATE|BF_COMPLETE);
00145   }
00146 }
00147   
00148 /* Initialize my environment */
00149 bool
00150 initGamma(std::ostream& errStream, 
00151           shared_ptr<TSEnvironment > gamma,
00152           shared_ptr<InstEnvironment > instEnv,
00153           const shared_ptr<AST> topAst)
00154 {
00155   bool errFree = true;
00156   // Make sure I am not processing the prelude itself
00157   // cout << "Processing " << ast->child(1)->child(0)->s 
00158   //      << std::endl;
00159   if (topAst->astType == at_interface &&
00160      topAst->child(0)->s == "bitc.prelude") {
00161     // cout << "Processing Prelude " << std::endl;
00162     return true;
00163   }
00164   
00165   // "use" everything in the prelude
00166   shared_ptr<TSEnvironment > preenv = GC_NULL;
00167   shared_ptr<InstEnvironment > preInsts = GC_NULL;
00168   
00169   UocMap::iterator itr = UocInfo::ifList.find("bitc.prelude");
00170   if (itr == UocInfo::ifList.end()) {
00171     errStream << topAst->loc << ": "
00172               << "Internal Compiler Error. "
00173               << "Prelude has NOT been processed till " 
00174               << "type inference."
00175               << std::endl;
00176     ::exit(1);
00177   }
00178 
00179   preenv = itr->second->gamma;
00180   preInsts = itr->second->instEnv;
00181 
00182   if (!preenv || !preInsts) {
00183     errStream << topAst->loc << ": "
00184               << "Internal Compiler Error. "
00185               << "Prelude's Gamma is NULL "
00186               << std::endl;
00187     ::exit(1);
00188   }
00189   
00190   useIFGamma(std::string(), preenv, gamma);
00191   useIFInsts(std::string(), preInsts, instEnv);
00192   return errFree;
00193 }
00194 

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