Type-pp.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2008, Johns Hopkins University.
00004  * Copyright (C) 2010, Jonathan S. Shapiro.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or
00008  * without modification, are permitted provided that the following
00009  * conditions are met:
00010  *
00011  *   - Redistributions of source code must contain the above 
00012  *     copyright notice, this list of conditions, and the following
00013  *     disclaimer. 
00014  *
00015  *   - Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions, and the following
00017  *     disclaimer in the documentation and/or other materials 
00018  *     provided with the distribution.
00019  *
00020  *   - Neither the names of the copyright holders nor the names of any
00021  *     of any contributors may be used to endorse or promote products
00022  *     derived from this software without specific prior written
00023  *     permission. 
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00026  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00027  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00028  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00029  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00030  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00031  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00032  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00033  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00034  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00035  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 //#define DEBUG_SHOW_ALL_LINKS
00066 //#define DEBUG_SHOW_RIGIDITY
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   // Bound the display recursion artificially. there really needs to be a
00092   // better way to do this, but I don't have a quick solution, and
00093   // this choice has worked well in practice so far.
00094   if (t->pMark >= 2)
00095     return " ... ";
00096   else 
00097     t->pMark++;
00098 
00099   // Debugging support for type variable linkage display:
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       // The debug version dumps the structure body in detail. These
00212       // should be reconciled more cleanly when we switch the type
00213       // syntax over.
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     // The debug version dumps the structure body in detail. These
00243     // should be reconciled more cleanly when we switch the type
00244     // syntax over.
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     // The debug version dumps the structure body in detail. These
00291     // should be reconciled more cleanly when we switch the type
00292     // syntax over.
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 /*asBlockString(tvP, options) + " OR " + */asSexprString(tvP, options);
00393 }
00394 
00395 void
00396 Type::PrettyPrint()
00397 {
00398   std::cerr << asString();
00399   std::cerr << std::endl;
00400 }
00401 
00402 // Return the precedence (in the grammar's view) of the production
00403 // that produces a given type.
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   // return true;
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   // Bound the display recursion artificially. there really needs to be a
00448   // better way to do this, but I don't have a quick solution, and
00449   // this choice has worked well in practice so far.
00450   if (t->pMark >= 2)
00451     return " ... ";
00452   else 
00453     t->pMark++;
00454 
00455   if (parenWrap) ss << '(';
00456 
00457   // Debugging support for type variable linkage display:
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     // No paren wrapping here. While the return value is not fully
00534     // bracketed by ty_fn itself, the bracketing decision must be made
00535     // by our container.
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     // No paren wrapping here. Function arguments are fully bracketed,
00543     // and ByRef is always outermost and lowest precedence.
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     // No paren wrapping here. Same argument as for ty_fn
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     //HERE
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       // No paren wrapping here. Everything here is fully bracketed,
00579       // and [type] application has about the highest precedence of anything.
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       // No paren wrapping here. Everything here is fully bracketed,
00611       // and [type] application has about the highest precedence of anything.
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       // No paren wrapping here. Everything here is fully bracketed,
00662       // and [type] application has about the highest precedence of anything.
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     // Always outermost, so never needs paren wrapping
00709     ss << "ByRef " << t->Base()->asBlockStringProducer(tvP, options, false);
00710     break;
00711 
00712   case ty_array_ref:
00713     // Always outermost, so never needs paren wrapping
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       //shared_ptr<TCConstraints> _tcc = new TCConstraints;
00823       //addConstraints(_tcc);
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 

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