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 #include <assert.h>
00039 #include <stdint.h>
00040 #include <stdlib.h>
00041 #include <dirent.h>
00042 #include <fstream>
00043 #include <iostream>
00044 #include <string>
00045 #include <sstream>
00046
00047 #include <libsherpa/UExcept.hxx>
00048
00049 #include "Options.hxx"
00050 #include "UocInfo.hxx"
00051 #include "AST.hxx"
00052 #include "Type.hxx"
00053 #include "TypeInfer.hxx"
00054 #include "TypeScheme.hxx"
00055 #include "TypeMut.hxx"
00056 #include "Typeclass.hxx"
00057 #include "inter-pass.hxx"
00058 #include "Unify.hxx"
00059
00060 using namespace std;
00061 using namespace boost;
00062 using namespace sherpa;
00063
00064 static TypeSet
00065 getDomain(shared_ptr<Typeclass> t)
00066 {
00067 TypeSet dom;
00068
00069 for (size_t i=0; i < t->typeArgs.size(); i++)
00070 dom.insert(t->TypeArg(i));
00071
00072 for (TypeSet::iterator itr = t->fnDeps.begin();
00073 itr != t->fnDeps.end(); ++itr) {
00074 shared_ptr<Type> fdep = (*itr);
00075 shared_ptr<Type> ret = fdep->Ret();
00076
00077 TypeSet newDom;
00078
00079 for (TypeSet::iterator itr_d = dom.begin(); itr_d != dom.end(); ++itr_d)
00080 if ((*itr_d)->getType() != ret->getType())
00081 newDom.insert(*itr_d);
00082
00083 dom = newDom;
00084 }
00085
00086 return dom;
00087 }
00088
00089 static TypeSet
00090 getDomVars(const TypeSet& dom)
00091 {
00092 TypeSet vars;
00093
00094 for (TypeSet::iterator itr = dom.begin(); itr != dom.end(); ++itr) {
00095 shared_ptr<Type> arg = (*itr)->getType();
00096 arg->collectAllftvs(vars);
00097 }
00098
00099 return vars;
00100 }
00101
00102 static bool
00103 mustSolve(const TypeSet& dom)
00104 {
00105 for (TypeSet::iterator itr = dom.begin(); itr != dom.end(); ++itr) {
00106 shared_ptr<Type> arg = (*itr)->getType();
00107 if (arg->isVariable())
00108 return false;
00109 }
00110
00111 return true;
00112 }
00113
00114 static void
00115 rigidify(TypeSet& vars)
00116 {
00117 for (TypeSet::iterator itr = vars.begin(); itr != vars.end(); ++itr) {
00118 shared_ptr<Type> arg = (*itr)->getType();
00119 assert(arg->typeTag == ty_tvar);
00120 arg->flags |= TY_RIGID;
00121 }
00122 }
00123
00124 static void
00125 unrigidify(TypeSet& vars)
00126 {
00127 for (TypeSet::iterator itr = vars.begin(); itr != vars.end(); ++itr) {
00128 shared_ptr<Type> arg = (*itr)->getType();
00129 assert(arg->typeTag == ty_tvar);
00130 arg->flags &= ~TY_RIGID;
00131 }
00132 }
00133
00134
00135 bool
00136 handlePcst(std::ostream &errStream, shared_ptr<Trail> trail,
00137 shared_ptr<Constraint> ct, shared_ptr<Constraints> cset,
00138 bool &handled, bool &handlable)
00139 {
00140 if (ct->isPcst()) {
00141 handlable = true;
00142 }
00143 else {
00144 handlable = false;
00145 handled = false;
00146 return true;
00147 }
00148
00149 DEBUG(PCST) errStream << "\t\tTrying PCST: "
00150 << ct->asString(Options::debugTvP)
00151 << std::endl;
00152
00153 shared_ptr<Type> k = ct->CompType(0)->getType();
00154 shared_ptr<Type> gen = ct->CompType(1)->getType();
00155 shared_ptr<Type> ins = ct->CompType(2)->getType();
00156
00157
00158 if (k == Type::Kmono) {
00159 DEBUG(PCST) errStream << "\t\tCase *(m, tg, ti), CLEAR."
00160 << std::endl;
00161 cset->clearPred(ct);
00162 handled = true;
00163 bool unifies = ins->unifyWith(gen, false, trail, errStream);
00164 return unifies;
00165 }
00166
00167 if (k == Type::Kpoly) {
00168
00169
00170 if (gen->isConcretizable()) {
00171 DEBUG(PCST) errStream << "\t\tCase *(p, tg, ti), [](tg), CLEAR."
00172 << std::endl;
00173 cset->clearPred(ct);
00174 handled = true;
00175 shared_ptr<Type> tgg = gen->minimizeDeepMutability();
00176 shared_ptr<Type> tii = ins->minimizeDeepMutability();
00177 bool errFree = true;
00178 CHKERR(errFree, gen->unifyWith(tgg, false, trail, errStream));
00179 CHKERR(errFree, ins->unifyWith(tii, false, trail, errStream));
00180 return errFree;
00181 }
00182
00183
00184 if (ins->isDeepMut()) {
00185 DEBUG(PCST) errStream << "\t\tCase *(p, tg, ti), Mut(ti) ERROR."
00186 << std::endl;
00187 cset->clearPred(ct);
00188 handled = true;
00189 return false;
00190 }
00191
00192 DEBUG(PCST) errStream << "\t\tCase *(p, tg, ti), "
00193 << "Immut(ti) KEEP."
00194 << std::endl;
00195
00196
00197 handled = false;
00198 return true;
00199 }
00200
00201 assert(k->typeTag == ty_kvar);
00202
00203
00204 if (ins->isDeepMut()) {
00205 DEBUG(PCST) errStream << "\t\tCase *(k, tg, ti), "
00206 << "Mut(ti) [k |-> m]."
00207 << std::endl;
00208 trail->subst(k, Type::Kmono);
00209 handled = true;
00210 return true;
00211 }
00212
00213
00214 if (gen->isDeepImmut()) {
00215 DEBUG(PCST) errStream << "\t\tCase *(k, tg, ti), Immut(tg)"
00216 << "Immut(tg) [k |-> p]."
00217 << std::endl;
00218 trail->subst(k, Type::Kpoly);
00219 handled = true;
00220 return true;
00221 }
00222
00223
00224 for (TypeSet::iterator itr = cset->begin();
00225 itr != cset->end(); ++itr) {
00226 shared_ptr<Constraint> newCt = (*itr)->getType();
00227 if (newCt == ct)
00228 continue;
00229
00230 if (!newCt->isPcst())
00231 continue;
00232
00233 shared_ptr<Type> newK = newCt->CompType(0)->getType();
00234 shared_ptr<Type> newGen = newCt->CompType(1)->getType();
00235 shared_ptr<Type> newIns = newCt->CompType(2)->getType();
00236
00237 if (newK == k && !ins->equals(newIns)) {
00238 DEBUG(PCST) errStream << "\t\tCase *(k, tg, ti), *(k, tg, tj)"
00239 << " ti !~~ tj, [k |-> p]."
00240 << std::endl;
00241
00242 trail->subst(k, Type::Kpoly);
00243 handled = true;
00244 return true;
00245 }
00246 }
00247
00248 DEBUG(PCST) errStream << "\t\tCase *(k, tg, ti) KEEP."
00249 << std::endl;
00250
00251 handled = false;
00252 return true;
00253 }
00254
00255 bool
00256 handleSpecialPred(std::ostream &errStream, shared_ptr<Trail> trail,
00257 shared_ptr<Constraint> pred, shared_ptr<Constraints> cset,
00258 bool &handled, bool &handlable)
00259 {
00260 bool errFree = true;
00261 pred = pred->getType();
00262
00263 do{
00264
00265 if (pred->typeTag != ty_typeclass) {
00266 handlable = false;
00267 handled = false;
00268 break;
00269 }
00270
00271
00272 const std::string &ref_types = SpecialNames::spNames.sp_ref_types;
00273 const std::string &has_field = SpecialNames::spNames.sp_has_field;
00274
00275 if (pred->defAst->s == ref_types) {
00276 handlable = true;
00277 DEBUG(SPSOL) errStream << "\t\tCase RefTypes for "
00278 << pred->asString(Options::debugTvP)
00279 << std::endl;
00280
00281 shared_ptr<Type> it = pred->TypeArg(0)->getType();
00282 if (it->isVariable()) {
00283 DEBUG(SPSOL) errStream << "\t\t ... Variable, KEEP"
00284 << pred->asString(Options::debugTvP)
00285 << std::endl;
00286 handled = false;
00287 break;
00288 }
00289
00290 handled = true;
00291 if (it->isRefType()) {
00292 DEBUG(SPSOL) errStream << "\t\t ... Satisfied, CLEAR"
00293 << pred->asString(Options::debugTvP)
00294 << std::endl;
00295 break;
00296 }
00297
00298
00299 DEBUG(SPSOL) errStream << "\t\t ... Unboxed-type, ERROR"
00300 << pred->asString(Options::debugTvP)
00301 << std::endl;
00302
00303 errFree = false;
00304 break;
00305 }
00306
00307 if(pred->defAst->s == has_field) {
00308 handlable = true;
00309 DEBUG(SPSOL) errStream << "\t\tCase HasField for "
00310 << pred->asString(Options::debugTvP)
00311 << std::endl;
00312
00313 shared_ptr<Type> st = pred->TypeArg(0)->getBareType();
00314 shared_ptr<Type> fName = pred->TypeArg(1)->getType();
00315 shared_ptr<Type> fType = pred->TypeArg(2)->getType();
00316
00317 if(st->isVariable()) {
00318 DEBUG(SPSOL) errStream << "\t\t ... Variable, KEEP"
00319 << pred->asString(Options::debugTvP)
00320 << std::endl;
00321 handled = false;
00322 break;
00323 }
00324
00325
00326
00327 if (st->isIndexableType() && fName->litValue.s == "length") {
00328 handled = false;
00329 errFree = true;
00330
00331 shared_ptr<Type> fld = Type::make(ty_word);
00332 CHKERR(errFree, fType->unifyWith(fld));
00333
00334 if (errFree) {
00335 handled = true;
00336 }
00337 else {
00338 DEBUG(SPSOL) errStream << "\t\t ... Field Unification failure, ERROR"
00339 << pred->asString(Options::debugTvP)
00340 << std::endl;
00341 }
00342
00343 break;
00344 }
00345
00346 handled = true;
00347 if (st->typeTag != ty_structv && st->typeTag != ty_structr) {
00348 DEBUG(SPSOL) errStream << "\t\t ... Non-structure type, ERROR"
00349 << pred->asString(Options::debugTvP)
00350 << std::endl;
00351 errFree = false;
00352 break;
00353 }
00354
00355 if (fName->typeTag != ty_field) {
00356 DEBUG(SPSOL) errStream << "\t\t ... Non-field type, ERROR"
00357 << pred->asString(Options::debugTvP)
00358 << std::endl;
00359 errFree = false;
00360 break;
00361 }
00362
00363 shared_ptr<Type> fld = GC_NULL;
00364 for (size_t i=0; i < st->components.size(); i++)
00365 if (st->CompName(i) == fName->litValue.s)
00366 if((st->CompFlags(i) & COMP_INVALID) == 0) {
00367 fld = st->CompType(i)->getType();
00368 break;
00369 }
00370
00371
00372 for (size_t i=0; i < st->methods.size(); i++)
00373 if (st->MethodName(i) == fName->litValue.s)
00374 if((st->MethodFlags(i) & COMP_INVALID) == 0) {
00375 fld = st->MethodType(i)->getType()->getDCopy();
00376
00377
00378 assert(fld->typeTag == ty_method);
00379 fld->typeTag = ty_fn;
00380 break;
00381 }
00382
00383 if(!fld) {
00384 DEBUG(SPSOL) errStream << "\t\t ... Field/Method not found, ERROR"
00385 << pred->asString(Options::debugTvP)
00386 << std::endl;
00387 errFree = false;
00388 break;
00389 }
00390
00391 CHKERR(errFree, fType->unifyWith(fld));
00392 if(!errFree)
00393 DEBUG(SPSOL) errStream << "\t\t ... Field Unification failure, ERROR"
00394 << pred->asString(Options::debugTvP)
00395 << std::endl;
00396 else
00397 DEBUG(SPSOL) errStream << "\t\t ... Field found, CLEAR"
00398 << pred->asString(Options::debugTvP)
00399 << std::endl;
00400 break;
00401 }
00402
00403
00404
00405 handlable = false;
00406 handled = false;
00407 break;
00408 } while(false);
00409
00410 if(handled)
00411 cset->clearPred(pred);
00412
00413 return errFree;
00414 }
00415
00416 bool
00417 handleTCPred(std::ostream &errStream, shared_ptr<Trail> trail,
00418 shared_ptr<Typeclass> pred, shared_ptr<TCConstraints> tcc,
00419 shared_ptr<const InstEnvironment > instEnv,
00420 bool must_solve, bool trial_mode, bool &handled)
00421 {
00422 DEBUG(TCSOL) errStream << "\t\tInstance Solver for: "
00423 << pred->asString(Options::debugTvP)
00424 << (trial_mode ? " [TRIAL]" : "")
00425 << std::endl;
00426
00427 shared_ptr<InstanceSet> insts =
00428 instEnv->getBinding(pred->defAst->fqn.asString());
00429
00430 if (!insts) {
00431 DEBUG(TCSOL) errStream << "\t\t ... No Instances in Environment"
00432 << std::endl;
00433 if (must_solve) {
00434 tcc->clearPred(pred);
00435 handled = true;
00436 return false;
00437 }
00438 else {
00439 handled = false;
00440 return true;
00441 }
00442 }
00443
00444 shared_ptr<TypeScheme> instScheme = GC_NULL;
00445 for (InstanceSet::iterator itr_j = insts->begin();
00446 itr_j != insts->end(); ++itr_j) {
00447 shared_ptr<TypeScheme> ts = (*itr_j)->ts->ts_instance();
00448 shared_ptr<Type> inst = ts->tau;
00449
00450
00451
00452
00453
00454
00455
00456 for (size_t c=0; c < inst->typeArgs.size(); c++)
00457 inst->TypeArg(c) = MBF(inst->TypeArg(c));
00458
00459 if (pred->equals(inst)) {
00460 instScheme = ts;
00461 break;
00462 }
00463 }
00464
00465 if (!instScheme) {
00466 DEBUG(TCSOL) errStream << "\t\t ... No Suitable Instance found"
00467 << std::endl;
00468 if (must_solve) {
00469 tcc->clearPred(pred);
00470 handled = true;
00471 return false;
00472 }
00473 else {
00474 handled = false;
00475 return true;
00476 }
00477 }
00478
00479 if (trial_mode) {
00480 handled = false;
00481 return true;
00482 }
00483
00484 bool errFree = pred->unifyWith(instScheme->tau);
00485
00486 DEBUG(TCSOL) errStream << "\t\t .. Post Unification with Instance: "
00487 << pred->asString(Options::debugTvP)
00488 << " CLEAR."
00489 << std::endl;
00490
00491 assert(errFree);
00492 tcc->clearPred(pred);
00493
00494 if (instScheme->tcc)
00495 for (TypeSet::iterator itr = instScheme->tcc->begin();
00496 itr != instScheme->tcc->end(); ++itr) {
00497 shared_ptr<Typeclass> instPred = (*itr);
00498
00499
00500
00501
00502 if (!pred->equals(instPred)) {
00503 tcc->addPred(instPred);
00504 DEBUG(TCSOL) errStream << "\t\t .. Adding pre-condition: "
00505 << instPred->asString(Options::debugTvP)
00506 << std::endl;
00507 }
00508 }
00509
00510 handled = true;
00511 return true;
00512 }
00513
00514 static bool
00515 handleEquPreds(std::ostream &errStream, shared_ptr<Trail> trail,
00516 shared_ptr<Typeclass> pred, shared_ptr<TCConstraints> tcc,
00517 TypeSet& vars,
00518 bool &handled)
00519 {
00520
00521
00522
00523 handled = false;
00524 rigidify(vars);
00525 for (TypeSet::iterator itr = tcc->begin();
00526 itr != tcc->end(); ++itr) {
00527 shared_ptr<Constraint> newCt = (*itr)->getType();
00528 if (newCt == pred)
00529 continue;
00530
00531 if (pred->equals(newCt)) {
00532 DEBUG(TCSOL) errStream << "\t\t EquPreds: "
00533 << pred->asString(Options::debugTvP)
00534 << " === "
00535 << newCt->asString(Options::debugTvP)
00536 << " UNIFY, CLEAR1."
00537 << std::endl;
00538
00539 pred->unifyWith(newCt);
00540 tcc->clearPred(pred);
00541 handled=true;
00542 break;
00543 }
00544 }
00545 unrigidify(vars);
00546
00547 return true;
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 bool
00611 TypeScheme::solvePredicates(std::ostream &errStream, const LexLoc &errLoc,
00612 shared_ptr< const InstEnvironment > instEnv,
00613 shared_ptr<Trail> trail)
00614 {
00615
00616
00617
00618
00619
00620
00621
00622 bool errFree = true;
00623 bool handled = false;
00624
00625 DEBUG(SOL) errStream << "\tTo Solve: "
00626 << asString(Options::debugTvP)
00627 << std::endl;
00628
00629 do {
00630 handled = false;
00631 shared_ptr<Typeclass> errPred = GC_NULL;
00632 bool errFreeNow = true;
00633
00634 for (TypeSet::iterator itr = tcc->begin();
00635 itr != tcc->end(); ++itr) {
00636 shared_ptr<Typeclass> pred = (*itr);
00637 errPred = pred;
00638 bool handlable = false;
00639
00640
00641 CHKERR(errFreeNow, handleSpecialPred(errStream, trail,
00642 pred, tcc,
00643 handled, handlable));
00644
00645 DEBUG(SOL) errStream << "\t[Sol 1] (special): "
00646 << asString(Options::debugTvP)
00647 << (handled ? " [HANDLED]" : "")
00648 << (handlable ? " [HANDLABLE]" : "")
00649 << (!errFreeNow ? " [ERROR]" : "")
00650 << std::endl;
00651
00652 if (handled)
00653 break;
00654 if (handlable)
00655 continue;
00656
00657
00658 CHKERR(errFreeNow, handlePcst(errStream, trail,
00659 pred, tcc, handled, handlable));
00660
00661 DEBUG(SOL) errStream << "\t[Sol 2] (pcst): "
00662 << asString(Options::debugTvP)
00663 << (handled ? " [HANDLED]" : "")
00664 << (handlable ? " [HANDLABLE]" : "")
00665 << (!errFreeNow ? " [ERROR]" : "")
00666 << std::endl;
00667
00668 if (handled)
00669 break;
00670 if (handlable)
00671 continue;
00672
00673 TypeSet dom = getDomain(pred);
00674 TypeSet vars = getDomVars(dom);
00675 bool ms = mustSolve(dom);
00676 if (ms) {
00677
00678 CHKERR(errFreeNow, handleTCPred(errStream, trail, pred, tcc,
00679 instEnv, ms, false, handled));
00680 DEBUG(SOL) errStream << "\t[Sol 3.a] (must-solve): "
00681 << asString(Options::debugTvP)
00682 << (handled ? " [HANDLED]" : "")
00683 << (handlable ? " [HANDLABLE]" : "")
00684 << (!errFreeNow ? " [ERROR]" : "")
00685 << std::endl;
00686
00687 if (handled)
00688 break;
00689 }
00690
00691
00692 rigidify(vars);
00693 handleTCPred(errStream, trail, pred, tcc,
00694 instEnv, ms, false, handled);
00695 unrigidify(vars);
00696 DEBUG(SOL) errStream << "\t[Sol 3.b.i] (exact): "
00697 << asString(Options::debugTvP)
00698 << (handled ? " [HANDLED]" : "")
00699 << (handlable ? " [HANDLABLE]" : "")
00700 << (!errFreeNow ? " [ERROR]" : "")
00701 << std::endl;
00702 if (handled)
00703 break;
00704
00705
00706 CHKERR(errFreeNow, handleTCPred(errStream, trail, pred, tcc,
00707 instEnv, false, true, handled));
00708 DEBUG(SOL) errStream << "[Sol 3.b.ii] (solvability): "
00709 << asString(Options::debugTvP)
00710 << (handled ? " [HANDLED]" : "")
00711 << (handlable ? " [HANDLABLE]" : "")
00712 << (!errFreeNow ? " [ERROR]" : "")
00713 << std::endl;
00714 if (handled)
00715 break;
00716
00717
00718 CHKERR(errFreeNow, handleEquPreds(errStream, trail,
00719 pred, tcc, vars, handled));
00720 DEBUG(SOL) errStream << "[Sol 4] (equ-pred): "
00721 << asString(Options::debugTvP)
00722 << (handled ? " [HANDLED]" : "")
00723 << (handlable ? " [HANDLABLE]" : "")
00724 << (!errFreeNow ? " [ERROR]" : "")
00725 << std::endl;
00726 if (handled)
00727 break;
00728
00729 if (!errFreeNow)
00730 assert(false);
00731 }
00732
00733 if (!errFreeNow) {
00734 assert(handled);
00735 assert(errPred);
00736 errStream << errLoc << ": "
00737 << "Unsatisfiable constraint: "
00738 << errPred->asString()
00739 << std::endl;
00740 }
00741
00742 CHKERR(errFree, errFreeNow);
00743
00744 } while (handled);
00745
00746 return errFree;
00747 }