Type.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 <assert.h>
00039 #include <stdint.h>
00040 #include <stdlib.h>
00041 #include <dirent.h>
00042 #include <fstream>
00043 #include <iostream>
00044 #include <string>
00045 #include <sstream>
00046 
00047 #include <libsherpa/UExcept.hxx>
00048 
00049 #include "Options.hxx"
00050 #include "UocInfo.hxx"
00051 #include "AST.hxx"
00052 #include "Type.hxx"
00053 #include "TypeInfer.hxx"
00054 #include "TypeScheme.hxx"
00055 #include "TypeMut.hxx"
00056 #include "Typeclass.hxx"
00057 #include "inter-pass.hxx"
00058 #include "Unify.hxx"
00059 #include "Typeclass.hxx"
00060 #include "machine-dep.hxx"
00061 
00062 using namespace boost;
00063 using namespace sherpa;
00064 using namespace std;
00065 
00066 unsigned long long Type::typeCount=0;
00067 shared_ptr<Type> Type::Kmono = Type::make(ty_kfix);
00068 shared_ptr<Type> Type::Kpoly = Type::make(ty_kfix);
00069 
00070 static struct {
00071   const char *nm;
00072   bool isPrimary;
00073   bool isSimpleTypeForC;
00074   bool isAtomic;
00075   bool isScalarType;
00076   bool isRefType;
00077   bool isPrimInt;
00078   bool isPrimFloat;
00079 } typeInfo[] = {
00080 #define DEFTYPE(nm, prim, csimp, atom, scalar, ref, primInt, primFloat)        \
00081   { #nm, prim, csimp, atom, scalar, ref, primInt, primFloat },
00082 #include "types.def"
00083 };
00084 
00085 const char *
00086 TypeTagName(TypeTag ttag)
00087 {
00088   return typeInfo[ttag].nm;
00089 }
00090 
00091 TypeTag
00092 Type::LookupTypeTag(const std::string& s)
00093 {
00094   // The check for isPrimary is completely unnecessary, but
00095   // it makes the fail cases faster.
00096   for (size_t i = 0; i < (sizeof(typeInfo) / sizeof(typeInfo[0])); i++)
00097     if (typeInfo[i].isPrimary && typeInfo[i].nm == s)
00098       return (TypeTag) i;
00099 
00100   assert(false);
00101 }
00102 
00103 
00104 TypeTag 
00105 Type::getValTypeTag(const TypeTag refTag)
00106 {
00107   switch(refTag) {
00108   case ty_structr:
00109     return ty_structv;
00110 
00111   case ty_unionr:
00112     return ty_unionv;
00113 
00114   case ty_uconr:
00115     return ty_uconv;
00116 
00117   case ty_uvalr:
00118     return ty_uvalv;
00119 
00120   case ty_ref:
00121     return ty_tvar;
00122 
00123   default:
00124     assert(false);
00125     return ty_tvar;
00126   }
00127 }
00128 
00129 TypeTag 
00130 Type::getRefTypeTag(const TypeTag valTag)
00131 {
00132   switch(valTag) {
00133   case ty_structv:
00134     return ty_structr;
00135 
00136   case ty_unionv:
00137     return ty_unionr;
00138 
00139   case ty_uconv:
00140     return ty_uconr;
00141 
00142   case ty_uvalv:
00143     return ty_uvalr;
00144 
00145   case ty_tvar:
00146     return ty_ref;
00147 
00148   default:
00149     assert(false);
00150     return ty_ref;
00151   }
00152 }
00153 
00154 
00155 shared_ptr<const Type> 
00156 Type::getTypePrim() const
00157 { 
00158   shared_ptr<const Type> curr = shared_from_this();
00159   while (curr->link)
00160     curr = curr->link;
00161   
00162   return curr;
00163 }
00164 
00165 shared_ptr<Type> 
00166 Type::getTypePrim()
00167 { 
00168   shared_ptr<Type> curr = shared_from_this();
00169   while (curr->link)
00170     curr = curr->link;
00171   
00172   return curr;
00173 }
00174 
00175 
00176 // Normalize Mutability Constructor Idempotence
00177 // Deal with the fact that 
00178 // (mutable (mutable t)) == (mutable t)
00179 // We cannot avoid this type of linkage because of a structure
00180 // getting parametrized over a mutable type while having a mutable
00181 // wrapper at the field level.  
00182 shared_ptr<Type> 
00183 Type::normalize_mut()
00184 { 
00185   shared_ptr<Type> t = getTypePrim();
00186   shared_ptr<Type> in = t;
00187   
00188   while (in->typeTag == ty_mutable) {
00189     t = in;
00190     in = in->Base()->getTypePrim();
00191   }
00192   
00193   return t;
00194 }
00195  
00196 shared_ptr<Type> 
00197 Type::getType()
00198 { 
00199   shared_ptr<Type> t = normalize_mut();
00200   
00201   // Maybe-types must be handled with special care:
00202   // mbTop can only be of the form 'a!t where the Var() part is a
00203   // type variable. If the Var() part of this mbTop type is not a
00204   // type variable, then, it has unified with some other type,
00205   // and we must follow that link.
00206   // mbFull can be of the form 'a!t or M'a|t. Otherwise, we follow
00207   // the link to whatever type the Var() part has unified with.
00208   // Maybe types may not be recursively nested.
00209   // The Var() part of an mbTop must only be linked to 
00210   // (be substituted by) an unconstrained type./
00211   // The Var() part of an mbFull can be linked to an mbTop type or an
00212   // unconstrained type.
00213 
00214   if (t->typeTag == ty_mbFull) {
00215     shared_ptr<Type> in = t->Var()->normalize_mut();
00216     shared_ptr<Type> within = ((in->typeTag == ty_mutable) ?
00217                                in->Base()->getTypePrim(): in);
00218     
00219     if(within->typeTag != ty_tvar)
00220       t = in;
00221   }
00222 
00223   if(t->typeTag == ty_mbTop) {
00224     shared_ptr<Type> in = t->Var()->normalize_mut();
00225     if(in->typeTag != ty_tvar)
00226       t = in;
00227   }
00228 
00229   if (t->typeTag == ty_mbFull || t->typeTag == ty_mbTop) {
00230     shared_ptr<Type> var = t->Var()->normalize_mut();
00231     shared_ptr<Type> core = t->Core()->normalize_mut();
00232     
00233     if (var == core)
00234       t = core;
00235   }
00236 
00237   return t;
00238 }
00239 
00240 shared_ptr<const Type> 
00241 Type::getType() const
00242 { 
00243   shared_ptr<const Type> t = getTypePrim();
00244   
00245   if (t->typeTag == ty_mutable) {    
00246     shared_ptr<Type> in = t->components[0]->typ->getTypePrim();
00247     while (in->typeTag == ty_mutable) {
00248       t = in;
00249       in = t->components[0]->typ->getTypePrim();
00250     }
00251   }
00252   
00253   return t;
00254 }
00255 
00256 shared_ptr<Type> 
00257 Type::getBareType()
00258 { 
00259   shared_ptr<Type> t = getType();
00260   
00261   if (t->mark & MARK_GET_BARE_TYPE)
00262     return t;
00263   
00264   t->mark |= MARK_GET_BARE_TYPE;
00265 
00266   shared_ptr<Type> retType = t;
00267 
00268   if (t->isMaybe())
00269     retType = t->Core()->getBareType();  
00270   
00271   if (t->isMutable())
00272     retType = t->Base()->getBareType();  
00273 
00274   t->mark &= ~MARK_GET_BARE_TYPE;
00275   return retType;
00276 }
00277 
00278 shared_ptr<Type> 
00279 Type::getTheType(bool mutableOK, bool maybeOK)
00280 { 
00281   shared_ptr<Type> t = getType();  
00282 
00283   if (t->mark & MARK_GET_THE_TYPE)
00284     return t;
00285   
00286   t->mark |= MARK_GET_THE_TYPE;
00287 
00288   shared_ptr<Type> retType = t;
00289   
00290   if ((t->typeTag == ty_mutable) && !mutableOK)
00291     retType = t->Base()->getTheType(mutableOK, maybeOK);
00292   else if (t->isMaybe() && !maybeOK)
00293     retType = t->Core()->getTheType(mutableOK, maybeOK);
00294   
00295   t->mark &= ~MARK_GET_THE_TYPE;
00296   return retType;
00297 }
00298 
00299 bool
00300 Type::isTvar()
00301 {
00302   shared_ptr<Type> t = getType();  
00303   return (t->typeTag == ty_tvar);
00304 }
00305 
00306 bool
00307 Type::isVariable()
00308 {
00309   shared_ptr<Type> t = getBareType();  
00310   return (t->typeTag == ty_tvar);
00311 }
00312 
00313 bool
00314 Type::isUnifiableVar(UnifyFlags uflags)
00315 {
00316   shared_ptr<Type> t = getType();
00317   shared_ptr<Type> var = t;
00318   
00319   switch(t->typeTag) {
00320   case ty_tvar:
00321     var = t;
00322     break;
00323 
00324   case ty_mbTop:
00325     var = t->Var()->getType();
00326     break;
00327 
00328   case ty_mbFull:
00329     var = t->Var()->getType();
00330   
00331     if(var->isMutable())
00332       var = var->Base()->getType();
00333     break;
00334     
00335   default:
00336     return false;
00337   }
00338 
00339   if (uflags & UFLG_UN_IGN_RIGIDITY)
00340     return true;
00341   
00342   return ((var->flags & TY_RIGID) == 0);
00343 }
00344 
00345 bool 
00346 Type::isAtomic()
00347 {
00348   shared_ptr<Type> t = getBareType();  
00349   return typeInfo[t->typeTag].isAtomic;
00350 }
00351 
00352 bool 
00353 Type::isSimpleTypeForC()
00354 {
00355   shared_ptr<Type> t = getBareType();
00356   return typeInfo[t->typeTag].isSimpleTypeForC;
00357 }
00358 
00359 bool 
00360 Type::isScalar()
00361 {
00362   shared_ptr<Type> t = getBareType();  
00363   return typeInfo[t->typeTag].isScalarType;
00364 }
00365 
00366 bool 
00367 Type::isRefType()
00368 {
00369   shared_ptr<Type> t = getBareType();
00370   return typeInfo[t->typeTag].isRefType;
00371 }
00372 
00373 bool 
00374 Type::isValType()
00375 {
00376   return !isRefType();
00377 }
00378 
00379 bool 
00380 Type::isByrefType()
00381 {
00382   shared_ptr<Type> t = getBareType();
00383   return (t->typeTag == ty_byref);
00384 }
00385 
00386 bool 
00387 Type::isArrayByref()
00388 {
00389   shared_ptr<Type> t = getBareType();
00390   return (t->typeTag == ty_array_ref);
00391 }
00392 
00393 bool 
00394 Type::isIndexableType()
00395 {
00396   shared_ptr<Type> t = getBareType();
00397   return (t->typeTag == ty_array_ref 
00398           || t->typeTag == ty_vector 
00399           || t->typeTag == ty_array);
00400 }
00401 
00402 bool 
00403 Type::isNullableType()
00404 {
00405   shared_ptr<Type> t = getBareType();
00406   return (t->typeTag == ty_unionv &&
00407           (t->defAst->flags & NULLABLE_UN));
00408 }
00409 
00410 bool 
00411 Type::isNonEscaping()
00412 {
00413   return isArrayByref();
00414 }
00415 
00416 
00417 // Is the current type constrained by (ref-types t) 
00418 // within the constraint set tcc?
00419 bool 
00420 Type::isConstrainedToRefType(boost::shared_ptr<TCConstraints> tcc)
00421 {
00422   shared_ptr<Type> t = getType();
00423   
00424   for (TypeSet::iterator itr = tcc->begin(); itr != tcc->end(); ++itr) {
00425     shared_ptr<Typeclass> pred = (*itr);
00426     
00427     const std::string &ref_types = SpecialNames::spNames.sp_ref_types; 
00428     
00429     if (pred->defAst->s == ref_types) {
00430       shared_ptr<Type> arg = pred->TypeArg(0)->getType();
00431       if (strictlyEquals(arg, false, true))
00432         return true;
00433     }
00434   }
00435 
00436   return false;
00437 }
00438 
00439 
00440 bool 
00441 Type::isFnxn()
00442 {
00443   shared_ptr<Type> t = getBareType();
00444   return (t->typeTag == ty_fn);
00445 }
00446 
00447 bool 
00448 Type::isMethod()
00449 {
00450   shared_ptr<Type> t = getBareType();
00451   return (t->typeTag == ty_method);
00452 }
00453 
00454 bool 
00455 Type::isBaseConstType()
00456 {
00457   switch(getType()->typeTag) {
00458   case ty_unit:
00459   case ty_bool:
00460   case ty_char:
00461   case ty_string:
00462   case ty_int8:
00463   case ty_int16:
00464   case ty_int32:
00465   case ty_int64:
00466   case ty_uint8:
00467   case ty_uint16:
00468   case ty_uint32:
00469   case ty_uint64:
00470   case ty_word:
00471   case ty_float:
00472   case ty_double:
00473   case ty_quad:
00474   case ty_dummy:
00475 
00476     // FIX: case ty_lit:
00477     return true;
00478   default:
00479     return false;
00480   }
00481 }
00482 
00483 
00484 //#if 0
00485 bool 
00486 Type::isClosure()
00487 {
00488   shared_ptr<Type> t = getBareType();
00489   return (t->typeTag == ty_fn);
00490 }
00491 //#endif
00492 
00493 bool 
00494 Type::isMutable()
00495 {
00496   shared_ptr<Type> t = getType();
00497   return t->typeTag == ty_mutable;
00498 }
00499 
00500 bool 
00501 Type::isMutType()
00502 {
00503   shared_ptr<Type> t = getType();
00504   return(t->isMutable() ||
00505          (t->isMbFull() && t->Var()->isMutable()));
00506 }
00507 
00508 bool 
00509 Type::isConst()
00510 {
00511   shared_ptr<Type> t = getType();
00512   return t->typeTag == ty_const;
00513 }
00514 
00515 bool 
00516 Type::isMaybe()
00517 {
00518   shared_ptr<Type> t = getType();
00519   return (t->typeTag == ty_mbTop || t->typeTag == ty_mbFull);
00520 }
00521 
00522 bool 
00523 Type::isMbFull()
00524 {
00525   shared_ptr<Type> t = getType();
00526   return (t->typeTag == ty_mbFull);
00527 }
00528 
00529 bool 
00530 Type::isMbTop()
00531 {
00532   shared_ptr<Type> t = getType();
00533   return (t->typeTag == ty_mbTop);
00534 }
00535  
00536 bool 
00537 Type::isMaxMutable()
00538 {
00539   return strictlyEquals(maximizeMutability());
00540 }
00541 
00542 extern shared_ptr<TvPrinter> debugTvp;
00543 bool
00544 Type::isMinMutable()
00545 {
00546   return strictlyEquals(minimizeMutability());
00547 }
00548 
00549 bool 
00550 Type::isPrimInt()
00551 {
00552   shared_ptr<Type> t = getBareType();
00553   return (typeInfo[t->typeTag].isPrimInt);
00554 }
00555 
00556 bool 
00557 Type::isPrimFloat()
00558 {
00559   shared_ptr<Type> t = getBareType();
00560   return (typeInfo[t->typeTag].isPrimFloat);
00561 }
00562 
00563 bool 
00564 Type::isPrimaryType()
00565 {
00566   shared_ptr<Type> t = getBareType();
00567   return (typeInfo[t->typeTag].isPrimary);
00568 }
00569 bool 
00570 Type::isInteger()
00571 {
00572   shared_ptr<Type> t = getBareType();
00573   switch(t->typeTag) {
00574   case ty_int8:
00575   case ty_int16:
00576   case ty_int32:
00577   case ty_int64:
00578   case ty_uint8:
00579   case ty_uint16:
00580   case ty_uint32:
00581   case ty_uint64:
00582 #ifdef KEEP_BF
00583   case ty_bitfield:
00584 #endif
00585     return true;
00586   default:
00587     return false;
00588   }
00589 }
00590 
00591 bool 
00592 Type::isbool()
00593 {
00594   shared_ptr<Type> t = getBareType();
00595   return (t->typeTag == ty_bool);
00596 }
00597 
00598 bool 
00599 Type::isIntegral()
00600 {
00601   shared_ptr<Type> t = getBareType();
00602   switch(t->typeTag) {
00603   case ty_int8:
00604   case ty_int16:
00605   case ty_int32:
00606   case ty_int64:
00607   case ty_uint8:
00608   case ty_uint16:
00609   case ty_uint32:
00610   case ty_uint64:
00611 #ifdef KEEP_BF
00612   case ty_bitfield:
00613 #endif
00614   case ty_word:
00615     return true;
00616   default:
00617     return false;
00618   }
00619 }
00620 
00621 
00622 size_t 
00623 Type::nBits()
00624 {
00625   shared_ptr<Type> t = getBareType();
00626   switch(t->typeTag) {
00627   case ty_bool:
00628     return 1;
00629 
00630   case ty_int8:
00631   case ty_uint8:
00632     return 8;
00633   case ty_int16:
00634   case ty_uint16:
00635     return 16;
00636 
00637   case ty_int32:
00638   case ty_uint32:
00639     return 32;
00640 
00641   case ty_int64:
00642   case ty_uint64:
00643     return 64;
00644     
00645 #ifdef KEEP_BF
00646   case ty_bitfield:
00647     return t->Isize;
00648 #endif
00649 
00650   case ty_word:
00651     return TARGET_WORD_SIZE;
00652 
00653   default:
00654     assert(false);
00655   }
00656 }
00657 
00658 
00659 bool 
00660 Type::isFloat()
00661 {
00662   shared_ptr<Type> t = getBareType();
00663   switch(t->typeTag) {
00664   case ty_float:
00665   case ty_double:
00666   case ty_quad:
00667     return true;
00668   default:
00669     return false;
00670   }
00671 }
00672 
00673 bool
00674 Type::isTypeClass()
00675 {
00676   shared_ptr<Type> t = getBareType();
00677   return (t->typeTag == ty_typeclass);    
00678 }
00679 
00680 bool
00681 Type::isPcst()
00682 {
00683   shared_ptr<Type> t = getBareType();
00684   return (t->typeTag == ty_pcst);    
00685 }
00686 
00687 // Returns true if this is a union type 
00688 bool 
00689 Type::isUnion(bool ignMut) 
00690 {
00691   shared_ptr<Type> t = ((ignMut) ? getBareType() : getType());
00692   return ((t->typeTag == ty_unionv) || (t->typeTag == ty_unionr));
00693 }
00694 
00695 bool 
00696 Type::isUcon(bool ignMut) 
00697 {
00698   shared_ptr<Type> t = ((ignMut) ? getBareType() : getType());
00699   return ((t->typeTag == ty_uconv) || (t->typeTag == ty_uconr));
00700 }
00701 
00702 bool 
00703 Type::isUval(bool ignMut) 
00704 {
00705   shared_ptr<Type> t =  ((ignMut) ? getBareType() : getType());
00706   return ((t->typeTag == ty_uvalv) || (t->typeTag == ty_uvalr));
00707 }
00708 
00709 bool 
00710 Type::isULeg(bool ignMut) 
00711 {
00712   return(isUcon(ignMut) || isUval(ignMut));
00713 }
00714 
00715 bool 
00716 Type::isUType(bool ignMut) 
00717 {
00718   return(isUnion(ignMut) || isUcon(ignMut) || isUval(ignMut));
00719 }
00720 
00721 bool
00722 Type::isDeepMut()
00723 {
00724   shared_ptr<Type> t = getType();
00725   
00726   if (t->mark & MARK_PREDICATE)
00727     return true;
00728   
00729   t->mark |= MARK_PREDICATE;
00730   
00731   bool mut = false;
00732   
00733   switch(t->typeTag) {
00734   case ty_mutable:
00735     mut = true;
00736     break;
00737     
00738   case ty_fn:
00739     break;
00740 
00741   default:
00742     for (size_t i=0;!mut &&  i < t->components.size(); i++)
00743       mut = t->CompType(i)->isDeepMut();
00744    
00745     for (size_t i=0; !mut && i < t->typeArgs.size(); i++)
00746       mut = t->TypeArg(i)->isDeepMut();
00747 
00748     // No need to check functional dependencies
00749     // May lead to error if checked because functional dependencies
00750     // might be on types that are used within a function constructor
00751     break;
00752   }
00753   
00754   t->mark &= ~MARK_PREDICATE;
00755   return mut;
00756 }
00757   
00758 bool 
00759 Type::isDeepImmut()
00760 {
00761   shared_ptr<Type> t = getType();
00762   
00763   if (t->mark & MARK_PREDICATE)
00764     return true;
00765   
00766   t->mark |= MARK_PREDICATE;
00767   
00768   bool immut = true;
00769   
00770   switch(t->typeTag) {
00771   case ty_mutable:
00772   case ty_tvar:
00773     immut = false;
00774     break;
00775  
00776   case ty_fn:
00777     break;
00778     
00779   default:
00780     for (size_t i=0; immut && i < t->components.size(); i++)
00781       immut = t->CompType(i)->isDeepImmut();
00782     
00783     for (size_t i=0; immut && i < t->typeArgs.size(); i++)
00784       immut = t->TypeArg(i)->isDeepImmut();
00785 
00786     // No need to check functional dependencies
00787     // May lead to error if checked because functional dependencies
00788     // might be on types that are used within a function constructor
00789     
00790     break;
00791   }
00792 
00793   t->mark &= ~MARK_PREDICATE;
00794   return immut;  
00795 }
00796 
00797 bool 
00798 Type::isConcretizable()
00799 {
00800   shared_ptr<Type> t = getType();
00801   
00802   if (t->mark & MARK_PREDICATE)
00803     return true;
00804   
00805   t->mark |= MARK_PREDICATE;
00806   
00807   bool concretizable = true;
00808   
00809   switch(t->typeTag) {
00810   case ty_tvar:
00811     concretizable = false;
00812     break;
00813 
00814   case ty_mbTop:
00815   case ty_mbFull:
00816     concretizable = t->Core()->isConcretizable();
00817     
00818   case ty_fn:
00819     break;
00820     
00821   default:
00822     for (size_t i=0; concretizable && i < t->typeArgs.size(); i++)
00823       concretizable = t->TypeArg(i)->isConcretizable();
00824     break;
00825   }
00826   
00827   t->mark &= ~MARK_PREDICATE;
00828   return concretizable;  
00829 }
00830 
00831 bool 
00832 Type::isShallowConcretizable()
00833 {
00834   shared_ptr<Type> t = getType();
00835   
00836   if (t->mark & MARK_PREDICATE)
00837     return true;
00838   
00839   t->mark |= MARK_PREDICATE;
00840   
00841   bool concretizable = true;
00842   
00843   switch(t->typeTag) {
00844   case ty_tvar:
00845     concretizable = false;
00846     break;
00847 
00848   case ty_mbTop:
00849   case ty_mbFull:
00850     concretizable = t->Core()->isShallowConcretizable();
00851     
00852   case ty_mutable:
00853   case ty_array:
00854     concretizable = t->Base()->isShallowConcretizable();
00855     break;
00856     
00857   case ty_structv:
00858   case ty_unionv:
00859   case ty_uvalv:
00860   case ty_uconv:
00861     for (size_t i=0; concretizable && i < t->typeArgs.size(); i++)
00862       concretizable = t->TypeArg(i)->isShallowConcretizable();
00863     break;
00864 
00865   default:
00866     break;
00867   }
00868   
00869   t->mark &= ~MARK_PREDICATE;
00870   return concretizable;  
00871 }
00872 
00873 bool 
00874 Type::isEffectivelyConst()
00875 {
00876   shared_ptr<Type> t = getType();
00877   
00878   if (t->mark & MARK_PREDICATE)
00879     return true;
00880   
00881   t->mark |= MARK_PREDICATE;
00882   
00883   bool effConst = true;
00884   
00885   switch(t->typeTag) {
00886   case ty_tvar:
00887   case ty_mbTop:
00888   case ty_mbFull:
00889   case ty_mutable:
00890     effConst = false;
00891     
00892   case ty_array:
00893   case ty_structv:
00894   case ty_unionv:
00895   case ty_uvalv:
00896   case ty_uconv:
00897     for (size_t i=0; effConst && i < t->components.size(); i++)
00898       effConst = t->CompType(i)->isEffectivelyConst();
00899     break;
00900     
00901   default:
00902     break;
00903   }
00904   
00905   t->mark &= ~MARK_PREDICATE;
00906   return effConst;
00907 }
00908 
00909 bool 
00910 Type::isConstReducible()
00911 {
00912   shared_ptr<Type> t = getType();
00913   
00914   if (t->mark & MARK_PREDICATE)
00915     return true;
00916   
00917   t->mark |= MARK_PREDICATE;
00918   
00919   bool constred = true;
00920   
00921   switch(t->typeTag) {
00922   case ty_tvar:
00923   case ty_mbTop:
00924   case ty_mbFull:
00925     constred = false;
00926     
00927   case ty_mutable:
00928   case ty_array:
00929   case ty_structv:
00930   case ty_unionv:
00931   case ty_uvalv:
00932   case ty_uconv:
00933     for (size_t i=0; constred && i < t->components.size(); i++)
00934       constred = t->CompType(i)->isConstReducible();
00935     break;
00936 
00937   default:
00938     break;
00939   }
00940   
00941   t->mark &= ~MARK_PREDICATE;
00942   return constred;
00943 }
00944 
00945 void 
00946 Type::normalize(boost::shared_ptr<Trail> trail)
00947 {
00948   normalize_mbFull(trail);
00949 }
00950 
00951 
00952 /* Produce Type ty_union[rv] from ty_ucon[rv] or ty_uval[rv]
00953    ONLY typeArgs are populated */
00954 shared_ptr<Type> 
00955 Type::getUnionType()
00956 {
00957   shared_ptr<Type> uType = getType();
00958   assert(uType->isUType());
00959   shared_ptr<Type> uCopy = uType->getType()->getDCopy();
00960   shared_ptr<Type> t = uCopy->getBareType();
00961   t->typeTag = (uType->isRefType() ? ty_unionr : ty_unionv);
00962   t->defAst = t->myContainer;
00963   t->components.clear();
00964   return uCopy;
00965 }
00966 
00967 bool 
00968 Type::isException() 
00969 {
00970   shared_ptr<Type> t = getBareType();
00971   return (t->typeTag == ty_exn);
00972 }
00973 
00974 bool 
00975 Type::isStruct()
00976 {
00977   shared_ptr<Type> t = getBareType();
00978 
00979   return ((t->typeTag == ty_structv) || 
00980           (t->typeTag == ty_structr));
00981 }
00982 
00983 bool
00984 Type::isArray()
00985 {
00986   shared_ptr<Type> t = getBareType();
00987   return (t->typeTag == ty_array);
00988 }
00989 
00990 bool
00991 Type::isVector()
00992 {
00993   shared_ptr<Type> t = getBareType();
00994   return (t->typeTag == ty_vector);
00995 }
00996 
00997 
00998 bool 
00999 Type::isObject()
01000 {
01001   shared_ptr<Type> t = getBareType();
01002 
01003   return ((t->typeTag == ty_objectv) || 
01004           (t->typeTag == ty_objectr));
01005 }
01006 
01007 bool 
01008 Type::isDecl()
01009 {
01010   shared_ptr<Type> t = getBareType();
01011   switch(t->typeTag) {
01012   case ty_unionv:
01013   case ty_unionr:
01014   case ty_structv:
01015   case ty_structr:
01016     return (t->components.empty());
01017 
01018   default:
01019     return false;
01020   }  
01021 }
01022 
01023 bool
01024 Type::isOfInfiniteType()
01025 {
01026   bool infType = false;
01027 
01028   if (getType() != shared_from_this())
01029     return getType()->isOfInfiniteType();
01030 
01031   if (mark & MARK_PREDICATE) 
01032     return true;
01033 
01034   mark |= MARK_PREDICATE;
01035 
01036   switch(typeTag) {
01037   case ty_tvar:
01038   case ty_kvar:
01039   case ty_kfix:
01040   case ty_dummy:
01041   case ty_unit:
01042   case ty_bool:
01043   case ty_char:
01044   case ty_string:
01045   case ty_int8:
01046   case ty_int16:
01047   case ty_int32:
01048   case ty_int64:
01049   case ty_uint8:
01050   case ty_uint16:
01051   case ty_uint32:
01052   case ty_uint64:
01053   case ty_word:
01054   case ty_float:
01055   case ty_double:
01056   case ty_quad:
01057 #ifdef KEEP_BF
01058   case ty_bitfield:
01059 #endif
01060   case ty_field:
01061     {
01062       infType = false;
01063       break;
01064     }
01065     
01066   case ty_mbFull:
01067   case ty_mbTop:
01068   case ty_array:
01069   case ty_vector:
01070   case ty_ref:
01071   case ty_byref:
01072   case ty_array_ref:
01073   case ty_mutable:
01074   case ty_const:
01075   case ty_fn:
01076   case ty_method:
01077     {
01078       for (size_t i=0; !infType && (i < components.size()); i++)
01079               if (CompType(i)->isOfInfiniteType())
01080                 infType = true;
01081       break;
01082     }
01083 
01084   case ty_letGather:
01085   case ty_tyfn:
01086   case ty_fnarg:
01087   case ty_structv:
01088   case ty_structr:
01089   case ty_uconv:
01090   case ty_uconr:
01091   case ty_uvalv:
01092   case ty_uvalr:
01093   case ty_unionv:
01094   case ty_unionr:
01095   case ty_typeclass:
01096   case ty_exn:
01097   case ty_pcst:
01098     {      
01099       for (size_t i=0; !infType && (i < typeArgs.size()); i++)
01100               if (TypeArg(i)->isOfInfiniteType())
01101                 infType = true;
01102 
01103       break;
01104     }
01105   }
01106   
01107  mark &= ~MARK_PREDICATE;
01108  return infType;
01109 }
01110 
01111 // Return true iff a binding of this type requires capture conversion
01112 // (by migrating it into the heap). Rules are as follows:
01113 //
01114 //   1. Mutable types *always* require capture 
01115 //   2. Otherwise, scalar and reference types do not require
01116 //      capture conversion.
01117 //   3. Otherwise, the type requires capture conversion. This
01118 //      is conservative, but correct.
01119 //   4. Function types need heapification! This case is handled
01120 //      separately since functions are marked scalars in kind.def
01121 //      (they actually are, except for this case). The issue here is
01122 //      that we are talking about a function *pointer* which must be a
01123 //      real location (alloc-ref) before the code for the closure can
01124 //      be produced, and later we can set the function pointer to the
01125 //      correct value (copy-ref).  
01126 
01127 bool
01128 Type::needsCaptureConversion()
01129 {
01130   shared_ptr<Type> t = getType();
01131   if (t->isMutable())
01132     return true;
01133   if (t->isFnxn())
01134     return true;
01135   else if (t->isRefType())
01136     return false;
01137   else if (t->isScalar())
01138     return false;
01139   
01140   // All other cases require conversion. 
01141   // This is somewhat conservative.
01142   return true;
01143 }
01144 
01145 
01146 bool 
01147 Type::isConcrete()
01148 {
01149   TypeSet tvs;
01150   collectAllftvs(tvs);
01151   return (tvs.empty());
01152 }
01153 
01154 void 
01155 Type::SetTvarsTo(shared_ptr<Type> t)
01156 {
01157   TypeSet tvs;
01158   collectAllftvs(tvs);
01159   
01160   for (TypeSet::iterator itr = tvs.begin(); itr != tvs.end(); ++itr)
01161     (*itr)->getType()->link = t;
01162 }
01163 
01164 void 
01165 Type::SetTvarsToUnit()
01166 {
01167   TypeSet tvs;
01168   collectAllftvs(tvs);
01169   
01170   for (TypeSet::iterator itr = tvs.begin(); itr != tvs.end(); ++itr) {
01171     shared_ptr<Type> ftv = (*itr)->getType();
01172     shared_ptr<Type> unit = Type::make(ty_unit);
01173     ftv->link = unit;
01174   }
01175 }
01176   
01177 comp::comp(shared_ptr<Type> t, CompFlagSet _flags) 
01178 {
01179   name = "";
01180   typ = (shared_ptr<Type> )t;
01181   flags=_flags;
01182 }
01183   
01184 comp::comp(const std::string s, shared_ptr<Type> t, CompFlagSet _flags) 
01185 {
01186   name = s;
01187   typ = t;
01188   flags = _flags;
01189 }
01190 
01191 // comp::comp(const comp &c)
01192 // {
01193 //   name = c.name;
01194 //   typ = c.typ;
01195 //   flags = c.flags;  
01196 // }
01197 
01198 #define TYPE_CTR_INIT(tt) do {                  \
01199     typeTag = tt;                               \
01200     defAst = GC_NULL;                           \
01201     myContainer = GC_NULL;                      \
01202     minSignedRep = 0;                           \
01203     minUnsignedRep = 0;                         \
01204     Isize = 0;                                  \
01205     if(typeTag == ty_array)                     \
01206       arrLen = ArrLen::make(0);                 \
01207     else                                        \
01208       arrLen = GC_NULL;                         \
01209     mark = MARK_NONE;                           \
01210     pMark = 0;                                  \
01211     sp = GC_NULL;                               \
01212     link = GC_NULL;                             \
01213     flags = TY_NO_FLAGS;                        \
01214   } while (0);
01215 
01216 
01217 Type::Type(const TypeTag ttag)
01218   : uniqueID(genTypeID())
01219 {
01220   TYPE_CTR_INIT(ttag);
01221 }
01222 
01225 Type::Type(const TypeTag ttag, shared_ptr<Type> child)
01226   : uniqueID(genTypeID())
01227 {
01228   TYPE_CTR_INIT(ttag);
01229   components.push_back(comp::make(child));
01230 }
01231 
01232 Type::Type(const TypeTag ttag, shared_ptr<Type> child1, shared_ptr<Type> child2)
01233   : uniqueID(genTypeID())
01234 {
01235   TYPE_CTR_INIT(ttag);
01236   components.push_back(comp::make(child1));
01237   components.push_back(comp::make(child2));
01238 }
01239 
01240 // Copy constructor, except distinct uniqueID
01241 Type::Type(shared_ptr<Type>  t)
01242   : uniqueID(genTypeID())
01243 {
01244   assert(t);
01245   typeTag = t->typeTag;
01246   defAst = t->defAst;
01247   myContainer = t->myContainer;
01248   link = t->link;    
01249   arrLen = t->arrLen; // Copies the indirection
01250   Isize = t->Isize;
01251   minSignedRep = t->minSignedRep;
01252   minUnsignedRep = t->minUnsignedRep;
01253   litValue = t->litValue;
01254 
01255   typeArgs = t->typeArgs;
01256   fnDeps = t->fnDeps;
01257     
01258   for (size_t i=0; i<t->components.size(); i++)
01259     components.push_back(comp::make(t->CompName(i), t->CompType(i), t->CompFlags(i)));
01260   for (size_t i=0; i<t->methods.size(); i++)
01261     methods.push_back(comp::make(t->MethodName(i), t->MethodType(i), t->MethodFlags(i)));
01262 
01263   mark = MARK_NONE;
01264   pMark = 0;  
01265   sp = GC_NULL;
01266   flags = t->flags;
01267 }
01268 
01269 // Makes a deep copy , but ** LINKS TVARS TO ORIGINAL ONES ** 
01270 shared_ptr<Type> 
01271 Type::getDCopy()
01272 {
01273   shared_ptr<Type> t = getType();
01274   shared_ptr<TypeScheme> sigma = TypeScheme::make(t, GC_NULL);
01275   // sigma's ftvs are empty, therefore, TypeSpecialize will link
01276   // all type-variables to the original ones
01277   shared_ptr<Type> newTyp = sigma->type_instance();
01278   newTyp->flags = flags;
01279   return newTyp;
01280 }
01281 
01282 // Returns true of the type `t' is structurally equal to `this'
01283 // under alpha renaming -- modulo:
01284 // i)   mutability 
01285 // ii)  declarations unify with definitions
01286 // iii) Imprecise integer/floating point types unify with 
01287 //          compatible primitive/prelude typres
01288 // 
01289 // However, it should be noted that this is rarely an issue 
01290 // if the function used once the inference process is OVER.
01291 //
01292 // If one is still not satisfied, he can use the next function
01293 // strictlyEquals which removes the above two restrictions.
01294 bool
01295 Type::eql(shared_ptr<Type> t, bool verbose, std::ostream &errStream,
01296           UnifyFlags uflags, bool keepSub,
01297           shared_ptr<Trail> trail)
01298 {
01299   std::stringstream ss;  
01300   LexLoc internalLocation;
01301   bool errFree = unify(ss, trail, internalLocation, 
01302                        shared_from_this(), t, uflags);
01303   
01304   if (!keepSub)
01305     trail->rollBack();
01306 
01307   if (verbose) {
01308     if (errFree)
01309       errStream << asString() << " === " << t->asString()
01310                 << std::endl;
01311     else
01312       errStream << asString() << " !== " << t->asString()
01313                 << " because " << ss.str() 
01314                 << std::endl;
01315   }
01316 
01317   return errFree;
01318 }
01319 
01320 bool
01321 Type::defEqualsDecl(shared_ptr<Type> t, bool verbose, std::ostream &errStream)
01322 {
01323   return eql(t, verbose, errStream, 
01324              UFLG_UNIFY_STRICT|UFLG_UN_IGN_RIGIDITY, false);
01325 }
01326 
01327 bool
01328 Type::equals(shared_ptr<Type> t, bool verbose, std::ostream &errStream)
01329 {
01330   return eql(t, verbose, errStream, UFLG_NO_FLAGS, false);
01331 }
01332 
01333 bool 
01334 Type::strictlyEquals(shared_ptr<Type> t, bool verbose,
01335                      bool noAlphaRename,
01336                      std::ostream &errStream)
01337 {
01338   UnifyFlags uflags = UFLG_UNIFY_STRICT;
01339   if (noAlphaRename)
01340     uflags |= UFLG_UNIFY_STRICT_TVAR;
01341   return eql(t, verbose, errStream, uflags, false);
01342 }
01343 
01344 bool
01345 Type::unifyWith(shared_ptr<Type> t, bool verbose, 
01346                 shared_ptr<Trail> trail, ostream &errStream)
01347 {
01348   return eql(t, verbose, errStream, UFLG_NO_FLAGS, true, trail);
01349 }
01350 
01351 bool 
01352 Type::forcedUnify(shared_ptr<Type> t, bool verbose, std::ostream &errStream)
01353 {
01354   return eql(t, verbose, errStream, UFLG_UN_IGN_RIGIDITY, true);
01355 }
01356 
01357 bool
01358 Type::equalsA(shared_ptr<Type> t, bool verbose, std::ostream &errStream)
01359 {
01360   return eql(t, verbose, errStream, UFLG_UN_IGN_RIGIDITY, false);
01361 }
01362 
01363 bool 
01364 Type::strictlyEqualsA(shared_ptr<Type> t, bool verbose,
01365                       std::ostream &errStream)
01366 {
01367   return eql(t, verbose, errStream, 
01368              UFLG_UNIFY_STRICT | UFLG_UN_IGN_RIGIDITY, false);
01369 }
01370 
01371 bool 
01372 Type::copy_compatible(shared_ptr<Type> t, bool verbose, std::ostream &errStream)
01373 {
01374   return MBF(shared_from_this())->equals(MBF(t), verbose, errStream);
01375 }
01376 
01377 bool 
01378 Type::copy_compatibleA(shared_ptr<Type> t, bool verbose, std::ostream &errStream)
01379 {
01380   return MBF(shared_from_this())->equalsA(MBF(t), verbose, errStream);
01381 }
01382 
01383 bool
01384 Type::allTvarsRigid()
01385 {
01386   TypeSet ftvs;
01387   getType()->collectAllftvs(ftvs);
01388   for (TypeSet::iterator itr = ftvs.begin(); itr != ftvs.end(); ++itr) {
01389     if (((*itr)->flags & TY_RIGID) == 0)
01390       return false;
01391   }
01392   return true;
01393 }

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