Type.hxx

Go to the documentation of this file.
00001 #ifndef TYPE_HXX
00002 #define TYPE_HXX
00003 
00004 /**************************************************************************
00005  *
00006  * Copyright (C) 2008, Johns Hopkins University.
00007  * Copyright (C) 2010, Jonathan S. Shapiro
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or
00011  * without modification, are permitted provided that the following
00012  * conditions are met:
00013  *
00014  *   - Redistributions of source code must contain the above 
00015  *     copyright notice, this list of conditions, and the following
00016  *     disclaimer. 
00017  *
00018  *   - Redistributions in binary form must reproduce the above
00019  *     copyright notice, this list of conditions, and the following
00020  *     disclaimer in the documentation and/or other materials 
00021  *     provided with the distribution.
00022  *
00023  *   - Neither the names of the copyright holders nor the names of any
00024  *     of any contributors may be used to endorse or promote products
00025  *     derived from this software without specific prior written
00026  *     permission. 
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00029  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00030  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00031  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00032  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00033  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00034  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00035  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00036  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00037  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00038  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039  *
00040  **************************************************************************/
00041 
00042 #include <stdlib.h>
00043 #include <dirent.h>
00044 #include <fstream>
00045 #include <iostream>
00046 #include <string>
00047 #include <set>
00048 #include <vector>
00049 
00050 #include <libsherpa/INOstream.hxx>
00051 #include <libsherpa/EnumSet.hxx>
00052 
00053 #include "AST.hxx"
00054 #include "debug.hxx"
00055 #include "TvPrinter.hxx"
00056 #include "Environment.hxx"
00057 #include "TypeInfer.hxx"
00058 #include "Trail.hxx"
00059 
00060 // Elements of the TypeTag enumeration have moved to types.def
00061 
00062 enum TypeTag { // What kind of type?
00063 #define DEFTYPE(nm,prim,csimp,atom,scalar,ref,impint,impfloat) ty_##nm,
00064 #include "types.def"
00065 };
00066 
00067 const char *TypeTagName(TypeTag tt);
00068 
00069 typedef long long TargetSWord;
00070 
00071 struct Type;
00072 struct TCConstraints;
00073 
00074 enum CompFlagValues {
00075   COMP_NO_FLAGS = 0u,
00076 
00078   COMP_UNIN_DISCM  = 0x01u,
00079 
00087   COMP_INVALID     = 0x02u,
00088 
00102   COMP_BYREF       = 0x04u,
00103 
00116   COMP_MAYBE_BYREF = 0x08u,
00117 };
00118 typedef sherpa::EnumSet<CompFlagValues> CompFlagSet;
00119 
00120 struct comp {
00121   std::string name;
00122   boost::shared_ptr<Type> typ;
00123   CompFlagSet flags;
00124 
00125   comp() {flags = COMP_NO_FLAGS;} 
00126   comp(boost::shared_ptr<Type> t, 
00127        CompFlagSet _flags = COMP_NO_FLAGS);
00128   comp(const std::string s, boost::shared_ptr<Type> t, 
00129        CompFlagSet _flags = COMP_NO_FLAGS);
00130 
00131   // Quasi-constructors
00132   static inline boost::shared_ptr<comp>
00133   make() {
00134     comp *tmp = new comp();
00135     return boost::shared_ptr<comp>(tmp);
00136   }
00137 
00138   static inline boost::shared_ptr<comp>
00139   make(boost::shared_ptr<Type> t, CompFlagSet _flags = COMP_NO_FLAGS) {
00140     comp *tmp = new comp(t, _flags);
00141     return boost::shared_ptr<comp>(tmp);
00142   }
00143 
00144   static inline boost::shared_ptr<comp>
00145   make(const std::string& s, 
00146        boost::shared_ptr<Type> t, CompFlagSet _flags = COMP_NO_FLAGS) {
00147     comp *tmp = new comp(s, t, _flags);
00148     return boost::shared_ptr<comp>(tmp);
00149   }
00150   //comp(const comp &c);
00151 };  
00152 
00153 // Array lengths can in some cases get unified even when their
00154 // containing type cannot. See the comment on the arrLen field in
00155 // class Type.
00156 //
00157 // This wrapper class was necessary for the early GCPtr
00158 // implementation. We could remove it now, but having a wrapper to
00159 // provide the make() function is useful.
00160 struct ArrLen {
00161   uint64_t  len;
00162   ArrLen(uint64_t _len) {len = _len;}
00163 
00164   // Quasi-constructor
00165   static inline boost::shared_ptr<ArrLen>
00166   make(uint64_t _len) {
00167     ArrLen *tmp = new ArrLen(_len);
00168     return boost::shared_ptr<ArrLen>(tmp);
00169   }
00170 };
00171 
00181 
00182 enum MarkFlagValues {
00183   // Base Mark
00184   MARK_NONE                     = 0x0,
00185 
00186   // Shared by many predicates over Types
00187   MARK_PREDICATE                = 0x0000001u,
00188 
00189   // Basic Functions: these functions are called by almost all
00190   // routines, and must never share flags with anything.
00191   MARK_GET_BARE_TYPE            = 0x0000002u,
00192   MARK_GET_THE_TYPE             = 0x0000004u,
00193   
00194   // Functions that do not change type structure
00195   MARK_SIZE                     = 0x0000008u,
00196   MARK_MANGLED_STRING           = 0x0000010u,
00197   MARK_EMIT_ARR_VEC_FN_TYPES    = 0x0000020u,
00198   MARK_CHECK_CONSTRAINTS        = 0x0000040u,
00199   MARK_CHECK_MUT_CONSISTENCY    = 0x0000080u,
00200   MARK_COLLECT_FTVS_WRT_GAMMA   = 0x0000100u,
00201   MARK_COLLECT_ALL_FTVS         = 0x0000200u,
00202   MARK_MAXIMIZE_MUTABILITY      = 0x0000400u,
00203   MARK_MINIMIZE_MUTABILITY      = 0x0000800u,
00204   MARK_MINIMIZE_DEEP_MUTABILITY = 0x0001000u,
00205   MARK_MIN_MUT_CONSTLESS        = 0x0002000u,
00206   MARK_NORMALIZE_CONST          = 0x0004000u,
00207 
00208   // Functions that affect type structure/contents
00209   MARK_SIGN_MBS                 = 0x0008000u,
00210   MARK_ADJ_MAYBE                = 0x0010000u,
00211   MARK_FIXUP_FN_TYPES           = 0x0020000u,
00212   MARK_PROPAGATE_MUTABILITY     = 0x0040000u,
00213   MARK_NORMALIZE_MBFULL         = 0x0080000u,
00214   MARK_NORMALIZE_CONST_INPLACE  = 0x0100000u,
00215   MARK_ENSURE_MINIMIZABILITY    = 0x0200000u,
00216 };
00217 typedef sherpa::EnumSet<MarkFlagValues> MarkFlags;
00218 
00219 
00221 enum TypeFlagValues {
00222   TY_NO_FLAGS     = 0x0,
00223 
00226   TY_CT_SUBSUMED  = 0x01u,
00228   TY_CT_SELF      = 0x02u,
00229   TY_RIGID        = 0x04u,
00237   TY_CCC          = 0x10u,
00240   TY_CLOS         = 0x20u,
00245   TY_COERCE       = 0x40u,
00254   TY_ARG_IN_CONST = 0x80u
00255 };
00256 typedef sherpa::EnumSet<TypeFlagValues> TypeFlags;
00257 
00258 enum PrintOptionValues {
00259   PO_NO_FLAGS     = 0x0,
00260 
00267   PO_NO_TRAVERSE  = 0x01u,
00268 
00273   PO_SHOW_LINKS  = 0x02u,
00274 
00279   PO_SHOW_FIELDS  = 0x04u,
00280 };
00281 typedef sherpa::EnumSet<PrintOptionValues> PrintOptions;
00282 
00283 // Specialization mask -- those flags which should NOT survive
00284 // specialization. 
00285 const TypeFlags TY_SP_MASK  =
00286   (TypeFlags(TY_CT_SELF) | TY_RIGID | TY_CCC | TY_CLOS | TY_COERCE | TY_ARG_IN_CONST);
00287 
00288 struct Type;
00289 
00290 typedef std::less<boost::shared_ptr<Type> > TypePtrLess;
00291 typedef std::set<boost::shared_ptr<Type>,
00292                  TypePtrLess > TypeSet;
00293 
00294 struct TypeScheme;
00295 
00296 struct Type : public boost::enable_shared_from_this<Type> {
00297   
00298   friend struct TypeScheme;
00299 
00300  private:  
00301   static unsigned long long typeCount; // To generate New Type Variables
00302   
00303   // Generator for unique Type record id's.
00304   // Use this ONLY in the constructor!
00305   static inline unsigned long long 
00306   genTypeID()
00307   {
00308     return ++typeCount;
00309   }
00310 
00311 public:
00312   TypeTag typeTag;
00313   
00318   boost::shared_ptr<Type> link;
00319   
00320   /* If this is the type node that is authoritative
00321      to answer to the link, it will be the last one, and 
00322      link will be NULL. If so, examine the details */
00323   
00324   // Depending on type, store a reference 
00325   // to the actual type. The following 3 fields should be in a union, 
00326   // but using a union makes the C++ constructor logic unhappy....
00327 
00328   // The unique type record ID is used both to name type records for 
00329   // printing purposes and also to provide unique alpha variable names.
00330   // Since every post-unified alpha variable is represented by a Type
00331   // structure, we re-use the uniqueID of the Type structure as the
00332   // unique alpha-renaming of the alpha variable.
00333 
00334   const unsigned long long uniqueID; // unique type record ID
00335 
00336   // defAST points to the AST of the defining occurrence. This field
00337   // is set for ty_struct*, ty_union*, tu_ucon, ty_exn
00338   boost::shared_ptr<AST> defAst;  // Defining occurrence (or declare)
00339 
00340   // If type is a union constructor, points to identifier AST of the
00341   // defining occurrence of the defunion.  If type is a type class
00342   // method type, points to the identifier AST of the typeclass.
00343   boost::shared_ptr<AST> myContainer;
00344 
00345   // Note that we use two different type tags, ty_int/ty_impint,
00346   // ty_float/ty_impfloat, to deal with whether the concrete type of a
00347   // literal has been successfully decided.
00348   //
00349   // The minXRep fields tell us the smallest number of bits that is
00350   // guaranteed to hold the given value according to whether the
00351   // result of the unification is signed or unsigned. For floating
00352   // point values, we use minSignedRep to describe the required
00353   // exponent size. In the integer cases, a value of "65" indicates
00354   // that the literal must be handled as an arbitrary precision
00355   // integer.
00356 
00357   uint8_t   minSignedRep;        // minimum signed representation size
00358   uint8_t   minUnsignedRep;        // minimum signed representation size
00359 
00360   // Array length is actually a type variable, which ultimnately
00361   // resolves to  singleton types. Strictly speaking, we must use type
00362   // variables here. Since we do not have singleton types or dependent
00363   // types over arrays, we have arrlen in the type record
00364   // itself. However, we still need a level of indirection because the
00365   // lengths must also be unified during unification [think of
00366   // unification calls such as 
00367   //     U(t1->minimizeMutability() == t2->mininmizeMutability()) ]
00368   // Implicitely, an indirection entry with `0' in it is a length
00369   // variable. Copy constructor and TypeSpecialize DO NOT copy this
00370   // variable deeply.  This "variable" is not subject to
00371   // generalization.  
00372   //
00373   // The use case here arises from copy compatibility. In particular,
00374   // given a copy between
00375   //       (array (mutable T) n)  ==~  (array T n)
00376   //
00377   // we need to unify the T and the n, but we cannot unify the overall
00378   // types, because they differ w.r.t. mutability.
00379   
00380   boost::shared_ptr<ArrLen> arrLen;        // Length in the case of an array type
00381   
00382   LitValue  litValue;                // for literal types
00383 
00384   size_t    Isize;                // size in fixint
00385   TypeSet   fnDeps;                // Functional Dependencies (for 
00386                                 //   Type classes only).
00387   
00388   std::vector<boost::shared_ptr<comp> > components;
00389   std::vector<boost::shared_ptr<Type> > typeArgs;  
00390 
00392   std::vector<boost::shared_ptr<comp> > methods;
00393     
00394   // Mark Flags:  used for Traversal
00395   // Used to prevent infinite recursion
00396   // while printing infinitely recursivetypes.
00397   MarkFlags mark;                // General traversal
00398   unsigned pMark;                // Type printer
00399   boost::shared_ptr<Type> sp;    // Type specializer.
00400   TypeFlags flags;               
00401 
00402   // Main (Base) Constructor
00403   Type(const TypeTag ttag);
00404   // Copy Constructor.
00405   Type(boost::shared_ptr<Type> t); 
00406   Type(const TypeTag ttag, boost::shared_ptr<Type> child);
00407   Type(const TypeTag ttag, boost::shared_ptr<Type> child1, boost::shared_ptr<Type> child2);
00408 
00409   // Quasi-constructors
00410   static inline boost::shared_ptr<Type>
00411   make(const TypeTag ttag)
00412   {
00413     Type *tmp = new Type(ttag);
00414     return boost::shared_ptr<Type>(tmp);
00415   }
00416 
00417   static inline boost::shared_ptr<Type>
00418   make(boost::shared_ptr<Type> t)
00419   {
00420     Type *tmp = new Type(t);
00421     return boost::shared_ptr<Type>(tmp);
00422   }
00423 
00424   static inline boost::shared_ptr<Type>
00425   make(const TypeTag ttag, boost::shared_ptr<Type> child)
00426   {
00427     Type *tmp = new Type(ttag, child);
00428     return boost::shared_ptr<Type>(tmp);
00429   }
00430 
00431   static inline boost::shared_ptr<Type>
00432   make(const TypeTag ttag,
00433        boost::shared_ptr<Type> child1, 
00434        boost::shared_ptr<Type> child2)
00435   {
00436     Type *tmp = new Type(ttag, child1, child2);
00437     return boost::shared_ptr<Type>(tmp);
00438   }
00439 
00440   // Makes a deep copy , but ** LINKS TVARS TO ORIGINAL ONES ** 
00441   // This function calls TypeSpecialize on a typeScheme with
00442   // no free variables.
00443   // This is different from the type_instance() in 
00444   // the typeScheme class in that this function makes a copy
00445   // of non-tvars, while type_instance() returns the original type.
00446   boost::shared_ptr<Type> getDCopy();
00447 
00448 private:
00449   boost::shared_ptr<const Type> getTypePrim() const;
00450   boost::shared_ptr<Type> getTypePrim();
00451   // Normalize Mutability Constructor Idempotence
00452   // (mutable (mutable t)) == (mutable t)
00453   boost::shared_ptr<Type> normalize_mut();
00454   
00455   // Normalize trivial forms of mbFull such as 
00456   // (copy-compat (mutable 'a) bool) to (mutable bool)
00457   // This normalization is done in-place.
00458   void normalize_mbFull(boost::shared_ptr<Trail> trail=Trail::make());
00459 
00460   // Inplace partial Const normalization
00461   // Normalize types such as (const bool) to bool inplace.
00462   // This const-reduction is ONLY DONE when a const constructor can be
00463   // dropped. It does not reduce (const ('a, 'b)) to 
00464   // ((const 'a), (const 'b))
00465   void normalize_const_inplace(boost::shared_ptr<Trail> trail=Trail::make());
00466 
00467   // Complete const normalization: Returns a new type where const only
00468   // wraps type variables or maybe types.
00469   // This is NOT an in-place normalization
00470   boost::shared_ptr<Type> normalize_const(const bool inConst=false);
00471   
00472 public:
00473   boost::shared_ptr<Type> getType();  
00474   boost::shared_ptr <const Type> getType() const;
00475   
00476   // Get the type without mutability / fix / maybe
00477   boost::shared_ptr<Type> getBareType();  
00478   // Get the type without some combinations of the above
00479   boost::shared_ptr<Type> getTheType(bool mutableOK=false, bool maybeOK=false);   
00480 
00481   // The only reason the following functions are not marked const is
00482   // that they call getType(), which uses the mark flag. 
00483   bool isUnion(bool ignMut=true); // 1. Union type.
00484   bool isUcon(bool ignMut=true);  // 2. Union Constructor.
00485   bool isUval(bool ignMut=true);  // 3. Constructed union value (includes zero arity ctrs).
00486   bool isULeg(bool ignMut=true);  // 2 or 3.
00487   bool isUType(bool ignMut=true); // 1, 2, or 3.
00488   bool isMethod(); // 1, 2, or 3.
00489   bool isDecl();
00490   bool isException();
00491   bool isStruct();
00492   bool isArray();
00493   bool isVector();
00494   bool isObject();
00495   bool isTvar();
00496   bool isVariable(); // Checks beyond mutability maybe-ness
00497   bool isAtomic();
00498   bool isSimpleTypeForC();
00499   bool isScalar();
00500   bool isRefType();
00501   bool isValType();
00502   bool isByrefType();
00503   bool isArrayByref();
00504   bool isIndexableType();
00505   bool isNullableType();
00506   bool isConstrainedToRefType(boost::shared_ptr<TCConstraints> tcc);
00507   bool isFnxn();
00508   bool isBaseConstType(); // Integers, floats, string, bool, unit, dummy.
00509   bool isClosure();
00510   bool isImmutableRefType();
00511   bool isMutable();  // (mutable T)
00512   bool isMutType();  // (mutable T) or (mutable 'a)|T
00513   bool isConst();    // (const T)
00514   bool isEffectivelyConst(); // T such that allwrapped within consts
00515   bool isMaybe();
00516   bool isMbFull();
00517   bool isMbTop();
00518   bool isConcrete();
00519   bool isPrimaryType();
00520   bool isPrimInt();
00521   bool isPrimFloat();
00522   void SetTvarsTo(boost::shared_ptr<Type> t);
00523   void SetTvarsToUnit();
00524   bool isInteger();
00525   bool isIntegral();
00526   bool isbool();
00527   bool isFloat();
00528   bool isTypeClass();
00529   bool isPcst();
00530   bool isOfInfiniteType();
00531   bool isConstReducible(); // (const T) is equivalent to minimizeMutability(T)
00532 
00533   size_t nBits();
00534   bool needsCaptureConversion();
00535 
00536   // Check if values of a type cannot be returned or be captured
00537   // Currently true only for array-by-ref
00538   bool isNonEscaping();
00539 
00540   // Test if the type is a variable that can be substituted with
00541   // another type. Tests if the type is a variable (mbFull or mbTop)
00542   // wherein the variable (possible within Var() component) is 
00543   // not marked RIGID, unless, fllags indicate that rigidity 
00544   // must be ignored.  
00545   bool isUnifiableVar(UnifyFlags uflags=UFLG_NO_FLAGS);
00546   
00547   // Mark significant MB-tvars.
00548   // Mb-Tvars that need not be preserved semantically are:
00549   //  (1) at a copy position of a function argument or return type.
00550   //  (2) at a copy-argument-position of typeclass argument.
00551   // (1) is detected automatically, for (2) pass cppos-true at start.
00552   // Actually what this does is an "unmark" on the TY_COERCE flag, not
00553   // a new mark. The idea is that only generalizable FTVs should be
00554   // marked this way. So, mark all generalizable TVs with TY_COERCE,
00555   // and this routine will unmark all those coercions that will alter
00556   // semantic meaning.
00557   void markSignMbs(bool cppos=false);
00558   
00559   // Due to the above normalization, instantiated function types will
00560   // not be of the proper template (always with maybe types in
00561   // argment/return position. This will be require fixup at
00562   // instantiation. Note that the types of non-generalizable functions
00563   // are not affected by this fixup as they will not be removed due to
00564   // normalization in the first place,
00565   void fixupFnTypes();
00566 
00567   // To ensure completeness of inference, bare type variables cannot
00568   // occur within a const meta-constructor. They must only occur
00569   // within mbFull types. However, this construction is not possible
00570   // during structure/union definitions since we cannot create extra
00571   // variables apart from those specified in the argument list. 
00572   // Therefore, at the time of instantiation, fix the above problem
00573   // with construction, and instantiate all variables occuring at
00574   // shallow-positions within a const meta-constructor to mbFull types.
00575   void fixupConstArguments(boost::shared_ptr<Trail> trail);
00576 
00577   /* Produce Type ty_union[rv] from ty_ucon[rv] or ty_uval[rv]
00578      ONLY typeArgs are polylated */
00579   boost::shared_ptr<Type> getUnionType();
00580     
00581   size_t size();
00582 
00583   /* Methods used in Equational Unification */
00584   // Is this type Mutable upto function boundary?
00585   bool isDeepMut();
00586   // Is the type known to be Immutable upto function boundary?
00587   bool isDeepImmut();
00588   // Does this type contain variables only within functions or on the
00589   // lhs of a maybe type?
00590   bool isConcretizable();
00591   // Does this type contain variables only within functions,
00592   // references or on the lhs of a maybe type?
00593   bool isShallowConcretizable();
00594 
00595   // Normalize a type in-place. The following normalizations are
00596   // currently performed: 
00597   // 1) Normalization of mbFull.
00598   void normalize(boost::shared_ptr<Trail> trail=Trail::make());
00599 
00600   /* Methods that can be used for various kinds of 
00601      comparisons between two types */
00602 
00603 private:  
00604   bool eql(boost::shared_ptr<Type> t, bool verbose, std::ostream &errStream,
00605            UnifyFlags uflags, bool keepSub,
00606            boost::shared_ptr<Trail> trail=Trail::make());
00607 public:
00608   // Returns true of the type `t' is structurally equal to `this'
00609   // under alpha renaming (and declarations unify with definitions)
00610   // 
00611   // The next function strictlyEquals removes the above two
00612   // restrictions. 
00613   bool equals(boost::shared_ptr<Type> t, bool verbose=false,
00614               std::ostream &errStream=std::cerr);
00615   bool defEqualsDecl(boost::shared_ptr<Type> t, bool verbose=false,
00616                      std::ostream &errStream=std::cerr);
00617   bool strictlyEquals(boost::shared_ptr<Type> t, bool verbose=false,
00618                       bool noAlphaRename=false,
00619                       std::ostream &errStream=std::cerr);  
00620   bool unifyWith(boost::shared_ptr<Type> t, bool verbose=false,
00621                  boost::shared_ptr<Trail> trail=Trail::make(),
00622                  std::ostream &errStream=std::cerr);
00623 
00624   // Unify Ignoring rigidity
00625   bool forcedUnify(boost::shared_ptr<Type> t, bool verbose=false,
00626                    std::ostream &errStream=std::cerr);
00627   
00628   // All Tvars are rigid?
00629   bool allTvarsRigid();
00630 
00631   // Equality under alpha renaming of all (including rigid)
00632   // variables. The following functions are the same as equals and
00633   // strictlyEquals except for the fact that they ignore rigidity.
00634   bool equalsA(boost::shared_ptr<Type> t, bool verbose=false,
00635                std::ostream &errStream=std::cerr);
00636   bool strictlyEqualsA(boost::shared_ptr<Type> t, bool verbose=false,
00637                        std::ostream &errStream=std::cerr);
00638   
00639   /* Test for copy compatibility 
00640      two versions based on inner function equal or equalsA? */
00641   bool copy_compatible(boost::shared_ptr<Type> t, bool verbose=false,
00642                            std::ostream &errStream=std::cerr);
00643   bool copy_compatibleA(boost::shared_ptr<Type> t, bool verbose=false,
00644                               std::ostream &errStream=std::cerr);
00645  
00646   /* Methods to support polymorphism */
00647   /* Is that Type variable contained in my type somewhere (deeply)? */
00648   bool boundInType(boost::shared_ptr<Type> tv);
00649   
00650   /* Is my type bound in the environment? Usually only used in the
00651      case of type variables to determine if it must be 
00652      generalized, or not */
00653   bool boundInGamma(boost::shared_ptr<const TSEnvironment > gamma);
00654   
00655   // Collect ALL ftvs regardless of gamma
00656   // This APPENDS TO the vector `tvs'. 
00657   void collectAllftvs(/* OUT */ TypeSet &tvs);
00658 
00659   // Collect the Free Type Variables in a type
00660   // that are unbound in gamma
00661   void collectftvsWrtGamma(/* OUT */ TypeSet& tvs,
00662                            boost::shared_ptr<const TSEnvironment > gamma);
00663 
00664   // Meta-polymorphism
00665   static boost::shared_ptr<Type> Kmono;
00666   static boost::shared_ptr<Type> Kpoly;
00667   
00668 private:
00669   boost::shared_ptr<Type> 
00670   TypeSpecializeReal(const std::vector<boost::shared_ptr<Type> >& ftvs,
00671                      std::vector<boost::shared_ptr<Type> >& nftvs);
00672   
00673   // Clear the sp (specialization) field of type records recursively.
00674   void clear_sp();
00675   
00676 public:
00677   boost::shared_ptr<Type> 
00678   TypeSpecialize(const std::vector<boost::shared_ptr<Type> >& ftvs,
00679                  std::vector<boost::shared_ptr<Type> >& nftvs);
00680 
00681   /* Methods to deal with mutability issues */
00682   // Fix all Maybe types surrounding type records containing a
00683   // polymorphic type variables, except in the case of those maybes
00684   // directly surrounding type variables, unless clearall is
00685   // mentioned. 
00686   bool fixMaybes(const TypeSet& ftvs, boost::shared_ptr<Trail> trail,
00687                  bool clearAll);
00688 
00689   // Wrapper for the above function with the clearAll flag set.
00690   void clearAllMaybes();
00691   
00692 public:
00693   void adjMaybe(boost::shared_ptr<Trail> trail, bool markedOnly=false,
00694                 bool minimize=false, bool adjFn=false);
00695   
00696   // Get the maximally-mutable, but copy-compatible type.
00697   boost::shared_ptr<Type> maximizeMutability(boost::shared_ptr<Trail>
00698                                              trail=Trail::make()); 
00699   // Get the minimally-mutable, but copy-compatible type.
00700   boost::shared_ptr<Type> minimizeMutability(boost::shared_ptr<Trail>
00701                                              trail=Trail::make()); 
00702 
00703   // Get the minimally-mutable version of this type, but interpret
00704   // const-meta-constructors at this step. This function is useful to
00705   // construct a maybe(full) type, since in 'a|p, p need not  
00706   // preserve const-ness.
00707   boost::shared_ptr<Type> minMutConstless(boost::shared_ptr<Trail> 
00708                                           trail=Trail::make());
00709   
00710   // Ensure that this type can be wrapped within a const type, that
00711   // is, all variables at shallow-positions are in a mbFull, so that
00712   // we do not lose completeness when we perform minimizeMutability()
00713   // If the markOnly flag is set, it only marks type variables that
00714   // must be instantiated to mbFull types (which can be done later). 
00715   // This marking is used to mark type arguments in structure/union
00716   // definitions that appear at copy-position within const. 
00717   void ensureMinimizability(boost::shared_ptr<Trail> trail, 
00718                             bool markOnly);
00719   
00720   boost::shared_ptr<Type>
00721   maximizeTopMutability(boost::shared_ptr<Trail> trail=Trail::make()); 
00722   boost::shared_ptr<Type>
00723   minimizeTopMutability(boost::shared_ptr<Trail> trail=Trail::make()); 
00724   boost::shared_ptr<Type>
00725   minimizeDeepMutability(boost::shared_ptr<Trail> trail=Trail::make());
00726 
00727 public:
00728   bool checkMutConsistency(bool inMut=false, bool inMbFull=false);
00729 
00730   // Propagate Mutability inwards for unboxed composite types.
00731   // This case might fail with an error if there is an inner immutable
00732   // type, for example (mutable (pair (int32 bool)))
00733   bool
00734   propagateMutability(boost::shared_ptr<Trail> trail, 
00735                       const bool inMutable=false); 
00736   
00737   
00738   // Check if maximally / minimally mutable
00739   bool isMaxMutable();
00740   bool isMinMutable();
00741   
00742   /* Determine Candidacy for Copy-Compatibility for type variables
00743      only, argument is a composite-type that is searched 
00744      to determine ccc-ness */  
00745   bool determineCCC(boost::shared_ptr<Type> comp, bool inRefType=false);
00746   
00747   // See if nth typeArg is a CCC based on the TY_CCC flag markings
00748   bool argCCOK(size_t argN);  
00749 
00750   // See if nth typeArg is within a const type based on the
00751   // TY_ARG_IN_CONST flag markings 
00752   bool argInConst(size_t argN);  
00753   
00754   /* Print a type into a string for interactive or debugging display. */
00755 protected:
00756   std::string 
00757   asBlockStringProducer(boost::shared_ptr<TvPrinter> tvP, 
00758                    PrintOptions options, bool parenWrap);
00759 public:
00760   std::string 
00761   asBlockString(boost::shared_ptr<TvPrinter> tvP = TvPrinter::make(), 
00762                 PrintOptions options = PO_NO_FLAGS);
00763 
00764   /* Print a type into a string for interactive or debugging display. */
00765   std::string 
00766   asSexprString(boost::shared_ptr<TvPrinter> tvP = TvPrinter::make(), 
00767                 PrintOptions options = PO_NO_FLAGS);
00768 
00769   std::string
00770   asString(boost::shared_ptr<TvPrinter> tvP = TvPrinter::make(), 
00771            PrintOptions options = PO_NO_FLAGS);
00772 
00773   // For use in GDB:
00774   void PrettyPrint();
00775 
00776   //  std::string 
00777   //  asString(boost::shared_ptr<TvPrinter> tvP = TvPrinter::make(), 
00778   //           bool traverse = true);
00779 
00780   void asXML(boost::shared_ptr<TvPrinter> tvP, sherpa::INOstream &out);
00781   std::string asXML(boost::shared_ptr<TvPrinter> tvP = TvPrinter::make());
00782   
00783   boost::shared_ptr<AST> 
00784   asAST(const sherpa::LexLoc &loc,
00785         boost::shared_ptr<TvPrinter> tvP = TvPrinter::make());
00786   // Ignore mutability, Ignore Top-level Mutability, or
00787   // Maximize mutability of type-args
00788   std::string mangledString(bool igMut=false, bool igTlMut=false,
00789                             bool maxArgMut=false);
00790 
00791   const char *typeTagName() const
00792   { return TypeTagName(typeTag); }
00793   static TypeTag LookupTypeTag(const std::string& nm);  
00794   static TypeTag getValTypeTag(TypeTag refTag);
00795   static TypeTag getRefTypeTag(TypeTag valTag);
00796 
00797   /* Typeclass special */
00798   bool addFnDep(boost::shared_ptr<Type> tc);
00799 
00800   /* PUBLIC Accessors (Conveniecnce Forms) */
00801   //Accessing Type Arguments and Components
00802   const boost::shared_ptr<Type> & TypeArg(size_t i) const
00803   {
00804     return typeArgs[i];
00805   }
00806   const boost::shared_ptr<comp> & Component(size_t i) const
00807   {
00808     return components[i];
00809   }
00810   boost::shared_ptr<Type> & TypeArg(size_t i)
00811   {
00812     return typeArgs[i];
00813   }
00814   boost::shared_ptr<comp> & Component(size_t i)
00815   {
00816     return components[i];
00817   }
00818   boost::shared_ptr<Type> & CompType(size_t i) const
00819   {
00820     return components[i]->typ;
00821   }
00822   std::string& CompName(size_t i) const
00823   {
00824     return components[i]->name;
00825   }
00826   CompFlagSet& CompFlags(size_t i) const
00827   {
00828     return components[i]->flags;
00829   }
00830   boost::shared_ptr<Type> & MethodType(size_t i) const
00831   {
00832     return methods[i]->typ;
00833   }
00834   std::string& MethodName(size_t i) const
00835   {
00836     return methods[i]->name;
00837   }
00838   CompFlagSet& MethodFlags(size_t i) const
00839   {
00840     return methods[i]->flags;
00841   }
00842   //Argument and return types of function-types
00843   boost::shared_ptr<Type> & Args() const
00844   {
00845     DEBUG(TYPE_ACC) assert(typeTag == ty_fn || typeTag == ty_tyfn || typeTag == ty_method);
00846     return CompType(0);
00847   }  
00848   boost::shared_ptr<Type> & Ret() const
00849   {
00850     DEBUG(TYPE_ACC) assert(typeTag == ty_fn || typeTag == ty_tyfn || typeTag == ty_method);
00851     return CompType(1);
00852   }  
00853   //The Inner type of Maybe-types
00854   boost::shared_ptr<Type> &Var() const
00855   {
00856     DEBUG(TYPE_ACC) assert(typeTag == ty_mbTop || typeTag == ty_mbFull);
00857     return CompType(0);
00858   }  
00859   boost::shared_ptr<Type> & Core() const
00860   {
00861     DEBUG(TYPE_ACC) assert(typeTag == ty_mbTop || typeTag == ty_mbFull);
00862     return CompType(1);
00863   }
00864   // The first component of an array/vector/mutable/ref type
00865   boost::shared_ptr<Type> & Base() const
00866   {
00867     DEBUG(TYPE_ACC) assert(typeTag == ty_mutable || 
00868                            typeTag == ty_const || 
00869                            typeTag == ty_byref || 
00870                            typeTag == ty_ref || 
00871                            typeTag == ty_array || 
00872                            typeTag == ty_vector);
00873     return CompType(0);
00874   }
00875 
00876   int operator<(const Type& rhs) const {
00877     return uniqueID < rhs.uniqueID;
00878   }
00879 };
00880 
00881 // Impose a canonical sort order on pointers to Type, so that
00882 // operations involving sets of Type pointers will procede in a
00883 // deterministic order
00884 static int operator<(const boost::shared_ptr<Type>& lhs, 
00885                      const boost::shared_ptr<Type>& rhs)
00886 {
00887   return (*lhs) < (*rhs);
00888 }
00889 
00890 inline
00891 std::ostream& operator<<(std::ostream& strm, Type& t)
00892 {
00893   strm << t.asString();
00894   return strm;
00895 }
00896 
00897 #endif /* TYPE_HXX */

Generated on Sat Feb 4 23:59:29 2012 for BitC Compiler by  doxygen 1.4.7