00001
00002
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 #include <assert.h>
00040 #include <stdint.h>
00041 #include <stdlib.h>
00042 #include <dirent.h>
00043 #include <fstream>
00044 #include <iostream>
00045 #include <string>
00046 #include <sstream>
00047
00048 #include <libsherpa/UExcept.hxx>
00049
00050 #include "Options.hxx"
00051 #include "UocInfo.hxx"
00052 #include "AST.hxx"
00053 #include "Type.hxx"
00054 #include "TypeInfer.hxx"
00055 #include "TypeScheme.hxx"
00056 #include "TypeMut.hxx"
00057 #include "Typeclass.hxx"
00058 #include "inter-pass.hxx"
00059 #include "Unify.hxx"
00060
00061 using namespace boost;
00062 using namespace sherpa;
00063 using namespace std;
00064
00065
00066
00067
00068 static string
00069 printName(shared_ptr<AST> ast)
00070 {
00071 if (!ast)
00072 return "NULL";
00073
00074 return ast->s;
00075 }
00076
00077 string
00078 Type::asSexprString(shared_ptr<TvPrinter> tvP, PrintOptions options)
00079 {
00080 stringstream ss;
00081
00082 if (options & PO_SHOW_LINKS)
00083 options |= PO_NO_TRAVERSE;
00084
00085 if (Options::rawTvars)
00086 tvP = GC_NULL;
00087
00088 shared_ptr<Type> t =
00089 (options & PO_NO_TRAVERSE) ? shared_from_this() : getType();
00090
00091
00092
00093
00094 if (t->pMark >= 2)
00095 return " ... ";
00096 else
00097 t->pMark++;
00098
00099
00100 if (options & PO_SHOW_LINKS) {
00101 shared_ptr<Type> t1 = shared_from_this();
00102 ss << "[";
00103 while (t1->link) {
00104 ss << "'a" << t1->uniqueID;
00105 ss << "->";
00106 t1 = t1->link;
00107 }
00108 ss << "'a" << t1->uniqueID;
00109 ss << "]";
00110 }
00111
00112 switch(t->typeTag) {
00113 case ty_tvar:
00114 if (!tvP) {
00115 ss << "'a" << t->uniqueID;
00116 if (t->flags & TY_RIGID)
00117 ss << 'R';
00118 }
00119 else {
00120 ss << tvP->tvName(t);
00121 }
00122
00123 break;
00124
00125 case ty_kvar:
00126 ss << "'K" << t->uniqueID;
00127 break;
00128
00129 case ty_dummy:
00130 ss << "#DUMMY#";
00131 break;
00132
00133 case ty_unit:
00134 ss << "()";
00135 break;
00136
00137 case ty_bool:
00138 case ty_char:
00139 case ty_string:
00140 case ty_int8:
00141 case ty_int16:
00142 case ty_int32:
00143 case ty_int64:
00144 case ty_uint8:
00145 case ty_uint16:
00146 case ty_uint32:
00147 case ty_uint64:
00148 case ty_word:
00149 case ty_float:
00150 case ty_double:
00151 case ty_quad:
00152 ss << t->typeTagName();
00153 break;
00154
00155 case ty_field:
00156 ss << t->litValue.s;
00157 break;
00158
00159 #ifdef KEEP_BF
00160 case ty_bitfield:
00161 ss << "(bitfield "
00162 << t->CompType(0)->toString()
00163 << " "
00164 << t->Isize
00165 << ")";
00166 break;
00167 #endif
00168
00169 case ty_method:
00170 assert(t->components.size() == 2);
00171 ss << "(method " << t->Args()->asSexprString(tvP, options)
00172 << " -> " << t->Ret()->asSexprString(tvP, options) << ")";
00173 break;
00174
00175 case ty_fn:
00176 assert(t->components.size() == 2);
00177 ss << "(fn " << t->Args()->asSexprString(tvP, options)
00178 << " -> " << t->Ret()->asSexprString(tvP, options) << ")";
00179 break;
00180
00181 case ty_fnarg:
00182 for (size_t i=0; i < t->components.size(); i++) {
00183 if (i > 0) ss << " ";
00184 if (t->CompFlags(i) & COMP_BYREF)
00185 ss << "(ByRef " << t->CompType(i)->asSexprString(tvP, options)
00186 << ")";
00187 else
00188 ss << t->CompType(i)->asSexprString(tvP, options);
00189 }
00190 break;
00191
00192 case ty_tyfn:
00193 assert(t->components.size() == 2);
00194 ss << "(tyfn " << t->Args()->asSexprString(tvP, options)
00195 << " -> " << t->Ret()->asSexprString(tvP, options) << ")";
00196 break;
00197
00198 case ty_letGather:
00199 ss << "(__letGather ";
00200 for (size_t i=0; i < t->components.size(); i++) {
00201 if (i > 0) ss << " ";
00202 ss << t->CompType(i)->asSexprString(tvP, options);
00203 }
00204 ss << ")";
00205
00206 break;
00207
00208 case ty_structv:
00209 case ty_structr:
00210 {
00211
00212
00213
00214 if (options & PO_SHOW_FIELDS) {
00215 ss << "(" << ((t->typeTag == ty_structr) ? "struct " : "structR ")
00216 << printName(t->defAst) << " - ";
00217 for (size_t i=0; i<components.size(); i++)
00218 ss << CompName(i) << ":"
00219 << CompType(i)->asSexprString(tvP, options) << " ";
00220 ss << ")";
00221 }
00222 else {
00223 if (t->typeArgs.size() == 0)
00224 ss << printName(t->defAst);
00225 else {
00226 ss << "(" << printName(t->defAst);
00227 for (size_t i=0; i < t->typeArgs.size(); i++)
00228 ss << " " << t->TypeArg(i)->asSexprString(tvP, options);
00229 ss << ")";
00230 }
00231 }
00232
00233 break;
00234 }
00235
00236 case ty_unionv:
00237 case ty_unionr:
00238 case ty_uvalv:
00239 case ty_uvalr:
00240 case ty_uconv:
00241 case ty_uconr:
00242
00243
00244
00245 if (options & PO_SHOW_FIELDS) {
00246 const char *dbName;
00247 switch(t->typeTag) {
00248 case ty_unionv:
00249 dbName = "union";
00250 break;
00251 case ty_unionr:
00252 dbName = "unionR";
00253 break;
00254 case ty_uvalv:
00255 dbName = "union-val";
00256 break;
00257 case ty_uvalr:
00258 dbName = "unionR-val";
00259 break;
00260 case ty_uconv:
00261 dbName = "union-con";
00262 break;
00263 case ty_uconr:
00264 dbName = "unionR-con";
00265 break;
00266 }
00267 ss << "(" << dbName << " " << printName(t->defAst);
00268 for (size_t i=0; i<typeArgs.size(); i++)
00269 ss << TypeArg(i)->getType()->asSexprString(tvP, options);
00270 ss << ") [";
00271 for (size_t i=0; i<components.size(); i++)
00272 ss << CompName(i) << ":"
00273 << CompType(i)->getType()->asSexprString(tvP, options);
00274 ss << "]";
00275 }
00276 else {
00277 if (t->typeArgs.size() == 0)
00278 ss << printName(t->myContainer);
00279 else {
00280 ss << "(" << printName(t->myContainer);
00281 for (size_t i=0; i < t->typeArgs.size(); i++)
00282 ss << " " << t->TypeArg(i)->asSexprString(tvP, options);
00283 ss << ")";
00284 }
00285 }
00286
00287 break;
00288
00289 case ty_typeclass:
00290
00291
00292
00293 if (options & PO_SHOW_FIELDS) {
00294 ss << "(Typeclass " << printName(t->defAst);
00295 for (size_t i=0; i < typeArgs.size(); i++)
00296 ss << " " << TypeArg(i)->asSexprString(tvP, options);
00297 ss << ")";
00298 }
00299 else {
00300 if (t->typeArgs.size() == 0)
00301 ss << printName(t->defAst);
00302 else {
00303 ss << "(" << printName(t->defAst);
00304 for (size_t i=0; i < t->typeArgs.size(); i++)
00305 ss << " " << t->TypeArg(i)->asSexprString(tvP, options);
00306 ss << ")";
00307 }
00308 }
00309 break;
00310
00311 case ty_array:
00312 ss << "(array " << t->Base()->asSexprString(tvP, options)
00313 << " " << t->arrLen->len << ")";
00314 break;
00315
00316 case ty_vector:
00317 ss << "(vector " << t->Base()->asSexprString(tvP, options) << ")";
00318 break;
00319
00320 case ty_ref:
00321 ss << "(ref " << t->Base()->asSexprString(tvP, options) << ")";
00322 break;
00323
00324 case ty_byref:
00325 ss << "(ByRef " << t->Base()->asSexprString(tvP, options) << ")";
00326 break;
00327
00328 case ty_array_ref:
00329 ss << "(ArrayRef " << t->Base()->asSexprString(tvP, options) << ")";
00330 break;
00331
00332 case ty_mbFull:
00333 case ty_mbTop:
00334 ss << t->Var()->asSexprString(tvP, options)
00335 << ((t->typeTag == ty_mbFull) ? "|" : "!")
00336 << ((t->Core()->typeTag == ty_fn)?"(":"")
00337 << t->Core()->asSexprString(tvP, options)
00338 << ((t->Core()->typeTag == ty_fn)?")":"");
00339 break;
00340
00341 case ty_mutable:
00342 ss << "(mutable " << t->Base()->asSexprString(tvP, options) << ")";
00343 break;
00344
00345 case ty_const:
00346 ss << "(const " << t->Base()->asSexprString(tvP, options) << ")";
00347 break;
00348
00349 case ty_exn:
00350 ss << "exception";
00351 break;
00352
00353 case ty_pcst:
00354 {
00355 ss << "*(";
00356 for (size_t i=0; i<t->components.size(); i++) {
00357 if (i > 0)
00358 ss << ", ";
00359 ss << t->CompType(i)->asSexprString(tvP, options);
00360 }
00361 ss << ")";
00362 break;
00363 }
00364
00365 case ty_kfix:
00366 {
00367 if (t == Type::Kmono)
00368 ss << "m";
00369 else if (t == Type::Kpoly)
00370 ss << "P";
00371 else
00372 assert(false);
00373 break;
00374 }
00375
00376 }
00377
00378 t->pMark--;
00379 return ss.str();
00380 }
00381
00382 string
00383 Type::asBlockString(shared_ptr<TvPrinter> tvP, PrintOptions options)
00384 {
00385 return " block type disabled ";
00386 return asBlockStringProducer(tvP, options, false);
00387 }
00388
00389 string
00390 Type::asString(shared_ptr<TvPrinter> tvP, PrintOptions options)
00391 {
00392 return asSexprString(tvP, options);
00393 }
00394
00395 void
00396 Type::PrettyPrint()
00397 {
00398 std::cerr << asString();
00399 std::cerr << std::endl;
00400 }
00401
00402
00403
00404 static int typePrecedence(TypeTag ttag)
00405 {
00406 switch(ttag) {
00407 case ty_fn:
00408 case ty_tyfn:
00409 case ty_method:
00410 return 3;
00411
00412 case ty_array:
00413 case ty_vector:
00414 case ty_ref:
00415 return 2;
00416
00417 case ty_mutable:
00418 case ty_const:
00419 return 1;
00420
00421 default:
00422 return 0;
00423 }
00424 }
00425
00426 static bool shouldParenWrap(TypeTag parent, TypeTag child)
00427 {
00428 return typePrecedence(parent) < typePrecedence(child);
00429
00430 }
00431
00432 string
00433 Type::asBlockStringProducer(shared_ptr<TvPrinter> tvP, PrintOptions options,
00434 bool parenWrap)
00435 {
00436 stringstream ss;
00437
00438 if (options & PO_SHOW_LINKS)
00439 options |= PO_NO_TRAVERSE;
00440
00441 if (Options::rawTvars)
00442 tvP = GC_NULL;
00443
00444 shared_ptr<Type> t =
00445 (options & PO_NO_TRAVERSE) ? shared_from_this() : getType();
00446
00447
00448
00449
00450 if (t->pMark >= 2)
00451 return " ... ";
00452 else
00453 t->pMark++;
00454
00455 if (parenWrap) ss << '(';
00456
00457
00458 if (options & PO_SHOW_LINKS) {
00459 shared_ptr<Type> t1 = shared_from_this();
00460 ss << "[";
00461 while (t1->link) {
00462 ss << "'a" << t1->uniqueID;
00463 ss << "->";
00464 t1 = t1->link;
00465 }
00466 ss << "'a" << t1->uniqueID;
00467 ss << "]";
00468 }
00469
00470 switch(t->typeTag) {
00471 case ty_tvar:
00472 if (!tvP) {
00473 ss << "'a" << t->uniqueID;
00474 if (t->flags & TY_RIGID)
00475 ss << 'R';
00476 }
00477 else {
00478 ss << tvP->tvName(t);
00479 }
00480
00481 break;
00482
00483 case ty_kvar:
00484 ss << "'K" << t->uniqueID;
00485 break;
00486
00487 case ty_dummy:
00488 ss << "#DUMMY#";
00489 break;
00490
00491 case ty_unit:
00492 ss << "()";
00493 break;
00494
00495 case ty_bool:
00496 case ty_char:
00497 case ty_string:
00498 case ty_int8:
00499 case ty_int16:
00500 case ty_int32:
00501 case ty_int64:
00502 case ty_uint8:
00503 case ty_uint16:
00504 case ty_uint32:
00505 case ty_uint64:
00506 case ty_word:
00507 case ty_float:
00508 case ty_double:
00509 case ty_quad:
00510 ss << t->typeTagName();
00511 break;
00512
00513 case ty_field:
00514 ss << t->litValue.s;
00515 break;
00516
00517 #ifdef KEEP_BF
00518 case ty_bitfield:
00519 ss << t->CompType(0)->toString()
00520 << "("
00521 << t->Isize
00522 << ")";
00523 break;
00524 #endif
00525
00526 case ty_method:
00527 assert(t->components.size() == 2);
00528 ss << "method (" << t->Args()->asBlockStringProducer(tvP, options, false)
00529 << ") -> " << t->Ret()->asBlockStringProducer(tvP, options, false);
00530 break;
00531
00532 case ty_fn:
00533
00534
00535
00536 assert(t->components.size() == 2);
00537 ss << "fn (" << t->Args()->asBlockStringProducer(tvP, options, false)
00538 << ") -> " << t->Ret()->asBlockStringProducer(tvP, options, false);
00539 break;
00540
00541 case ty_fnarg:
00542
00543
00544 for (size_t i=0; i < t->components.size(); i++) {
00545 if (i > 0) ss << ", ";
00546 if (t->CompFlags(i) & COMP_BYREF)
00547 ss << "ByRef " << t->CompType(i)->asBlockStringProducer(tvP, options, false)
00548 << "";
00549 else
00550 ss << t->CompType(i)->asBlockStringProducer(tvP, options, false);
00551 }
00552 break;
00553
00554 case ty_tyfn:
00555
00556 assert(t->components.size() == 2);
00557 ss << "tyfn (" << t->Args()->asBlockStringProducer(tvP, options, false)
00558 << ", -> " << t->Ret()->asBlockStringProducer(tvP, options, false);
00559 break;
00560
00561 case ty_letGather:
00562
00563 ss << "(__letGather ";
00564 for (size_t i=0; i < t->components.size(); i++) {
00565 shared_ptr<Type> compType = t->CompType(i);
00566
00567 if (i > 0) ss << " ";
00568 ss << compType->asBlockStringProducer(tvP, options, shouldParenWrap(t->typeTag, compType->typeTag));
00569
00570 }
00571 ss << ")";
00572
00573 break;
00574
00575 case ty_structv:
00576 case ty_structr:
00577 {
00578
00579
00580 ss << printName(t->defAst);
00581 if (t->typeTag == ty_structr) ss << '^';
00582
00583 if (t->typeArgs.size() > 0) {
00584 ss << '(';
00585 for (size_t i=0; i < t->typeArgs.size(); i++) {
00586 if (i > 0) ss << ", ";
00587 ss << t->TypeArg(i)->asBlockStringProducer(tvP, options, false);
00588 }
00589 ss << ')';
00590 }
00591
00592 if (options & PO_SHOW_FIELDS) {
00593 ss << "{ ";
00594 for (size_t i=0; i<components.size(); i++)
00595 ss << CompName(i) << ":"
00596 << CompType(i)->asBlockStringProducer(tvP, options, false) << "; ";
00597 ss << "}";
00598 }
00599
00600 break;
00601 }
00602
00603 case ty_unionv:
00604 case ty_unionr:
00605 case ty_uvalv:
00606 case ty_uvalr:
00607 case ty_uconv:
00608 case ty_uconr:
00609 {
00610
00611
00612 ss << printName(t->myContainer);
00613 if ((t->typeTag == ty_unionr) ||
00614 (t->typeTag == ty_uvalr) ||
00615 (t->typeTag == ty_uconr))
00616 ss << '^';
00617
00618 if (t->typeArgs.size() > 0) {
00619 ss << '(';
00620 for (size_t i=0; i < t->typeArgs.size(); i++) {
00621 if (i > 0) ss << ", ";
00622 ss << t->TypeArg(i)->asBlockStringProducer(tvP, options, false);
00623 }
00624 ss << ")";
00625 }
00626
00627 if (options & PO_SHOW_FIELDS) {
00628 const char *dbName;
00629 switch(t->typeTag) {
00630 case ty_unionv:
00631 dbName = "union";
00632 break;
00633 case ty_unionr:
00634 dbName = "union^";
00635 break;
00636 case ty_uvalv:
00637 dbName = "union-val";
00638 break;
00639 case ty_uvalr:
00640 dbName = "union^-val";
00641 break;
00642 case ty_uconv:
00643 dbName = "union-con";
00644 break;
00645 case ty_uconr:
00646 dbName = "union^-con";
00647 break;
00648 }
00649
00650 ss << dbName << "{ ";
00651 for (size_t i=0; i<components.size(); i++)
00652 ss << CompName(i) << ":"
00653 << CompType(i)->getType()->asBlockStringProducer(tvP, options, false)
00654 << "; ";
00655 ss << "}";
00656 }
00657 break;
00658 }
00659 case ty_typeclass:
00660 {
00661
00662
00663 ss << printName(t->defAst);
00664 if (t->typeArgs.size() != 0) {
00665 ss << "(";
00666 for (size_t i=0; i < t->typeArgs.size(); i++) {
00667 if (i > 0) ss << ", ";
00668 ss << t->TypeArg(i)->asBlockStringProducer(tvP, options, false);
00669 }
00670 ss << ")";
00671 }
00672
00673 break;
00674 }
00675
00676 case ty_array:
00677 {
00678 shared_ptr<Type> base = t->Base();
00679 bool wrap = shouldParenWrap(t->typeTag, base->typeTag);
00680
00681 ss << base->asBlockStringProducer(tvP, options, wrap);
00682 ss << '[' << t->arrLen->len << "]";
00683 break;
00684 }
00685
00686 case ty_vector:
00687 {
00688 shared_ptr<Type> base = t->Base();
00689 bool wrap = shouldParenWrap(t->typeTag, base->typeTag);
00690
00691 ss << base->asBlockStringProducer(tvP, options, wrap);
00692 ss << "[]";
00693 break;
00694 }
00695
00696 case ty_ref:
00697 {
00698 shared_ptr<Type> base = t->Base();
00699 bool wrap = shouldParenWrap(t->typeTag, base->typeTag);
00700
00701 ss << base->asBlockStringProducer(tvP, options, wrap);
00702 ss << " reference";
00703 break;
00704 }
00705 break;
00706
00707 case ty_byref:
00708
00709 ss << "ByRef " << t->Base()->asBlockStringProducer(tvP, options, false);
00710 break;
00711
00712 case ty_array_ref:
00713
00714 ss << "ArrayRef " << t->Base()->asBlockStringProducer(tvP, options, false);
00715 break;
00716
00717 case ty_mbFull:
00718 case ty_mbTop:
00719 ss << t->Var()->asBlockStringProducer(tvP, options, false)
00720 << ((t->typeTag == ty_mbFull) ? "|" : "!")
00721 << ((t->Core()->typeTag == ty_fn)?"(":"")
00722 << t->Core()->asBlockStringProducer(tvP, options, false)
00723 << ((t->Core()->typeTag == ty_fn)?")":"");
00724 break;
00725
00726 case ty_mutable:
00727 {
00728 shared_ptr<Type> base = t->Base();
00729 bool wrap = shouldParenWrap(t->typeTag, base->typeTag);
00730
00731 ss << "mutable "
00732 << base->asBlockStringProducer(tvP, options, wrap);
00733 break;
00734 }
00735
00736 case ty_const:
00737 {
00738 shared_ptr<Type> base = t->Base();
00739 bool wrap = shouldParenWrap(t->typeTag, base->typeTag);
00740
00741 ss << "const "
00742 << base->asBlockStringProducer(tvP, options, wrap);
00743 break;
00744 }
00745
00746 case ty_exn:
00747 ss << "exception";
00748 break;
00749
00750 case ty_pcst:
00751 {
00752 ss << "*(";
00753 for (size_t i=0; i<t->components.size(); i++) {
00754 if (i > 0) ss << ", ";
00755 ss << t->CompType(i)->asBlockStringProducer(tvP, options, true);
00756 }
00757 ss << ")";
00758 break;
00759 }
00760
00761 case ty_kfix:
00762 {
00763 if (t == Type::Kmono)
00764 ss << "m";
00765 else if (t == Type::Kpoly)
00766 ss << "P";
00767 else
00768 assert(false);
00769 break;
00770 }
00771
00772 }
00773
00774 t->pMark--;
00775
00776 if (parenWrap) ss << ')';
00777
00778 return ss.str();
00779 }
00780
00781 std::string
00782 TypeScheme::asString(shared_ptr<TvPrinter> tvP, bool norm)
00783 {
00784 std::stringstream ss;
00785 bool forall = false;
00786
00787 if (norm)
00788 normalize();
00789
00790 if (Options::FQtypes)
00791 if (ftvs.size()) {
00792 ss << "(forall";
00793 forall = true;
00794 for (TypeSet::iterator itr_i = ftvs.begin();
00795 itr_i != ftvs.end(); ++itr_i)
00796 ss << " " << (*itr_i)->asString(tvP);
00797 ss << " ";
00798 }
00799
00800 if (tcc) {
00801 if (Options::showAllTccs) {
00802 if (tcc->size()) {
00803 if (!forall) {
00804 ss << "(forall";
00805 forall = true;
00806 }
00807
00808 ss << " (";
00809 for (TypeSet::iterator itr = tcc->begin();
00810 itr != tcc->end(); ++itr) {
00811 shared_ptr<Typeclass> pred = (*itr)->getType();
00812 ss << pred->asString(tvP) << " ";
00813
00814 for (TypeSet::iterator itr_j = pred->fnDeps.begin();
00815 itr_j != pred->fnDeps.end(); ++itr_j)
00816 ss << (*itr_j)->asString(tvP) << " ";
00817 }
00818 ss << ") ";
00819 }
00820 }
00821 else {
00822
00823
00824 shared_ptr<TCConstraints> _tcc = tcc;
00825
00826 if (_tcc->size()) {
00827 for (TypeSet::iterator itr = _tcc->begin();
00828 itr != _tcc->end(); ++itr) {
00829 if ((((*itr)->flags & TY_CT_SUBSUMED) == 0) &&
00830 (((*itr)->flags & TY_CT_SELF) == 0)) {
00831 if (!forall) {
00832 ss << "(forall (";
00833 forall = true;
00834 }
00835 ss << (*itr)->asString(tvP) << " ";
00836 }
00837 }
00838
00839 if (forall)
00840 ss << ") ";
00841 }
00842 }
00843 }
00844
00845 ss << tau->asString(tvP);
00846 if (forall)
00847 ss << ")";
00848
00849 return ss.str();
00850 }
00851
00852 std::string
00853 Instance::asString() const
00854 {
00855 return ts->tau->asString();
00856 }
00857