TypeMut.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 "UocInfo.hxx"
00050 #include "AST.hxx"
00051 #include "Type.hxx"
00052 #include "TypeInfer.hxx"
00053 #include "TypeScheme.hxx"
00054 #include "TypeMut.hxx"
00055 #include "Typeclass.hxx"
00056 #include "inter-pass.hxx"
00057 #include "Unify.hxx"
00058 #include "Options.hxx"
00059 
00060 using namespace boost;
00061 using namespace sherpa;
00062 using namespace std;
00063 
00064 
00065 /********************************************************************/
00066 /*
00067                         HANDLING MUTABILITY 
00068                         *******************
00069          The following are some implementation level Observations
00070               in implementing mutability rules in BitC. 
00071 
00072 1) When a type variable is introduced in an expression, it MUST have a
00073 maybe-wrapper around it. For example: 
00074 
00075 (define (f x y)
00076   (if #t x y)  
00077   x:int32
00078   y:(mutable int32))
00079 
00080   if x and y are just given the types 'a and 'b, then they are linked at
00081   the if expression, and subsequent steps will fail to type check.
00082 
00083   When a type variable is introduced to construct a type, this need
00084   not be true.
00085 
00086   Since:
00087     - when the use writes 'a, he means any type whether mutable or
00088       immutable, and 
00089     - we do not have an immutable type qualifier (yet),
00090    type variables are always given a maybe-wrapper at binding
00091    time. These are discarded at the let-boundary.
00092 
00093    There are 2 positions we can take on Type Variables:
00094    i) Maybe-types are a *part of the type-variuable itself*.
00095       Two type-variables with different maybe-wrappers are different
00096       types with copy-compatibility constraints. Therefore, they must
00097       always co-exist, even in the type-schemes.
00098 
00099    ii) May-be wrappers are actually a *part of the constraint*
00100        requiring copy-compatibility. Therefore, eventhough we need
00101        them while we are working (just like any other type), they need
00102        not exist in the type-scheme. While instantiating, they should
00103        be instantiated with maybe-wrappers.
00104 
00105 
00106 2) The following type-records should never have a maybe-wrapper:
00107       ty_fnarg, ty_letgather, ty_typeclass, ty_tyfn.
00108 
00109  
00110 3) All type expressions (except in the case of a type variable) are
00111    stand for their immutable versions, so, they are given a type
00112    without any wrapper.
00113  
00114 4) At top level, all monomorphic type variables are instantiated to
00115    dummy types.
00116 
00117  
00118 2) We perform exact Unification in the following circumstances:
00119   i) Type Qualification
00120   ii) Unification past a ref-boundary.
00121 
00122 
00123 3) We need to unify maybe-type-records even after contents have unified.
00124    Otherwise:
00125 
00126 (lambda (x:(vector 'a) y:(vector 'b))
00127   (== x y) ;; succeeds
00128   x:(vector int32)
00129   y:(vector (mutable int32))
00130   (== x y)  ;; fails
00131 )
00132    
00133 4) TypeSpecialize must return ``hints'' as is:
00134 
00135 -- Rationale: For something that is frozen at a let and put in the 
00136    environment, there is no maybeHint 
00137 -- Otherwise, we are workingon some type, and it is reasonable to 
00138    use the same hint. 
00139 
00140 5) Type-class constraints: 
00141    While the value-restriction requies that we clear maybe-wrappers on  
00142    types, this is not true for constraints. I think we can let the
00143    constraints have maybe-types (with undecided mutability status) even 
00144    on polymorphic types with no effect on soundness. This will give more
00145    expressiveness in cases like:
00146     
00147 (deftypeclass (CL 'a)
00148   MTD: (fn ((vector 'a)) ()))
00149 
00150 (define (p x) (MTD (vector x)))
00151 p: (CL (maybe-1 'a)) => (fn ('a) ())
00152 
00153    Then, an instance of (CL (mutable bool)) can satisfy use of p with
00154    bool. 
00155  
00156    This issue goes away if we require all arguments of a type-class to
00157    not have typ-level mutability, as opposed to only those used in
00158    copy-positions in methods.  
00159    
00160    However, Prof.Shapiro has suggested that we fix all maybes
00161    including those in constraints for now. 
00162 
00163 6) Whereas the type of definitions and declarations must ordinarily
00164    match exactly, if the definition in question is a function, the
00165    definition and declaration shall be deemed compatible if all the
00166    arguments return type of the definition and declaration are
00167    copy-compatible. 
00168 
00169 7) Implementation level issue: Since closure conversion introduces
00170    new Refs, copy-compatibility at letbindings must be adjusted to
00171    work beyond these refs.
00172                    
00173 8) getDCopy() on types actually does the right thing. It does not
00174    create duplicate maybe-records in the wrong places and create
00175    unwanted copy-compatibilities. This is because it ultimately calls
00176    TypeSpecialize, which not only links tvars to original ones, but
00177    also remembers the specialized type of a particular type record,
00178    and always returns the same thing. For this reason, it is
00179    imperative that TypeSpecialize be the **only** routine that
00180    duplicates type records deeply.
00181                                                                     */
00182 /********************************************************************/  
00183 
00184 /********************************************************************
00185          Operators for Minimizing/Maximizing Mutability
00186   [ Name of the operator in formalization document written in braces]
00187 
00188  *******************************************************************/
00189 
00190 
00191 /* Maximize Mutability at the top-most level [\blacktriangle] */
00192 shared_ptr<Type> 
00193 Type::maximizeTopMutability(shared_ptr<Trail> trail)
00194 {
00195   shared_ptr<Type> t = getType();
00196   shared_ptr<Type> rt = GC_NULL;
00197   
00198   switch(t->typeTag) {
00199     
00200   case ty_mbFull:    
00201   case ty_mbTop:    
00202     {
00203       rt = t->Core()->maximizeTopMutability(trail);
00204       break;
00205     }
00206 
00207   case ty_mutable:
00208     {
00209       rt = t->Base()->maximizeTopMutability(trail);
00210     }
00211 
00212   case ty_letGather:
00213     {
00214       assert(false);
00215       break;
00216     }
00217     
00218   default:
00219     {
00220       rt = Mutable(t->getDCopy());
00221       break;
00222     }
00223   }
00224 
00225   return rt;
00226 }
00227 
00228 /* Minimize Mutability at the top-most level [\blacktriangledown] */
00229 shared_ptr<Type> 
00230 Type::minimizeTopMutability(shared_ptr<Trail> trail)
00231 {
00232   shared_ptr<Type> t = getType();
00233   shared_ptr<Type> rt = GC_NULL;
00234   
00235   switch(t->typeTag) {
00236     
00237   case ty_mbFull:    
00238   case ty_mbTop:    
00239     {
00240       rt = t->Core()->minimizeTopMutability(trail);
00241       break;
00242     }
00243     
00244   case ty_mutable:
00245     {
00246       rt = t->Base()->minimizeTopMutability(trail);
00247       break;
00248     }
00249 
00250   case ty_letGather:
00251     {
00252       assert(false);
00253       break;
00254     }
00255         
00256   default:
00257     {
00258       rt = t;
00259       break;
00260     }
00261   }
00262   
00263   return rt;
00264 }
00265 
00266 /* Maximize Mutability up to copy boundary [\triangle] */
00267 shared_ptr<Type> 
00268 Type::maximizeMutability(shared_ptr<Trail> trail)
00269 {
00270   shared_ptr<Type> t = getType();
00271   shared_ptr<Type> rt = GC_NULL;
00272 
00273   if (t->mark & MARK_MAXIMIZE_MUTABILITY)
00274     return t;
00275   
00276   t->mark |= MARK_MAXIMIZE_MUTABILITY;  
00277   
00278   switch(t->typeTag) {
00279     
00280   case ty_mbFull:    
00281   case ty_mbTop:    
00282     {
00283       rt = t->Core()->maximizeMutability(trail);
00284       break;
00285     }
00286 
00287   case ty_mutable:
00288     {
00289       rt = t->Base()->maximizeMutability(trail);
00290       break;
00291     }
00292     
00293   case ty_array:
00294     {
00295       rt = t->getDCopy();
00296       rt->Base() = t->Base()->maximizeMutability(trail);
00297       rt = Mutable(rt);
00298       break;
00299     }
00300 
00301   case ty_structv:
00302   case ty_unionv: 
00303   case ty_uvalv: 
00304   case ty_uconv: 
00305     {
00306       rt = t->getDCopy();
00307       for (size_t i=0; i < rt->typeArgs.size(); i++) {
00308         shared_ptr<Type> arg = rt->TypeArg(i)->getType();
00309 
00310         if (rt->argCCOK(i)) {
00311           shared_ptr<Type> argMax =
00312             arg->maximizeMutability(trail)->getType(); 
00313           if (arg != argMax)
00314             trail->link(arg, argMax);
00315         }
00316       }
00317       
00318       rt = Mutable(rt);
00319       break;
00320     } 
00321     
00322   case ty_letGather:
00323     {
00324       rt = t->getDCopy();
00325       for (size_t i=0; i < t->components.size(); i++)
00326         rt->CompType(i) = t->CompType(i)->maximizeMutability(trail); 
00327       break;
00328     }
00329     
00330   default:
00331     {
00332       rt = Mutable(t->getDCopy());
00333       break;
00334     }
00335   }
00336   
00337   t->mark &= ~MARK_MAXIMIZE_MUTABILITY;
00338   return rt;
00339 }
00340 
00341 /* Minimize Mutability up to copy boundary [\triangledown] */
00342 shared_ptr<Type> 
00343 Type::minimizeMutability(shared_ptr<Trail> trail)
00344 {
00345   shared_ptr<Type> t = getType();
00346   shared_ptr<Type> rt = GC_NULL;
00347   
00348   if (t->mark & MARK_MINIMIZE_MUTABILITY)
00349     return t;
00350   
00351   t->mark |= MARK_MINIMIZE_MUTABILITY;  
00352   
00353   switch(t->typeTag) {
00354     
00355   case ty_mbFull:    
00356   case ty_mbTop:    
00357     {
00358       rt = t->Core()->minimizeMutability(trail);
00359       break;
00360     }
00361 
00362   case ty_mutable:
00363     {
00364       rt = t->Base()->minimizeMutability(trail);
00365       break;
00366     }
00367 
00368   case ty_array:
00369     {
00370       rt = Type::make(t);
00371       rt->Base() = t->Base()->minimizeMutability(trail);
00372       break;
00373     }
00374 
00375   case ty_structv:
00376   case ty_unionv: 
00377   case ty_uvalv: 
00378   case ty_uconv: 
00379     {
00380       rt = t->getDCopy();
00381       for (size_t i=0; i < rt->typeArgs.size(); i++) {
00382         shared_ptr<Type> arg = rt->TypeArg(i)->getType();
00383         if (rt->argCCOK(i)) {
00384           shared_ptr<Type> argMin =
00385             arg->minimizeMutability(trail)->getType(); 
00386           if (arg != argMin)
00387             trail->link(arg, argMin);
00388         }
00389       }
00390       break;
00391     }
00392 
00393   case ty_letGather:
00394     {
00395       rt = t->getDCopy();
00396       for (size_t i=0; i < t->components.size(); i++) 
00397         rt->CompType(i) = t->CompType(i)->minimizeMutability(trail);
00398       break;
00399     }
00400     
00401   default:
00402     {
00403       rt = t;
00404       break;
00405     }
00406   }
00407   
00408   t->mark &= ~MARK_MINIMIZE_MUTABILITY;
00409   return rt;
00410 }
00411 
00412 /* Minimize Mutability up to function boundary [\mathfrak{I}] */
00413 shared_ptr<Type> 
00414 Type::minimizeDeepMutability(shared_ptr<Trail> trail)
00415 {
00416   shared_ptr<Type> t = getType();
00417   shared_ptr<Type> rt = GC_NULL;
00418   
00419   if (t->mark & MARK_MINIMIZE_DEEP_MUTABILITY)
00420     return t;
00421   
00422   t->mark |= MARK_MINIMIZE_DEEP_MUTABILITY;  
00423   
00424   switch(t->typeTag) {
00425     
00426   case ty_mbFull:    
00427   case ty_mbTop:    
00428     {
00429       rt = t->Core()->minimizeDeepMutability(trail);
00430       break;
00431     }
00432 
00433   case ty_mutable:
00434     {
00435       rt = t->Base()->minimizeDeepMutability(trail);
00436       break;
00437     }
00438 
00439   case ty_ref:
00440   case ty_vector:
00441   case ty_array:
00442     {
00443       rt = Type::make(t);
00444       rt->Base() = t->Base()->minimizeDeepMutability(trail);
00445       break;
00446     }
00447 
00448   case ty_structv:
00449   case ty_unionv: 
00450   case ty_uvalv: 
00451   case ty_uconv: 
00452   case ty_structr:
00453   case ty_unionr: 
00454   case ty_uvalr: 
00455   case ty_uconr: 
00456     {
00457       rt = t->getDCopy();
00458       for (size_t i=0; i < rt->typeArgs.size(); i++) {
00459         shared_ptr<Type> arg = rt->TypeArg(i)->getType();
00460         shared_ptr<Type> argMin =
00461           arg->minimizeDeepMutability(trail)->getType(); 
00462         
00463         if (arg != argMin)
00464           trail->link(arg, argMin);
00465       }
00466       break;
00467     } 
00468     
00469   case ty_letGather:
00470     {
00471       rt = t->getDCopy();
00472       for (size_t i=0; i < t->components.size(); i++) {
00473         rt->CompType(i) =
00474           t->CompType(i)->minimizeDeepMutability(trail);
00475       }
00476       break;
00477     }
00478 
00479   default:
00480     {
00481       // Concrete types and function types enter this case
00482       rt = t;
00483       break;
00484     }
00485   }
00486   
00487   t->mark &= ~MARK_MINIMIZE_DEEP_MUTABILITY;
00488   return rt;
00489 }
00490 
00491 
00492 /* Get the minimally-mutable version of this type, but interpret
00493    const-meta-constructors at this step. This function is useful to
00494    construct a maybe(full) type, since in 'a|p, p need not  
00495    preserve const-ness. 
00496 
00497    This function is similar to [\triangledown], except for the
00498    handling  of const  */
00499 shared_ptr<Type> 
00500 Type::minMutConstless(shared_ptr<Trail> trail)
00501 {
00502   shared_ptr<Type> t = getType();
00503   shared_ptr<Type> rt = GC_NULL;
00504   
00505   if (t->mark & MARK_MIN_MUT_CONSTLESS)
00506     return t;
00507   
00508   t->mark |= MARK_MIN_MUT_CONSTLESS;  
00509   
00510   switch(t->typeTag) {
00511     
00512   case ty_mbFull:    
00513   case ty_mbTop:    
00514     {
00515       rt = t->Core()->minMutConstless(trail);
00516       break;
00517     }
00518 
00519   case ty_const:
00520   case ty_mutable:
00521     {
00522       rt = t->Base()->minMutConstless(trail);
00523       break;
00524     }
00525 
00526   case ty_array:
00527     {
00528       rt = Type::make(t);
00529       rt->Base() = t->Base()->minMutConstless(trail);
00530       break;
00531     }
00532 
00533   case ty_structv:
00534   case ty_unionv: 
00535   case ty_uvalv: 
00536   case ty_uconv: 
00537     {
00538       rt = t->getDCopy();
00539       for (size_t i=0; i < rt->typeArgs.size(); i++) {
00540         shared_ptr<Type> arg = rt->TypeArg(i)->getType();
00541         if (rt->argCCOK(i)) {
00542           shared_ptr<Type> argMin =
00543             arg->minMutConstless(trail)->getType(); 
00544           if (arg != argMin)
00545             trail->link(arg, argMin);
00546         }
00547       }
00548       break;
00549     }
00550 
00551   case ty_letGather:
00552     {
00553       rt = t->getDCopy();
00554       for (size_t i=0; i < t->components.size(); i++) 
00555         rt->CompType(i) = t->CompType(i)->minMutConstless(trail);
00556       break;
00557     }
00558     
00559   default:
00560     {
00561       rt = t;
00562       break;
00563     }
00564   }
00565   
00566   t->mark &= ~MARK_MIN_MUT_CONSTLESS;
00567   return rt;
00568 }
00569 
00570 
00571 
00572 /********************************************************************
00573       Mutability Propagation inwards for unboxed structures 
00574              and mutability consistency checking
00575  *******************************************************************/
00576 
00577 bool
00578 Type::checkMutConsistency(bool inMut, bool seenMut)
00579 {
00580   bool errFree = true;
00581   shared_ptr<Type> t = getType();
00582   
00583   if (t->mark & MARK_CHECK_MUT_CONSISTENCY)
00584     return errFree;
00585   
00586   t->mark |= MARK_CHECK_MUT_CONSISTENCY;
00587   
00588   switch(t->typeTag) {
00589   case ty_tvar:
00590     {
00591       // Should we enforce:  
00592       //CHKERR(errFree, !inMut || seenMut); ??
00593       break;
00594     }
00595 
00596   case ty_mbTop:
00597     {
00598       CHKERR(errFree, !inMut);
00599       CHKERR(errFree, t->Core()->checkMutConsistency(inMut, false));
00600       break;
00601     }
00602     
00603   case ty_mbFull:
00604     {
00605       shared_ptr<Type> var = t->Var()->getType();
00606       shared_ptr<Type> inner = t->Core()->getType();
00607     
00608       bool varMutable = var->isMutable();
00609     
00610       CHKERR(errFree, !inMut || varMutable);
00611     
00612       if(varMutable) {
00613         shared_ptr<Type> innerMax = inner->maximizeMutability();
00614         CHKERR(errFree, innerMax->checkMutConsistency(false, false));
00615       }
00616       else {
00617         CHKERR(errFree, inner->checkMutConsistency(false, false));
00618       }
00619       
00620       break;
00621     }
00622     
00623   case ty_mutable:
00624     {
00625       CHKERR(errFree, t->Base()->checkMutConsistency(true, true));
00626       break;
00627     }
00628     
00629   case ty_array:
00630     {
00631       CHKERR(errFree, !inMut || seenMut);
00632       CHKERR(errFree, t->Base()->checkMutConsistency(inMut, false)); 
00633       break;
00634     }
00635     
00636   case ty_structv:
00637     {
00638       CHKERR(errFree, !inMut || seenMut);
00639       for (size_t i=0; i < t->components.size(); i++) {
00640         shared_ptr<Type> component = t->CompType(i);
00641         CHKERR(errFree, component->checkMutConsistency(inMut, false));
00642       }
00643       break;
00644     }
00645 
00646   default:
00647     {
00648       CHKERR(errFree, !inMut || seenMut);
00649       for (size_t i=0; i < t->components.size(); i++) {
00650         shared_ptr<Type> component = t->CompType(i);
00651         CHKERR(errFree, component->checkMutConsistency(false, false));
00652       }
00653       break;
00654     }
00655   }
00656   
00657   t->mark &= ~MARK_CHECK_MUT_CONSISTENCY;
00658   return errFree;
00659 }
00660 
00661 /* Mutability Propagation [\mathbb{M}] */
00662 bool
00663 Type::propagateMutability(boost::shared_ptr<Trail> trail, 
00664                           const bool inMutable)
00665 {
00666   bool errFree = true;
00667   shared_ptr<Type> t = getType();
00668   
00669   if (t->mark & MARK_PROPAGATE_MUTABILITY)
00670     return errFree;
00671   
00672   t->mark |= MARK_PROPAGATE_MUTABILITY;  
00673   
00674   switch(t->typeTag) {
00675     
00676   case ty_tvar:
00677     {
00678       errFree = false;
00679       break;
00680     }
00681     
00682   case ty_mbTop:    
00683     {
00684       shared_ptr<Type> var = t->Var()->getType();
00685       shared_ptr<Type> inner = t->Core()->getType();
00686       if(!inner->isMutable())
00687         inner = Type::make(ty_mutable, inner);
00688       
00689       CHKERR(errFree, inner->propagateMutability(trail, false));
00690 
00691       if(errFree)
00692         trail->subst(var, inner);
00693 
00694       break;
00695     }
00696     
00697   case ty_mbFull:    
00698     {
00699       shared_ptr<Type> var = t->Var()->getType();
00700       shared_ptr<Type> inner = t->Core()->getType();
00701       
00702       if(!var->isMutable())
00703         trail->subst(var, Type::make(ty_mutable, newTvar()));
00704 
00705       CHKERR(errFree, t->checkMutConsistency());
00706       
00707       break;
00708     }
00709     
00710   case ty_mutable:
00711     {
00712       CHKERR(errFree, t->Base()->propagateMutability(trail, true));
00713       break;
00714     }
00715 
00716   case ty_array:
00717     {
00718       CHKERR(errFree, inMutable);
00719       CHKERR(errFree, t->Base()->propagateMutability(trail, false)); 
00720       break;
00721     }
00722     
00723   case ty_structv:
00724     {
00725       CHKERR(errFree, inMutable);
00726       for (size_t i=0; i < t->components.size(); i++) {
00727         shared_ptr<Type> component = t->CompType(i);
00728         CHKERR(errFree, component->propagateMutability(trail, false)); 
00729       }
00730       break;
00731     } 
00732     
00733   case ty_unionv: 
00734   case ty_uvalv: 
00735   case ty_uconv: 
00736     {
00737       CHKERR(errFree, inMutable);
00738       break;
00739     }
00740     
00741   case ty_letGather:
00742     {
00743       assert(false);
00744       break;
00745     }
00746     
00747     // concrete types, function type and reference types.
00748   default:
00749     {
00750       CHKERR(errFree, inMutable);
00751       break;
00752     }
00753   }
00754   
00755   t->mark &= ~MARK_PROPAGATE_MUTABILITY;
00756   return errFree;
00757 }
00758 
00759 /********************************************************************
00760                       Maybe normalization
00761  *******************************************************************/
00762 
00763 /* Normalize types such as 
00764    ((mutable 'a)|bool) to (mutable bool) [\mathfrac{M}] */
00765 void
00766 Type::normalize_mbFull(boost::shared_ptr<Trail> trail)
00767 {
00768   shared_ptr<Type> t = getType();
00769   
00770   if (t->mark & MARK_NORMALIZE_MBFULL)
00771     return;
00772   
00773   t->mark |= MARK_NORMALIZE_MBFULL;  
00774   
00775   switch(t->typeTag) {
00776   case ty_mbFull:    
00777     {
00778       shared_ptr<Type> var = t->Var()->getType();
00779       shared_ptr<Type> inner = t->Core()->getType();
00780       
00781       inner->normalize_mbFull(trail);
00782       
00783       if(var->isMutable() && inner->isShallowConcretizable())
00784         trail->subst(var->Base(), inner->maximizeMutability(trail));
00785       
00786       break;
00787     }
00788     
00789   default:
00790     {
00791       for (size_t i=0; i < t->components.size(); i++)
00792         t->CompType(i)->normalize_mbFull(trail);
00793       
00794       for (size_t i=0; i < t->typeArgs.size(); i++)
00795         t->TypeArg(i)->normalize_mbFull(trail);
00796       
00797       for (TypeSet::iterator itr = t->fnDeps.begin();
00798            itr != t->fnDeps.end(); ++itr)
00799         (*itr)->normalize_mbFull(trail);
00800       
00801       break;
00802     }
00803   }
00804   
00805   t->mark &= ~MARK_NORMALIZE_MBFULL;
00806   return;
00807 }
00808 
00809 /********************************************************************
00810                       Const handling
00811  *******************************************************************/
00812 
00813 /* Normalize types such as (const bool) to bool ONLY when thhe const
00814    wrapper can be completely removed. This is an in-place
00815    normalization operation [Functional version: \mahtcal{N}] */
00816 
00817 void
00818 Type::normalize_const_inplace(boost::shared_ptr<Trail> trail)
00819 {
00820   shared_ptr<Type> t = getType();
00821   
00822   if (t->mark & MARK_NORMALIZE_CONST_INPLACE)
00823     return;
00824   
00825   t->mark |= MARK_NORMALIZE_CONST_INPLACE;  
00826   
00827   for (size_t i=0; i < t->components.size(); i++)
00828     t->CompType(i)->normalize_const_inplace(trail);
00829   
00830   for (size_t i=0; i < t->typeArgs.size(); i++)
00831     t->TypeArg(i)->normalize_const_inplace(trail);
00832   
00833   for (TypeSet::iterator itr = t->fnDeps.begin();
00834        itr != t->fnDeps.end(); ++itr)
00835     (*itr)->normalize_const_inplace(trail);
00836 
00837   if((t->typeTag == ty_const) && t->Base()->isConstReducible())
00838     trail->link(t, t->Base()->minimizeMutability());
00839   
00840   t->mark &= ~MARK_NORMALIZE_CONST_INPLACE;
00841 }
00842 
00843 /* Complete const normalization: Reduce const to only appear on 
00844    type variables and constrained types [\mathbb{N}] */
00845 
00846 boost::shared_ptr<Type> 
00847 Type::normalize_const(const bool inConst)
00848 {
00849   shared_ptr<Type> t = getType();
00850   shared_ptr<Type> rt = GC_NULL;
00851   
00852   if (t->mark & MARK_NORMALIZE_CONST)
00853     return t;
00854   
00855   t->mark |= MARK_NORMALIZE_CONST;  
00856 
00857   switch(t->typeTag) {
00858     
00859   case ty_tvar:
00860     {
00861       rt = t->getDCopy();
00862       if(inConst)
00863         rt = Type::make(ty_const, rt);
00864       break;
00865     }
00866     
00867   case ty_mbTop:    
00868   case ty_mbFull:    
00869     {
00870       shared_ptr<Type> var = t->Var()->getType();
00871       shared_ptr<Type> inner = t->Core()->getType();
00872       
00873       rt = Type::make(t->typeTag, var->getDCopy(),
00874                       inner->normalize_const(false));
00875       
00876       if(inConst)
00877         rt = Type::make(ty_const, rt);
00878       
00879       break;
00880     }
00881     
00882   case ty_const:
00883     {
00884       rt = t->Base()->normalize_const(true);
00885       break;
00886     }
00887 
00888   case ty_mutable:
00889     {
00890       rt = t->Base()->normalize_const(inConst);
00891       if(!inConst) 
00892         rt = Type::make(ty_mutable, rt);
00893       break;
00894     }
00895 
00896   case ty_array:
00897     {
00898       rt = Type::make(ty_array, t->Base()->normalize_const(inConst));
00899       break;
00900     }
00901     
00902   case ty_structv:
00903   case ty_uvalv: 
00904   case ty_uconv: 
00905     {
00906       rt = t->getDCopy();
00907       for (size_t i=0; i < rt->components.size(); i++) {
00908         shared_ptr<Type> fld = rt->CompType(i);
00909         if(inConst) 
00910           fld = Type::make(ty_const, fld);
00911         rt->CompType(i) = fld->normalize_const(false);
00912       }
00913       break;
00914     }
00915     
00916   case ty_unionv: 
00917     {
00918       rt = t->getDCopy();
00919       for (size_t i=0; i < rt->components.size(); i++) {
00920         shared_ptr<Type> ctr = rt->CompType(i);
00921         rt->CompType(i) = ctr->normalize_const(inConst);
00922       }
00923       
00924       break;
00925     }
00926     
00927   case ty_letGather:
00928     {
00929       assert(false);
00930       break;
00931     }
00932     
00933     // concrete types, function type and reference types.
00934   default:
00935     {
00936       rt = t->getDCopy();
00937       break;
00938     }
00939   }
00940   
00941   t->mark &= ~MARK_NORMALIZE_CONST;
00942   return rt;
00943 }
00944 
00945 /* Ensure that this type can be wrapped within a const type, that is,
00946    all variables at copy-positions are in a mbFull, so that we do not
00947    lose completeness when we permirm minimizeMutability()  
00948 
00949    In the case of structure/union definitions,  we cannot unify
00950    arguments with maybe types at the time of definition to ensure
00951    wrapability by const. Therefore, we mark such arguments to be
00952    instantiated to maybe types at the time of instantiation. This flag
00953    is used by argInConst() predicate */
00954 
00955 void
00956 Type::ensureMinimizability(boost::shared_ptr<Trail> trail, 
00957                            bool markOnly)
00958 {
00959   shared_ptr<Type> t = getType();
00960   
00961   if (t->mark & MARK_ENSURE_MINIMIZABILITY)
00962     return;
00963   
00964   t->mark |= MARK_ENSURE_MINIMIZABILITY;  
00965   
00966   switch(t->typeTag) {
00967     
00968   case ty_tvar:
00969     if(markOnly)
00970       t->flags |= TY_ARG_IN_CONST;
00971     else
00972       trail->subst(t, MBF(newTvar()));
00973     break;
00974     
00975   case ty_mbTop:    
00976     {
00977       assert(!t->Core()->isTvar());
00978       t->Core()->ensureMinimizability(trail, markOnly);
00979       break;
00980     }
00981 
00982   case ty_mutable:
00983     {
00984       t->Base()->ensureMinimizability(trail, markOnly);
00985       break;
00986     }
00987     
00988   case ty_array:
00989     {
00990       t->Base()->ensureMinimizability(trail, markOnly);
00991       break;
00992     }
00993 
00994   case ty_structv:
00995   case ty_unionv: 
00996   case ty_uvalv: 
00997   case ty_uconv: 
00998     {
00999       for (size_t i=0; i < t->typeArgs.size(); i++) {
01000         shared_ptr<Type> arg = t->TypeArg(i)->getType();
01001         if (t->argCCOK(i)) 
01002           arg->ensureMinimizability(trail, markOnly);
01003       }
01004       break;
01005     }
01006 
01007   case ty_letGather:
01008     {
01009       for (size_t i=0; i < t->components.size(); i++) 
01010         t->CompType(i)->ensureMinimizability(trail, markOnly);
01011       break;
01012     }
01013     
01014   case ty_const:
01015   case ty_mbFull:    
01016   default:
01017     {
01018       break;
01019     }
01020   }
01021   
01022   t->mark &= ~MARK_ENSURE_MINIMIZABILITY;
01023 }
01024 
01025 /* Instantiate all variables occuring at shallow-positions in a
01026    composite data structure within a const meta-constructor 
01027    to mbFull types.
01028    
01029    To ensure completeness of inference, bare type variables cannot
01030    occur within a const meta-constructor. They must only occue
01031    within mbFull types. However, this construction is not possible
01032    during structure/union definitions since we cannot create extra
01033    variables apart from those specified in the argument list. 
01034    Therefore, at the time of instantiation, fix the above problem
01035    with construction, and */
01036 
01037 void 
01038 Type::fixupConstArguments(boost::shared_ptr<Trail> trail)
01039 {
01040   shared_ptr<Type> t = getType();
01041   assert(t->isStruct() || t->isUType());
01042   for (size_t i=0; i<t->typeArgs.size(); i++)
01043     if(t->argInConst(i))
01044       trail->subst(t->TypeArg(i), MBF(newTvar()));
01045 }
01046 
01047 
01048 /********************************************************************
01049   Structures special: determine whether type arguments occur purely
01050   at copy-compatible position, whether they occur within const, etc.
01051  *******************************************************************/
01052 
01053 // See if nth typeArg is a CCC based on the TY_CCC flag markings
01054 bool
01055 Type::argCCOK(size_t argN)
01056 {
01057   shared_ptr<Type> t = getType();
01058   assert(t->isValType());
01059   assert(argN < t->typeArgs.size());
01060   assert(t->defAst);
01061 
01062   // Be REALLY careful about bt. It is the type in the scheme.
01063   // NEVER unify it with anything.
01064   shared_ptr<Type> bt = t->defAst->symType;  
01065   if (bt->TypeArg(argN)->getType()->flags & TY_CCC)
01066     return true;
01067   else
01068     return false;
01069 }
01070 
01071 // See if nth typeArg is within a const type based on the
01072 // TY_ARG_IN_CONST flag markings 
01073 bool
01074 Type::argInConst(size_t argN)
01075 {
01076   shared_ptr<Type> t = getType();
01077   assert(argN < t->typeArgs.size());
01078   assert(t->defAst);
01079 
01080   // Be REALLY careful about bt. It is the type in the scheme.
01081   // NEVER unify it with anything.
01082   shared_ptr<Type> bt = t->defAst->symType;  
01083   if (bt->TypeArg(argN)->getType()->flags & TY_ARG_IN_CONST)
01084     return true;
01085   else
01086     return false;
01087 }
01088 
01089 
01090 /* Determine Candidacy for Copy-Compatibility For type variables only,
01091    argument is a composite-type that is searched to determine ccc-ness */ 
01092 
01093 bool
01094 Type::determineCCC(shared_ptr<Type> t, bool inRefType)
01095 { 
01096   if (shared_from_this() != getType())
01097     return getType()->determineCCC(t);
01098   
01099   t = t->getType();
01100 
01101   if (t->mark & MARK_PREDICATE)
01102     return true;
01103   
01104   t->mark |= MARK_PREDICATE;  
01105   bool cccOK = true;
01106   
01107   switch(t->typeTag) {
01108   case ty_tvar:                                       
01109     {
01110       if ((t == shared_from_this()) && (inRefType))
01111         cccOK = false;
01112       break;
01113     }
01114 
01115   case ty_typeclass:
01116   case ty_tyfn:
01117     {
01118       assert(false);
01119       break;
01120     }
01121 
01122   default:
01123     {
01124       for (size_t i=0; cccOK && (i<t->typeArgs.size()); i++) 
01125         cccOK = determineCCC(t->TypeArg(i), 
01126                              inRefType || t->isRefType() || 
01127                              (!t->argCCOK(i)));
01128       
01129       for (size_t i=0; cccOK && (i<t->components.size()); i++)
01130         cccOK = determineCCC(t->CompType(i), t->isRefType());
01131       
01132       // I think no need to process fnDeps here.
01133       break;
01134     }
01135   }
01136 
01137   t->mark &= ~MARK_PREDICATE;
01138   return cccOK;
01139 }
01140 
01141 
01142 /********************************************************************
01143                       Maybe Type coercion
01144  *******************************************************************/
01145 
01146 static void 
01147 coerceMaybe(shared_ptr<Type> t, shared_ptr<Trail> trail, 
01148             bool minimize)
01149 {
01150   //std::cerr << "Coercing: " << t->asString(Options::debugTvP)
01151   //            << " to ";
01152   
01153   shared_ptr<Type> core = t->Core()->getType();
01154   shared_ptr<Type> var = t->Var()->getType();
01155 
01156   if((t->typeTag == ty_mbFull) && var->isMutable()) {
01157     var = var->Base()->getType();
01158     core = core->maximizeMutability()->getType();
01159   }
01160   else {
01161     if (minimize && (t->typeTag == ty_mbFull))
01162       core = core->minimizeMutability()->getType();
01163     else
01164       core = core->minimizeTopMutability()->getType();
01165   }
01166   
01167   if (core->typeTag != ty_tvar)
01168     trail->subst(var, core);
01169   else
01170     trail->link(t, core);
01171 }
01172 
01173 void
01174 Type::adjMaybe(shared_ptr<Trail> trail, bool markedOnly, 
01175                bool minimize, bool adjFn) 
01176 {
01177   shared_ptr<Type> t = getType();
01178   
01179   if (t->mark & MARK_ADJ_MAYBE)
01180     return;
01181   
01182   t->mark |= MARK_ADJ_MAYBE;
01183     
01184   switch(t->typeTag) {
01185   case ty_mbFull:
01186     {
01187       t->Core()->adjMaybe(trail, markedOnly, minimize, adjFn);
01188       if (!markedOnly || (t->Var()->getType()->flags & TY_COERCE))
01189         coerceMaybe(t, trail, minimize);
01190       break;
01191     }
01192     
01193   case ty_mbTop:
01194     {
01195       t->Core()->adjMaybe(trail, markedOnly, minimize, adjFn);
01196       if (!markedOnly || (t->Var()->getType()->flags & TY_COERCE))
01197         coerceMaybe(t, trail, minimize);
01198       break;
01199     }
01200 
01201   case ty_fn:
01202     {
01203       if (!adjFn)
01204         break;
01205       // otherwise, fall through
01206     }
01207 
01208   default:
01209     {
01210       for (size_t i=0; i < t->typeArgs.size(); i++) 
01211         t->TypeArg(i)->adjMaybe(trail, markedOnly, minimize, adjFn);
01212       
01213       for (size_t i=0; i<t->components.size(); i++)
01214         t->CompType(i)->adjMaybe(trail, markedOnly, minimize, adjFn);
01215       
01216       for (TypeSet::iterator itr = t->fnDeps.begin();
01217           itr != t->fnDeps.end(); ++itr)
01218         (*itr)->adjMaybe(trail, markedOnly, minimize, adjFn);
01219       
01220       break;
01221     }
01222   }
01223   
01224   t->mark &= ~MARK_ADJ_MAYBE;
01225 }
01226 
01227 
01228 // Mark significant MB-tvars.
01229 // Mb-Tvars that need not be preserved semantically are:
01230 //  (1) at a copy position of a function argument or return type.
01231 //  (2) at a copy-argument-position of typeclass argument.
01232 // (1) is detected automatically, for (2) pass cppos-true at start.
01233 // Actually what this does is an "unmark" on the TY_COERCE flag, not
01234 // a new mark. The idea is that only generalizable FTVs should be
01235 // marked this way. So, mark all generalizable TVs with TY_COERCE,
01236 // and this routine will unmark all those coercions that will alter
01237 // semantic meaning.
01238 void 
01239 Type::markSignMbs(bool cppos)
01240 {
01241   shared_ptr<Type> t = getType();
01242   
01243   if (t->mark & MARK_SIGN_MBS)
01244     return;
01245   
01246   t->mark |= MARK_SIGN_MBS;  
01247   
01248   switch(t->typeTag) {
01249     
01250   case ty_tvar:
01251     {
01252       t->flags &= ~TY_COERCE;
01253       break;
01254     }
01255     
01256   case ty_mbFull:    
01257   case ty_mbTop:    
01258     {
01259       if (!cppos)
01260         t->Var()->markSignMbs(cppos);
01261       
01262       t->Core()->markSignMbs(cppos);
01263       break;
01264     }
01265 
01266   case ty_mutable:
01267   case ty_array:
01268     {
01269       t->Base()->markSignMbs(cppos);
01270       break;
01271     }
01272     
01273   case ty_vector:
01274   case ty_ref:
01275   case ty_byref:
01276   case ty_array_ref:
01277     {
01278       t->Base()->markSignMbs(false);
01279       break;
01280     }
01281 
01282   case ty_fn:
01283     {
01284       t->Args()->markSignMbs(true);
01285       t->Ret()->markSignMbs(true);
01286       break;
01287     }    
01288     
01289   case ty_fnarg:
01290     {
01291       for (size_t i=0; i < t->components.size(); i++)
01292         if(t->CompFlags(i) & COMP_BYREF)
01293           t->CompType(i)->markSignMbs(false);
01294         else
01295           t->CompType(i)->markSignMbs(true);
01296 
01297       break;
01298     }
01299     
01300   case ty_letGather:
01301     {
01302       for (size_t i=0; i < t->components.size(); i++)
01303         t->CompType(i)->markSignMbs(cppos);
01304       break;
01305     }
01306     
01307   case ty_structv:
01308   case ty_unionv: 
01309   case ty_uvalv: 
01310   case ty_uconv: 
01311     {
01312       for (size_t i=0; i < t->typeArgs.size(); i++) {
01313         shared_ptr<Type> arg = t->TypeArg(i)->getType();
01314         if (t->argCCOK(i))
01315           arg->markSignMbs(cppos);
01316         else
01317           arg->markSignMbs(false);
01318       }
01319       break;
01320     }
01321   case ty_structr:
01322   case ty_unionr: 
01323   case ty_uvalr: 
01324   case ty_uconr: 
01325     {
01326       for (size_t i=0; i < t->typeArgs.size(); i++) {
01327         shared_ptr<Type> arg = t->TypeArg(i)->getType();
01328         arg->markSignMbs(false);
01329       }
01330       break;
01331     }
01332     
01333   default:
01334     {
01335       break;
01336     }
01337   }
01338   
01339   t->mark &= ~MARK_SIGN_MBS;
01340   return;
01341 }
01342 
01343 void
01344 Type::fixupFnTypes()
01345 {
01346   shared_ptr<Type> t = getType();
01347   
01348   if (t->mark & MARK_FIXUP_FN_TYPES)
01349     return;
01350   
01351   t->mark |= MARK_FIXUP_FN_TYPES;
01352   
01353   switch(t->typeTag) {
01354     
01355   case ty_mbFull:    
01356   case ty_mbTop:    
01357     {
01358       t->Core()->fixupFnTypes();
01359       break;
01360     }
01361     
01362   case ty_mutable:
01363   case ty_array:
01364   case ty_vector:    
01365   case ty_ref:
01366   case ty_byref:
01367   case ty_array_ref:
01368     {
01369       t->Base()->fixupFnTypes();
01370       break;
01371     }
01372   
01373   case ty_fn:
01374     {
01375       t->Args()->fixupFnTypes();
01376       t->Ret()->fixupFnTypes();
01377       shared_ptr<Type> ret = t->Ret()->getType();
01378       if (ret->typeTag != ty_mbFull)
01379         t->Ret() = MBF(ret);
01380       break;
01381     }
01382 
01383   case ty_fnarg:
01384     {
01385       for (size_t i=0; i < t->components.size(); i++) {
01386         t->CompType(i)->fixupFnTypes();
01387         shared_ptr<Type> arg = t->CompType(i)->getType();
01388         if ((t->CompFlags(i) & COMP_BYREF) == 0) {
01389           if (arg->typeTag != ty_mbFull)
01390             t->CompType(i) = MBF(arg);
01391         }
01392       }
01393       
01394       break;
01395     }
01396   
01397   case ty_structv:
01398   case ty_unionv: 
01399   case ty_uvalv: 
01400   case ty_uconv: 
01401   case ty_structr:
01402   case ty_unionr: 
01403   case ty_uvalr: 
01404   case ty_uconr: 
01405     {
01406       for (size_t i=0; i < t->typeArgs.size(); i++)
01407         t->TypeArg(i)->fixupFnTypes();
01408       
01409       break;
01410     }
01411 
01412   case ty_letGather:
01413     {
01414       for (size_t i=0; i < t->components.size(); i++) 
01415         t->CompType(i)->fixupFnTypes();
01416       break;
01417     }
01418     
01419   default:
01420     {
01421       break;
01422     }
01423   }
01424   
01425   t->mark &= ~MARK_FIXUP_FN_TYPES;
01426 }

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