00001 #ifndef TYPE_HXX
00002 #define TYPE_HXX
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
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
00061
00062 enum TypeTag {
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
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
00151 };
00152
00153
00154
00155
00156
00157
00158
00159
00160 struct ArrLen {
00161 uint64_t len;
00162 ArrLen(uint64_t _len) {len = _len;}
00163
00164
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
00184 MARK_NONE = 0x0,
00185
00186
00187 MARK_PREDICATE = 0x0000001u,
00188
00189
00190
00191 MARK_GET_BARE_TYPE = 0x0000002u,
00192 MARK_GET_THE_TYPE = 0x0000004u,
00193
00194
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
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
00284
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;
00302
00303
00304
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
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 const unsigned long long uniqueID;
00335
00336
00337
00338 boost::shared_ptr<AST> defAst;
00339
00340
00341
00342
00343 boost::shared_ptr<AST> myContainer;
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 uint8_t minSignedRep;
00358 uint8_t minUnsignedRep;
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 boost::shared_ptr<ArrLen> arrLen;
00381
00382 LitValue litValue;
00383
00384 size_t Isize;
00385 TypeSet fnDeps;
00386
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
00395
00396
00397 MarkFlags mark;
00398 unsigned pMark;
00399 boost::shared_ptr<Type> sp;
00400 TypeFlags flags;
00401
00402
00403 Type(const TypeTag ttag);
00404
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
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
00441
00442
00443
00444
00445
00446 boost::shared_ptr<Type> getDCopy();
00447
00448 private:
00449 boost::shared_ptr<const Type> getTypePrim() const;
00450 boost::shared_ptr<Type> getTypePrim();
00451
00452
00453 boost::shared_ptr<Type> normalize_mut();
00454
00455
00456
00457
00458 void normalize_mbFull(boost::shared_ptr<Trail> trail=Trail::make());
00459
00460
00461
00462
00463
00464
00465 void normalize_const_inplace(boost::shared_ptr<Trail> trail=Trail::make());
00466
00467
00468
00469
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
00477 boost::shared_ptr<Type> getBareType();
00478
00479 boost::shared_ptr<Type> getTheType(bool mutableOK=false, bool maybeOK=false);
00480
00481
00482
00483 bool isUnion(bool ignMut=true);
00484 bool isUcon(bool ignMut=true);
00485 bool isUval(bool ignMut=true);
00486 bool isULeg(bool ignMut=true);
00487 bool isUType(bool ignMut=true);
00488 bool isMethod();
00489 bool isDecl();
00490 bool isException();
00491 bool isStruct();
00492 bool isArray();
00493 bool isVector();
00494 bool isObject();
00495 bool isTvar();
00496 bool isVariable();
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();
00509 bool isClosure();
00510 bool isImmutableRefType();
00511 bool isMutable();
00512 bool isMutType();
00513 bool isConst();
00514 bool isEffectivelyConst();
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();
00532
00533 size_t nBits();
00534 bool needsCaptureConversion();
00535
00536
00537
00538 bool isNonEscaping();
00539
00540
00541
00542
00543
00544
00545 bool isUnifiableVar(UnifyFlags uflags=UFLG_NO_FLAGS);
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 void markSignMbs(bool cppos=false);
00558
00559
00560
00561
00562
00563
00564
00565 void fixupFnTypes();
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 void fixupConstArguments(boost::shared_ptr<Trail> trail);
00576
00577
00578
00579 boost::shared_ptr<Type> getUnionType();
00580
00581 size_t size();
00582
00583
00584
00585 bool isDeepMut();
00586
00587 bool isDeepImmut();
00588
00589
00590 bool isConcretizable();
00591
00592
00593 bool isShallowConcretizable();
00594
00595
00596
00597
00598 void normalize(boost::shared_ptr<Trail> trail=Trail::make());
00599
00600
00601
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
00609
00610
00611
00612
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
00625 bool forcedUnify(boost::shared_ptr<Type> t, bool verbose=false,
00626 std::ostream &errStream=std::cerr);
00627
00628
00629 bool allTvarsRigid();
00630
00631
00632
00633
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
00640
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
00647
00648 bool boundInType(boost::shared_ptr<Type> tv);
00649
00650
00651
00652
00653 bool boundInGamma(boost::shared_ptr<const TSEnvironment > gamma);
00654
00655
00656
00657 void collectAllftvs( TypeSet &tvs);
00658
00659
00660
00661 void collectftvsWrtGamma( TypeSet& tvs,
00662 boost::shared_ptr<const TSEnvironment > gamma);
00663
00664
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
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
00682
00683
00684
00685
00686 bool fixMaybes(const TypeSet& ftvs, boost::shared_ptr<Trail> trail,
00687 bool clearAll);
00688
00689
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
00697 boost::shared_ptr<Type> maximizeMutability(boost::shared_ptr<Trail>
00698 trail=Trail::make());
00699
00700 boost::shared_ptr<Type> minimizeMutability(boost::shared_ptr<Trail>
00701 trail=Trail::make());
00702
00703
00704
00705
00706
00707 boost::shared_ptr<Type> minMutConstless(boost::shared_ptr<Trail>
00708 trail=Trail::make());
00709
00710
00711
00712
00713
00714
00715
00716
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
00731
00732
00733 bool
00734 propagateMutability(boost::shared_ptr<Trail> trail,
00735 const bool inMutable=false);
00736
00737
00738
00739 bool isMaxMutable();
00740 bool isMinMutable();
00741
00742
00743
00744
00745 bool determineCCC(boost::shared_ptr<Type> comp, bool inRefType=false);
00746
00747
00748 bool argCCOK(size_t argN);
00749
00750
00751
00752 bool argInConst(size_t argN);
00753
00754
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
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
00774 void PrettyPrint();
00775
00776
00777
00778
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
00787
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
00798 bool addFnDep(boost::shared_ptr<Type> tc);
00799
00800
00801
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
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
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
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
00882
00883
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