BitC-pp.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2010, Jonathan S. Shapiro
00004  * Portions Copyright (C) 2008, Johns Hopkins University.
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 
00042 
00043 #include <assert.h>
00044 #include <stdint.h>
00045 #include <stdio.h>
00046 #include <unistd.h>
00047 #include <dirent.h>
00048 #include <string>
00049 #include <iostream>
00050 
00051 #include "Options.hxx"
00052 #include "UocInfo.hxx"
00053 #include "AST.hxx"
00054 #include "Type.hxx"
00055 #include "TypeInfer.hxx"
00056 #include "inter-pass.hxx"
00057 #include "TypeScheme.hxx"
00058 #include "libsherpa/EnumSet.hxx"
00059 
00060 using namespace boost;
00061 using namespace sherpa;
00062 using namespace std;
00063 
00064 const PrettyPrintFlags NonRecursiveFlags = pp_InLayoutBlock | pp_FinalNewline;
00065 
00066 // At the moment, the "pretty" part of the pretty printing is broken.
00067 static void
00068 print_type(INOstream& out, shared_ptr <const AST> ast)
00069 {
00070   shared_ptr<Type> ty = ast->symType;
00071 
00072   if (ty) {
00073     out << " /* : " << ty->asString() << " */";
00074   }
00075   else
00076     out << " /* : " << "?untyped?" << " */";
00077 
00078 }
00079 
00080 static void
00081 blk_BitcP(INOstream& out, shared_ptr <const AST> ast, PrettyPrintFlags);
00082 
00087 static void
00088 doChildren(void (*BitcP)(INOstream& out, shared_ptr <const AST> ast, PrettyPrintFlags),
00089            INOstream& out, shared_ptr <const AST> ast, size_t from,
00090            const std::string& startMark,
00091            const std::string& sep,
00092            const std::string& endMark,
00093            PrettyPrintFlags flags)
00094 {
00095   assert( (flags & NonRecursiveFlags) == pp_NONE );
00096 
00097   if (from == ast->children.size())
00098     return;
00099 
00100   out << startMark;
00101   for (size_t c = from; c < ast->children.size(); c++) {
00102     if (c > from)
00103       out << sep;
00104     BitcP(out, ast->child(c), flags);
00105   }
00106   out << endMark;
00107 }
00108 
00109 // Not yet handled:
00110 //
00111 //  at_docstring
00112 //  at_Null - should it be? (no)
00113 //  at_declare
00114 //
00115 //  at_qualType   - obsolete; last use removed from MethDecl.cxx
00116 //
00117 //  at_inner_ref  - deferred, not currently supported
00118 //  at_suspend    - deferred, not currently supported
00119 //  
00120 static void
00121 blk_BitcP(INOstream& out, shared_ptr <const AST> ast, PrettyPrintFlags flags)
00122 {
00123   size_t startIndent = out.indentToHere();
00124 
00125   PrettyPrintFlags nrFlags = flags & NonRecursiveFlags;
00126   flags &= ~NonRecursiveFlags;
00127 
00128   // The following just recurse:
00129   switch(ast->astType) {
00130   case at_module:
00131     {
00132       out << ast->atKwd();
00133 
00134       // All modules are anonymous - the module name is just window
00135       // dressing, and we do not preserve it.
00136 
00137       out.more();
00138       doChildren(blk_BitcP, out, ast, 0, " is\n", "\n\n", "", flags);
00139       out.less();
00140       break;
00141     }
00142 
00143   case at_interface:
00144     {
00145       out << ast->atKwd();
00146 
00147       // Put name on same line:
00148       out << " ";
00149       blk_BitcP(out, ast->child(0), flags);
00150 
00151       out.more();
00152       doChildren(blk_BitcP, out, ast, 1, " is\n", "\n\n", "", flags);
00153       out.less();
00154 
00155       break;
00156     }
00157 
00158   case at_import:
00159     {
00160       out << ast->atKwd();
00161       out << " ";
00162       blk_BitcP(out, ast->child(0), flags);
00163       doChildren(blk_BitcP, out, ast, 1, " ", ", ", "", flags);
00164       break;
00165     }
00166 
00167   case at_ifsel:
00168     {
00169       // Note: arguments are somewhat inverted. Local ident is child(1).
00170       out << ast->child(0)->s;
00171       if (ast->child(0)->s != ast->child(1)->s) {
00172         out << " = "
00173             << ast->child(1)->s;
00174       }
00175       break;
00176     }
00177 
00178   case at_importAs:
00179     { 
00180       out << ast->atKwd();
00181 
00182       doChildren(blk_BitcP, out, ast, 0, " ", " as ", "", flags);
00183 
00184       break;
00185     }
00186   case at_provide:
00187     {
00188       out << ast->atKwd();
00189 
00190       out << " ";
00191       blk_BitcP(out, ast->child(0), flags);
00192 
00193       doChildren(blk_BitcP, out, ast, 1, " ", ", ", "", flags);
00194 
00195       break;
00196     }
00197 
00198   case at_deftypeclass:
00199     {
00200       shared_ptr<AST> ident = ast->child(0);
00201       shared_ptr<AST> tvlist = ast->child(1);
00202       shared_ptr<AST> tcdecls = ast->child(2);
00203       shared_ptr<AST> openclosed = ast->child(3);
00204       shared_ptr<AST> methods = ast->child(4);
00205       shared_ptr<AST> constraints = ast->child(5);
00206 
00207       doChildren(blk_BitcP, out, constraints, 0, "where ", ", ", "\n", flags);
00208       blk_BitcP(out, openclosed, flags);
00209       out << ast->atKwd() << " ";
00210       blk_BitcP(out, ident, flags);
00211       doChildren(blk_BitcP, out, tvlist, 0, "(", ", ", ")", flags);
00212       out.more();
00213       //      blk_BitcP(out, tcdecls, flags);
00214       out.less();
00215 
00216       if (methods->children.size()) {
00217         out << "\nis ";
00218 
00219         out.indentToHere();
00220         doChildren(blk_BitcP, out, methods, 0, "", 
00221                    "\n",
00222                    "", flags);
00223       }
00224       else
00225         out << " {}";
00226 
00227       break;
00228     }
00229 
00230   case at_definstance:
00231     {
00232       shared_ptr<AST> tapp = ast->child(0);
00233       shared_ptr<AST> methods = ast->child(1);
00234       shared_ptr<AST> constraints = ast->child(2);
00235 
00236       doChildren(blk_BitcP, out, constraints, 0, "where ", ", ", "\n", flags);
00237       out << ast->atKwd() << " ";
00238       blk_BitcP(out, tapp, flags);
00239 
00240       if (methods->children.size()) {
00241         out << "\nis ";
00242 
00243         out.indentToHere();
00244         doChildren(blk_BitcP, out, methods, 0, "", "\n", "", flags);
00245       }
00246 
00247       break;
00248     }
00249   case at_tcmethod_binding:
00250     {
00251       doChildren(blk_BitcP, out, ast, 0, "", " = ", "", flags);
00252       break;
00253     }
00254 
00255   case at_defrepr:
00256   case at_defstruct:
00257   case at_defunion:
00258   case at_defexception:
00259     {
00260       shared_ptr<AST> ident = ast->child(0);
00261       shared_ptr<AST> tvlist = ast->child(1);
00262       shared_ptr<AST> category = ast->child(2);
00263       shared_ptr<AST> declares = ast->child(3);
00264       shared_ptr<AST> fc = ast->child(4);
00265       shared_ptr<AST> constraints = ast->child(5);
00266 
00267       doChildren(blk_BitcP, out, constraints, 0, "where ", ", ", "\n", flags);
00268 
00269       blk_BitcP(out, category, flags);
00270 
00271       // Careful! Reprs are transformed into unions by the reprSimp
00272       // pass, so what we get here might actually be a repr:
00273       if (ast->flags & UNION_IS_REPR)
00274         out << "repr ";
00275       else
00276         out << ast->atKwd() << " ";
00277       blk_BitcP(out, ident, flags);
00278       doChildren(blk_BitcP, out, tvlist, 0, "(", ", ", ")", flags);
00279 
00280       out.more();
00281       doChildren(blk_BitcP, out, declares, 0, "\n", "\n", "", flags);
00282       out.less();
00283 
00284       if (fc->children.size()) {
00285         out << "\nis ";
00286 
00287         out.indentToHere();
00288         doChildren(blk_BitcP, out, fc, 0, "", 
00289 #if 0
00290                    (ast->astType == at_defstruct) ? "\n" : "\n\n",
00291 #else
00292                    "\n",
00293 #endif
00294                    "", flags);
00295       }
00296 
00297       break;
00298     }
00299 
00300   case at_reprctr:
00301     {
00302       bool emittedSome = false;
00303 
00304       blk_BitcP(out, ast->child(0), flags);
00305       out << "\nwhere ";
00306       out.indentToHere();
00307 
00308       doChildren(blk_BitcP, out, ast, 1, "", ",\n", "", flags);
00309       break;
00310     }
00311   case at_reprrepr:
00312     {
00313       doChildren(blk_BitcP, out, ast, 0, "", " == ", "", flags);
00314       break;
00315     }
00316 
00317   case at_constructor:
00318     {
00319       bool isRepr = false;
00320 
00321       if (ast->children.size() == 1) {
00322         blk_BitcP(out, ast->child(0), flags);
00323       }
00324       else {
00325         blk_BitcP(out, ast->child(0), flags);
00326         out << " ";
00327         (void) out.indentToHere(); // record the "is" depth
00328 
00329         out << "is ";
00330         size_t isDepth = out.indentToHere();
00331         doChildren(blk_BitcP, out, ast, 1, "", "\n", "", flags);
00332         out.setIndent(isDepth);
00333 
00334         for(size_t c = 1; c < ast->children.size(); c++) {
00335           shared_ptr<AST> fld = ast->child(c);
00336           if (fld->flags & FLD_IS_DISCM) {
00337             isRepr = true;
00338             break;
00339           }
00340         }
00341 
00342         //        out.setIndent(isDepth);
00343 
00344         if (isRepr) {
00345           bool emittedSome = false;
00346 
00347           out << "\nwhere ";
00348           out.indentToHere();
00349           for(size_t c = 1; c < ast->children.size(); c++) {
00350             shared_ptr<AST> fld = ast->child(c);
00351             if (fld->flags & FLD_IS_DISCM) {
00352               if (emittedSome)
00353                 out << ",\n";
00354 
00355               blk_BitcP(out, fld->child(0), flags); // field name
00356               out << " == "
00357                   << fld->unin_discm;
00358               emittedSome = true;
00359             }
00360           }
00361         }
00362       }
00363       
00364       break;
00365     }
00366 
00367   case at_declstruct:
00368   case at_declunion:
00369   case at_declrepr:
00370     {
00371       shared_ptr<AST> ident = ast->child(0);
00372       shared_ptr<AST> tvlist = ast->child(1);
00373       shared_ptr<AST> category = ast->child(2);
00374       shared_ptr<AST> constraints = ast->child(5);
00375 
00376       doChildren(blk_BitcP, out, constraints, 0, "where ", ",", "\n", flags);
00377       blk_BitcP(out, category, flags);
00378       if (ast->flags & UNION_IS_REPR)
00379         out << "repr ";
00380       else
00381         out << ast->atKwd() << " ";
00382       blk_BitcP(out, ident, flags);
00383       doChildren(blk_BitcP, out, tvlist, 0, "(", ", ", ")", flags);
00384 
00385       out.more();
00386       if (ident->flags & DEF_IS_EXTERNAL) {
00387         out << "\nexternal";
00388         if (ident->externalName.size())
00389           out << " " << ident->externalName;        
00390       }
00391       out.less();
00392 
00393 
00394       break;
00395     }
00396 
00397   case at_proclaim:
00398     {
00399       shared_ptr<AST> ident = ast->child(0);
00400       shared_ptr<AST> proc_type = ast->child(1);
00401       shared_ptr<AST> constraints = ast->child(2);
00402 
00403       doChildren(blk_BitcP, out, constraints, 0, "where ", ",", "\n", flags);
00404       out << " " << ast->atKwd() << " ";
00405       blk_BitcP(out, ident, flags);
00406       out << " : ";
00407       blk_BitcP(out, proc_type, flags);
00408 
00409       out.more();
00410 
00411       if (ident->flags & DEF_IS_EXTERNAL) {
00412         out << "\nexternal";
00413         if (ident->externalName.size())
00414           out << " " << ident->externalName;        
00415       }
00416       out.less();
00417     }
00418     break;
00419 
00421     // Things that are still implemented in sxp_BitcP in support of
00422     // something that hasn't moved yet:
00424   case at_fill:
00425     out << ast->atKwd() << " : ";
00426     blk_BitcP(out, ast->child(0), flags);
00427     if (ast->children.size() > 0) { // if RESERVED
00428       out << " = ";
00429       blk_BitcP(out, ast->child(0), flags);
00430     }
00431       
00432     break;
00433 
00434   case at_field:
00435   case at_methdecl:
00436   case at_method_decl:          // TC method
00437     doChildren(blk_BitcP, out, ast, 0, "", " : ", "", flags);
00438     break;
00439 
00440   case at_fieldType:
00441     {
00442       blk_BitcP(out, ast->child(0), flags);
00443       break;
00444     }
00445   case at_ident:
00446   case at_ifident:
00447     out << ast->s;
00448     if (Options::ppFQNS) {
00449       out << " /*" << ast->fqn;
00450       if (ast->externalName.size()) {
00451         out << "," << ast->externalName;
00452       }
00453       out << "*/";
00454     }
00455 
00456     break;
00457 
00458   case at_tcapp:
00459   case at_typeapp:
00460     {
00463       blk_BitcP(out, ast->child(0), flags);
00464       doChildren(blk_BitcP, out, ast, 1, "(", ", ", ")", flags);
00465       break;
00466     }
00467 
00468   case at_methType:
00469   case at_fn:
00470   case at_tyfn:
00471     {
00472       out << ast->atKwd();
00473       blk_BitcP(out, ast->child(0), flags);
00474       out << " -> ";
00475       blk_BitcP(out, ast->child(1), flags);
00476       break;
00477     }
00478 
00479   case at_tvlist:
00480   case at_fnargVec:
00481   case at_argVec:
00482     {
00483       out << "(";
00484       doChildren(blk_BitcP, out, ast, 0, "", ", ", "", flags);
00485       out << ")";
00486       break;
00487     }
00488 
00489   case at_primaryType:
00490     if (ast->s == "unit")
00491       out << "()";
00492     else
00493       out << ast->s;
00494     break;
00495 
00496   case at_mixfix:
00497     {
00498       // This should never occur in production, but we need it to
00499       // support --dumpafter for the early passes:
00500       doChildren(blk_BitcP, out, ast, 0, "", " ", "", flags);
00501       break;
00502     }
00503 
00504   case at_mutableType:
00505   case at_constType:
00506   case at_arrayRefType:
00507   case at_byRefType:
00508     out << ast->atKwd() << " ";
00509     blk_BitcP(out, ast->child(0), flags);
00510     break;
00511 
00513   case at_boxedType:
00514   case at_unboxedType:
00515   case at_vectorType:
00516   case at_arrayType:
00517     {
00518       out << ast->atKwd();
00519       doChildren(blk_BitcP, out, ast, 0, "(", ",", ")", flags);
00520       break;
00521     }
00522 
00523     // This is exactly like the expedient case above. I'm keeping it
00524     // separate because this one isn't merely an expedient.
00525   case at_bitfieldType:
00526     {
00527       out << ast->atKwd();
00528       doChildren(blk_BitcP, out, ast, 0, "", "(", ")", flags);
00529       break;
00530     }
00531 
00532   case at_boxedCat:
00533     if (!(ast->printVariant & pf_IMPLIED))
00534       out << "boxed ";
00535     break;
00536   case at_unboxedCat:
00537     out << "unboxed ";
00538     break;
00539   case at_opaqueCat:
00540     out << "opaque ";
00541     break;
00542 
00543   case at_oc_closed:
00544     out << "closed ";
00545     break;
00546   case at_oc_open:
00547     // does not print!
00548     break;
00549 
00551     // EXPRESSIONS
00553   case at_typeAnnotation:
00554     // Argument order was swapped.
00555     doChildren(blk_BitcP, out, ast, 0, "", " : ", "", flags & ~pp_ShowTypes);
00556     break;
00557 
00558   case at_boolLiteral:
00559   case at_charLiteral:
00560   case at_intLiteral:
00561   case at_floatLiteral:
00562 
00563     out << ast->s;
00564     if (flags & pp_LitValues)
00565       out << " /* " << ast->litValue << " */";
00566     break;
00567 
00568   case at_stringLiteral:
00569     out << "\"" << ast->s << "\"";
00570 
00571     break;
00572 
00573   case at_recdef:
00574     {
00575       shared_ptr<AST> identPattern = ast->child(0);
00576       shared_ptr<AST> iLambda = ast->child(1);
00577       shared_ptr<AST> constraints = ast->child(2);
00578 
00579       doChildren(blk_BitcP, out, constraints, 0, "where ", ", ", "\n", flags);
00580       out << ast->atKwd() << " ";
00581 
00582       // Procedure name:
00583       blk_BitcP(out, identPattern, flags);
00584 
00585       // Procedure arguments:
00586       shared_ptr<AST> iLamArgs = iLambda->child(0);
00587       shared_ptr<AST> iLamRetBlock = iLambda->child(1);
00588       if (iLamArgs->children.size())
00589         doChildren(blk_BitcP, out, iLamArgs, 0, "(", ", ", ")", flags);
00590       else
00591         out << "()";
00592 
00593       out << " = " ;
00594 
00595       out.more();
00596 
00597       // Because of the way we build lambdas, the body is always an
00598       // at_labeledBlock for __return, and we are going to suppress
00599       // that during pretty print. The body of *that* is the true body
00600       // of the lambda:
00601       shared_ptr<AST> iLamBody = iLamRetBlock->child(1);
00602 
00603       // If it's a begin form, let the opening brace be on the same
00604       // line as the '='. This requires that we emit the '{' here.
00605       if (iLamBody->astType == at_begin)
00606         out << "{\n";
00607       else
00608         out << "\n";
00609 
00610       blk_BitcP(out, iLamRetBlock, flags| pp_InLayoutBlock);
00611 
00612       if (iLamBody->astType == at_begin) {
00613         out.less();
00614         out << "\n}";
00615       }
00616 
00617       out << "\n";
00618       break;
00619     }
00620 
00621   case at_define:
00622     {
00623       shared_ptr<AST> identPattern = ast->child(0);
00624       shared_ptr<AST> expr = ast->child(1);
00625       shared_ptr<AST> constraints = ast->child(2);
00626 
00627       doChildren(blk_BitcP, out, constraints, 0, "where ", ", ", "\n", flags);
00628 
00629       out << ast->atKwd() << " ";
00630 
00631       // Identifier:
00632       blk_BitcP(out, identPattern, flags);
00633 
00634       out << " = " ;
00635       blk_BitcP(out, expr, flags);
00636       break;
00637     }
00638 
00639   case at_identPattern:
00640     doChildren(blk_BitcP, out, ast, 0, "", " : ", "", flags);
00641     break;
00642 
00643   case at_container:
00644     {
00645       out << "__letSSA ";
00646       size_t outer = out.indentToHere();
00647       doChildren(blk_BitcP, out, ast->child(0), 0, "", "\n", "", flags);
00648       out.setIndent(outer);
00649       out << "\nin ";
00650       out.indentToHere();
00651       blk_BitcP(out, ast->child(1), flags | pp_InLayoutBlock);
00652       break;
00653     }
00654 
00655   case at_localFrame:
00656     {
00657       out << ast->atKwd();
00658       size_t outer = out.indentToHere();
00659       doChildren(blk_BitcP, out, ast->child(0), 0, "", "\n", "", flags);
00660       out.setIndent(outer);
00661       out << "\nin ";
00662       out.indentToHere();
00663       blk_BitcP(out, ast->child(1), flags | pp_InLayoutBlock);
00664       break;
00665     }
00666 
00667   case at_letStar:
00668   case at_let:
00669   case at_letrec:
00670     {
00671       out << ast->atKwd() << " ";
00672       size_t outer = out.indentToHere();
00673       doChildren(blk_BitcP, out, ast->child(0), 0, "", "\n", "", flags);
00674       out.setIndent(outer);
00675       out << "\nin ";
00676       out.indentToHere();
00677       blk_BitcP(out, ast->child(1), flags | pp_InLayoutBlock);
00678       break;
00679     }
00680   case at_letbinding:
00681     {
00682       doChildren(blk_BitcP, out, ast, 0, "", " = ", "", flags);
00683       break;
00684     }
00685   case at_loopbinding:
00686     {
00687       blk_BitcP(out, ast->child(0), flags);
00688       out << " = ";
00689       blk_BitcP(out, ast->child(1), flags);
00690       out << " then ";
00691       blk_BitcP(out, ast->child(2), flags);
00692       break;
00693     }
00694 
00695   case at_dummyType:
00696   case at_exceptionType:
00697     {
00698       out << ast->atKwd();
00699       break;
00700     }
00701 
00702   case at_begin:
00703     {
00704       if (nrFlags & pp_InLayoutBlock) {
00705         doChildren(blk_BitcP, out, ast, 0, "", "\n", "", flags);
00706       }
00707       else {
00708         out << "{\n";
00709         out.more();
00710         doChildren(blk_BitcP, out, ast, 0, "", "\n", "", flags);
00711         out.less();
00712         out << "\n}";
00713       }
00714       break;
00715     }
00716 
00717   case at_labeledBlock:
00718     {
00719       // labeled blocks get automatically inserted to handle return
00720       // and continue. The labels used are compiler-reserved symbols,
00721       // so we need to undo the labeling in those two cases.
00722       std::string label = ast->child(0)->s;
00723 
00724       if ((flags & pp_Raw) ||
00725           (label != "__return" && label != "__continue")) {
00726         out << ast->atKwd() << " ";
00727         blk_BitcP(out, ast->child(0), flags);
00728         out << "\nin ";
00729         out.indentToHere();
00730         blk_BitcP(out, ast->child(1), flags | pp_InLayoutBlock);
00731       }
00732       else {
00733         // Preserve the layout block context here, since if we are the
00734         // expression in a layout block context, and we are
00735         // suppressing the labels, then our body is in a layout block
00736         // context.
00737         blk_BitcP(out, ast->child(1), flags | (nrFlags & pp_InLayoutBlock));
00738       }
00739 
00740       break;
00741     }
00742 
00743   case at_return_from:
00744     {
00745       // __return and __continue are internally inserted. Emit
00746       // those the way the user keyed them.
00747       string ident = ast->child(0)->s;
00748       
00749       if (ident == "__continue") {
00750         out << "continue";
00751       }
00752       else if (ident == "__return") {
00753         out << "return ";
00754         blk_BitcP(out, ast->child(1), flags);
00755       }
00756       else {
00757         out << "from ";
00758         blk_BitcP(out, ast->child(0), flags);
00759         out << "return ";
00760         blk_BitcP(out, ast->child(1), flags);
00761       }
00762       break;
00763     }
00764 
00765   case at_lambda:
00766     {
00767 #if 0
00768       if (ast->printVariant && pf_IMPLIED) {
00769         // While this test is true while printing whole top-level forms,
00770         // it is not true in the case of  individual expressions. Hence
00771         // I have disabled it. If the final version of the compiler has
00772         // no expression printing, we may re-enable it.
00773         std::cerr << "The pretty printer should never be printing an "
00774                   << "at_ilambda pattern!\n";
00775         exit(1);
00776       }
00777 #endif
00778   
00779       shared_ptr<AST> lamArgs = ast->child(0);
00780       shared_ptr<AST> lamRetBlock = ast->child(1);
00781 
00782       out << ast->atKwd();
00783       if (lamArgs->children.size())
00784         doChildren(blk_BitcP, out, lamArgs, 0, "(", ", ", ") ", flags);
00785       else
00786         out << "() ";
00787 
00788       blk_BitcP(out, lamRetBlock, flags| pp_InLayoutBlock);
00789       break;
00790     }
00791 
00792   case at_usesel:
00793   case at_fqCtr:
00794   case at_sel_ctr:
00795   case at_select:
00796     {
00797       doChildren(blk_BitcP, out, ast, 0, "", ".", "", flags);
00798       break;
00799     }
00800 
00801   case at_nth:
00802   case at_array_nth:
00803   case at_array_ref_nth:
00804   case at_vector_nth:
00805     {
00806       doChildren(blk_BitcP, out, ast, 0, "", "[", "]", flags);
00807       break;
00808     }
00809 
00810   case at_loop:
00811     {
00812       out << ast->atKwd() << " ";
00813       size_t baseIndent = out.indentToHere();
00814       doChildren(blk_BitcP, out, ast->child(0), 0, "", "\n", "", flags);
00815       out.setIndent(baseIndent);
00816       out << "\n  until ";
00817       out.indentToHere();
00818       blk_BitcP(out, ast->child(1), flags);
00819       out.setIndent(baseIndent);
00820       out << "\nin ";
00821       out.indentToHere();
00822       
00823       shared_ptr<AST> loopBody = ast->child(2);
00824 
00825       // Following is not true in gen-c.cxx, because an at_letStar has
00826       // been emitted.
00827       if (flags.lacks(pp_Raw) && 
00828           loopBody->astType == at_labeledBlock) {
00829         assert ((loopBody->astType == at_labeledBlock)
00830                 && (loopBody->child(0)->s == "__continue"));
00831         loopBody = loopBody->child(1);
00832         // For the moment, I'm wrapping loop bodies in a BEGIN with a
00833         // trailing () for typing purposes. Suppress that:
00834         assert((loopBody->astType == at_begin)
00835                && (loopBody->children.size() == 2)
00836                && (loopBody->child(1)->astType == at_unit));
00837         loopBody = loopBody->child(0);
00838       }
00839 
00840       blk_BitcP(out, loopBody, flags | pp_InLayoutBlock);
00841 
00842       break;
00843     }
00844 
00845   case at_looptest:
00846     {
00847       // The at_looptest node is now vestigial, but I don't want to
00848       // make that change simultaneous with this one.
00849       blk_BitcP(out, ast->child(0), flags);
00850       break;
00851     }
00852 
00853   case at_uswitch:
00854     {
00855       // switch id = expr
00856       // case T in block
00857       // otherwise block
00858 
00859       out << ast->atKwd() << " ";
00860       blk_BitcP(out, ast->child(0), flags);
00861       out << " = ";
00862       blk_BitcP(out, ast->child(1), flags);
00863       out << "\n";
00864       doChildren(blk_BitcP, out, ast->child(2), 0, "", "\n", "", flags);
00865       if (ast->child(3)->astType != at_Null)
00866         blk_BitcP(out, ast->child(3), flags);
00867       
00868       break;
00869     }
00870 
00871   case at_usw_leg:
00872     {
00873       // Technically, the AST allows for multiple matches, and we
00874       // should add support for that in the grammar.
00875       out << ast->atKwd() << " ";
00876       blk_BitcP(out, ast->child(2), flags);
00877       out << " in ";
00878       out.indentToHere();
00879       blk_BitcP(out, ast->child(1), flags);
00880       break;
00881     }
00882 
00883   case at_otherwise:
00884     {
00885       // Can be under at_uswitch or at_try
00886       out << "\n" << ast->atKwd() << " ";
00887       blk_BitcP(out, ast->child(0), flags);
00888       break;
00889     }
00890 
00891   case at_try:
00892     {
00893       out << ast->atKwd() << " ";
00894       blk_BitcP(out, ast->child(0), flags);
00895       out << "\ncatch ";
00896       blk_BitcP(out, ast->child(1), flags);
00897 
00898       doChildren(blk_BitcP, out, ast->child(2), 0, "", "\n", "", flags);
00899 
00900       if (ast->child(3)->astType != at_Null)
00901         blk_BitcP(out, ast->child(3), flags);
00902       break;
00903     }
00904 
00905   case at_apply:
00906   case at_struct_apply:
00907   case at_object_apply:
00908   case at_ucon_apply:
00909     {
00910       blk_BitcP(out, ast->child(0), flags);
00911       out << "(";
00912       doChildren(blk_BitcP, out, ast, 1, "", ", ", "", flags);
00913       out << ")";
00914       break;
00915     }
00916 
00917   case at_setbang:
00918     {
00919       doChildren(blk_BitcP, out, ast, 0, "", " := ", "", flags);
00920       break;
00921     }
00922 
00923   case at_unit:
00924     {
00925       out << "()";
00926       break;
00927     }
00928 
00929     // Apply-style output, but built-in:
00930   case at_deref:
00931   case at_dup:
00932   case at_sizeof:
00933   case at_bitsizeof:
00934   case at_MakeVector:
00935   case at_vector:
00936   case at_array:
00937   case at_allocREF:
00938   case at_copyREF:
00939   case at_mkClosure:
00940   case at_setClosure:
00941   case at_mkArrayRef:
00942 #ifdef HAVE_INDEXABLE_LENGTH_OPS
00943   case at_array_length:
00944   case at_array_ref_length:
00945   case at_vector_length:
00946 #endif
00947     {
00948       out << ast->atKwd() << "(";
00949       doChildren(blk_BitcP, out, ast, 0, "", ", ", "", flags);
00950       out << ")";
00951       break;
00952     }
00953 
00954   case at_throw:
00955     {
00956       out << ast->atKwd() << " ";
00957       blk_BitcP(out, ast->child(0), flags);
00958       break;
00959     }
00960 
00961     // Following three are legacy transition from the S-expression
00962     // syntax, and can be removed once the transition is complete:
00963   case at_cond:
00964     {
00965       shared_ptr<AST> legs = ast->child(0);
00966       shared_ptr<AST> condElse = ast->child(1);
00967 
00968       if (legs->children.size()) {
00969         doChildren(blk_BitcP, out, legs, 0, "", "\nelse ", "", flags);
00970 
00971         out << "\nelse ";
00972         blk_BitcP(out, condElse, flags);
00973       }
00974       else {
00975         // No legs - simplifies to just the else case:
00976         blk_BitcP(out, condElse, flags);
00977       }
00978 
00979       break;
00980     }
00981 
00982   case at_cond_leg:
00983     {
00984       out << "if ";
00985       blk_BitcP(out, ast->child(0), flags);
00986       out << "\nthen ";
00987       blk_BitcP(out, ast->child(1), flags);
00988       break;
00989     }
00990 
00991   case at_if:
00992     {
00993       out << ast->atKwd() << " ";
00994       blk_BitcP(out, ast->child(0), flags);
00995       out << "\nthen ";
00996 
00997       size_t thenIndent = out.indentToHere();
00998       blk_BitcP(out, ast->child(1), flags | pp_InLayoutBlock );
00999       out.setIndent(thenIndent);
01000 
01001       if (ast->children.size() > 2) {
01002         out << "\nelse ";
01003         blk_BitcP(out, ast->child(2), flags | pp_InLayoutBlock );
01004       }
01005       break;
01006     }
01007 
01008   case at_when:
01009   case at_unless:
01010     {
01011       out << ast->atKwd() << " ";
01012       blk_BitcP(out, ast->child(0), flags);
01013       out << "\ndo ";
01014       out.indentToHere();
01015       blk_BitcP(out, ast->child(1), flags | pp_InLayoutBlock);
01016       break;
01017     }
01018 
01019   case at_and:
01020     {
01021       doChildren(blk_BitcP, out, ast, 0, "((", ") && (", "))", flags);
01022       break;
01023     }
01024   case at_or:
01025     {
01026       doChildren(blk_BitcP, out, ast, 0, "((", ") || (", "))", flags);
01027       break;
01028     }
01029 
01030 #if dbg_flags != 0
01031   case at_letGather:            // DEBUG ONLY
01032   case at_fields:               // DEBUG_ONLY
01033     {
01034       out << ast->atKwd() << " { ";
01035       out.indentToHere();
01036       doChildren(blk_BitcP, out, ast, 0, "", ";\n", "\n}", flags);
01037       break;      
01038     }
01039 #endif
01040 
01041     // CATCH-ALL:
01042   default:
01043     {
01044       std::cerr << "blk_BitcP() needs support for AST type " 
01045                 << ast->tagName() << std::endl;
01046       assert(false);
01047     }
01048   }
01049 
01050 
01051   if (flags & pp_ShowTypes) print_type(out, ast);
01052 
01053   out.setIndent(startIndent);
01054 }
01055 
01057 static void
01058 doShowTypes(std::ostream& out, shared_ptr<AST> ast,
01059             shared_ptr<TSEnvironment > gamma,
01060             bool showMangName,
01061             bool raw = false,
01062             shared_ptr<TvPrinter> tvP=GC_NULL)
01063 {
01064   switch(ast->astType) {
01065   case at_ident:
01066 
01067     // Move this to at_define ... etc, in case
01068     // there is a need to see differentiated
01069     // tvars in a single definition.
01070 
01071     if (!raw)
01072       tvP = TvPrinter::make();
01073 
01074     out << ast->s  << ": "
01075               << ((!ast->scheme)
01076             ? "??"
01077             : ast->scheme->asString(tvP, true));
01078 
01079     if (showMangName)
01080       if (ast->symType->isOfInfiniteType())
01081         out << "[Infinite Type]";
01082       else
01083         out << " [" << ast->symType->mangledString() << "]";
01084 
01085     break;
01086 
01087   case at_usesel:
01088     {
01089       doShowTypes(out, ast->child(1), gamma,
01090                   showMangName, raw, tvP);
01091       break;
01092     }
01093 
01094   case at_interface:
01095   case at_module:
01096     {
01097       size_t i=0;
01098       if (ast->astType == at_interface) {
01099         out << "(" << ast->atKwd() << " "
01100             << ast->child(0)->s << endl;
01101         i=1;
01102       }
01103       else {
01104         out << "(" << "source-unit"  << endl;
01105         i=0;
01106       }
01107 
01108       for (; i<ast->children.size(); i++) {
01109         switch(ast->child(i)->astType){
01110         case at_importAs:
01111         case at_provide:
01112         case at_declare:
01113           break;
01114         default:
01115           doShowTypes(out, ast->child(i), gamma,
01116                       showMangName, raw, tvP);
01117           out << endl;
01118           break;
01119         }
01120       }
01121 
01122       out << ")";
01123       break;
01124     }
01125 
01126   case at_proclaim:
01127     out << " " << " opaque ";
01128     doShowTypes(out, ast->child(0), gamma,
01129                 showMangName, raw, tvP);
01130     break;
01131 
01132   case at_declare:
01133   case at_importAs:
01134   case at_provide:
01135     break;
01136 
01137   case at_defexception:
01138     {
01139       out << "  " << "exception " << ast->child(0)->s;
01140       break;
01141     }
01142 
01143   case at_deftypeclass:
01144     {
01145       //       out << "  " << "type-class "
01146       //           << ast->child(0)->s << ": "
01147       //           << ast->child(0)->symType->asString();
01148       out << "  " << "type-class ";
01149       doShowTypes(out, ast->child(0), gamma,
01150                   showMangName, raw, tvP);
01151       break;
01152     }
01153 
01154   case at_definstance:
01155     {
01156       if (!raw && (!tvP))
01157         tvP = TvPrinter::make();
01158 
01159       out << "  " << "Instance : "
01160           << ((!ast->scheme)
01161               ? "??"
01162               : ast->scheme->asString(tvP));
01163 
01164       break;
01165     }
01166 
01167   case at_defunion:
01168   case at_declunion:
01169     {
01170       out << "  " << "union ";
01171       doShowTypes(out, ast->child(0), gamma,
01172                   showMangName, raw, tvP);
01173       break;
01174     }
01175 
01176   case at_defstruct:
01177   case at_declstruct:
01178     {
01179       out << "  " << "struct ";
01180       doShowTypes(out, ast->child(0), gamma,
01181                   showMangName, raw, tvP);
01182       break;
01183     }
01184 
01185   case at_define:
01186   case at_recdef:
01187     {
01188       doShowTypes(out, ast->child(0), gamma,
01189                   showMangName, raw, tvP);
01190       break;
01191     }
01192 
01193   case at_identPattern:
01194     out << "  " << "val ";
01195     doShowTypes(out, ast->child(0), gamma,
01196                 showMangName, raw, tvP);
01197     break;
01198 
01199   default:
01200     cerr << ast->loc.asString() << ": "
01201          << "Internal Compiler Error."
01202          << " Unexpected AST type "
01203          << ast->tagName()
01204          << " obtained by doshowTypes() routine."
01205          << endl;
01206     break;
01207   }
01208 }
01209 
01211 void
01212 AST::PrettyPrint(std::ostream& strm, PrettyPrintFlags flags) const
01213 {
01214   INOstream out(strm);
01215   blk_BitcP(out, shared_from_this(), flags);
01216   if (flags & pp_FinalNewline)
01217     out << std::endl;
01218 }
01219 
01220 void
01221 AST::PrettyPrint(INOstream& out, PrettyPrintFlags flags) const
01222 {
01223   blk_BitcP(out, shared_from_this(), flags);
01224   if (flags & pp_FinalNewline)
01225     out << std::endl;
01226 }
01227 
01229 void
01230 AST::PrettyPrint(bool decorated) const
01231 {
01232   INOstream out(std::cerr);
01233 
01234   PrettyPrintFlags flags = 
01235     decorated ? PrettyPrintFlags(pp_ShowTypes) : PrettyPrintFlags();
01236 
01237   blk_BitcP(out, shared_from_this(), flags);
01238   out << endl;
01239 }
01240 
01242 void
01243 UocInfo::PrettyPrint(std::ostream& out, bool decorated)
01244 {
01245   assert (uocAst->astType == at_module
01246           || uocAst->astType == at_interface);
01247 
01248   PrettyPrintFlags flags = 
01249     decorated ? PrettyPrintFlags(pp_ShowTypes) : PrettyPrintFlags();
01250   uocAst->PrettyPrint(out, flags);
01251 }
01252 
01253 void
01254 UocInfo::ShowTypes(std::ostream& out)
01255 {
01256   doShowTypes(out, uocAst, gamma, false);
01257 }
01258 

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