Hoist.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2006, Johns Hopkins University.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or
00007  * without modification, are permitted provided that the following
00008  * conditions are met:
00009  *
00010  *   - Redistributions of source code must contain the above 
00011  *     copyright notice, this list of conditions, and the following
00012  *     disclaimer. 
00013  *
00014  *   - Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions, and the following
00016  *     disclaimer in the documentation and/or other materials 
00017  *     provided with the distribution.
00018  *
00019  *   - Neither the names of the copyright holders nor the names of any
00020  *     of any contributors may be used to endorse or promote products
00021  *     derived from this software without specific prior written
00022  *     permission. 
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00027  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  **************************************************************************/
00037 
00038 #include <stdint.h>
00039 #include <stdlib.h>
00040 #include <dirent.h>
00041 #include <fstream>
00042 #include <iostream>
00043 #include <sstream>
00044 #include <string>
00045 #include <libsherpa/UExcept.hxx>
00046 #include <libsherpa/CVector.hxx>
00047 #include <libsherpa/avl.hxx>
00048 #include <assert.h>
00049 #include "AST.hxx"
00050 #include "Type.hxx"
00051 #include "inter-pass.hxx"
00052 
00053 using namespace sherpa;
00054 
00055 #define NULL_MODE 0x0u
00056 #define LOCAL_MODE 0x2u  // Parameters
00057 #define USE_MODE 0x3u
00058 
00059 //WARNING: **REQUIRES** answer and errFree.
00060 #define HOIST(a, b, c, d, e, f, g) do{                  \
00061     answer = hoist((a), (b), (c), (d), (e), (f), (g));  \
00062     if(answer == false)                                 \
00063       errFree = false;                                  \
00064   }while(0)
00065 
00066 
00067 struct hstruct{
00068   size_t toppos;
00069   AST *ident;
00070   AST *lambda;
00071 
00072   hstruct(size_t _toppos, AST *_ident, AST *_lambda)
00073   {
00074     toppos = _toppos;
00075     ident = _ident;
00076     lambda = _lambda;
00077   }
00078 };
00079   
00080 bool
00081 hoist(std::ostream& errStream,
00082       AST *ast, 
00083       CVector<hstruct *> *hs,
00084       const size_t toppos,
00085       AST *parent, 
00086       const size_t chno,
00087       const bool hoistme)
00088 {
00089   bool errFree = true, answer = true;
00090   switch(ast->astType) {
00091   case at_Null:
00092     break;
00093 
00094   case at_AnyGroup:
00095   case at_version:
00096   case agt_literal:
00097   case agt_tvar:
00098   case agt_var:
00099   case agt_definition:
00100   case agt_type:
00101   case agt_bindingPattern:
00102   case agt_valuePattern:
00103   case agt_expr:
00104   case agt_eform:
00105   case agt_type_definition:
00106   case agt_value_definition:
00107   case agt_CompilationUnit:
00108   case at_ifident:
00109   case at_localFrame:
00110   case at_frameBindings:
00111   case agt_tc_definition:
00112   case agt_if_definition:
00113   case agt_category:
00114   case agt_ow:
00115   case agt_qtype:
00116   case agt_fielditem:
00117   case at_refCat:
00118   case at_valCat:
00119   case at_opaqueCat:
00120   case at_tcdecls:
00121   case at_tyfn:
00122   case at_tcapp:
00123   case at_usesel:
00124   case at_use_case:
00125   case at_identList:
00126   case at_container:
00127     {
00128       errStream << ast->loc.asString() << "Internal Compiler Error. " 
00129            << "Function hoist, unexpected astType: " 
00130            << ast->astTypeName()
00131            << std::endl;
00132       
00133       errFree = false;
00134       break;
00135     } 
00136 
00137   case at_unit:
00138   case at_boolLiteral:
00139   case at_charLiteral:
00140   case at_intLiteral:
00141   case at_floatLiteral:
00142   case at_stringLiteral:
00143   case at_bitfield:
00144   case at_ident:
00145   case at_defexception:
00146   case at_deftypeclass:
00147   case at_declunion:
00148   case at_declstruct:
00149   case at_declrepr:
00150   case at_defstruct:
00151   case at_defunion:
00152   case at_defrepr:
00153   case at_reprbody:
00154   case at_reprcase:
00155   case at_reprcaselegR:
00156   case at_reprtag:
00157   case agt_reprbodyitem:
00158   case at_declValue:
00159   case at_use:
00160   case at_import:
00161   case at_provide:
00162   case at_declares:
00163   case at_declare:
00164   case at_tvlist:
00165   case at_constructors:
00166   case at_constructor:
00167   case at_fields:
00168   case at_field:
00169   case at_fill:
00170   case at_fn:
00171   case at_arrayType:
00172   case at_vectorType:
00173   case at_typeapp:
00174   case at_refType:
00175   case at_exceptionType:
00176   case at_valType:
00177   case at_primaryType:
00178   case at_pairType:
00179   case at_fnargVec:
00180   case at_mutableType:
00181   case at_identPattern:
00182   case at_literalPattern:
00183   case at_unitPattern:
00184   case at_pairPattern:
00185   case at_applyPattern:    
00186   case at_argVec:
00187   case at_qualType:
00188   case at_constraints:
00189     {
00190       break;
00191     }
00192 
00193   case at_start:
00194     {
00195       // match at_module/at_interface
00196       HOIST(errStream, ast->children[0], hs, 0, ast, 1, true);
00197       break;
00198     }
00199 
00200   case at_interface:
00201   case at_module:
00202     {
00203       // match agt_definition*    
00204       for(size_t c = (ast->astType == at_module)?0:1; 
00205           c < ast->children.size(); c++)
00206         HOIST(errStream, ast->children[c], hs, c, ast, c, true);      
00207       break;
00208     }
00209 
00210   case at_define:
00211     {
00212       // match agt_expr
00213       if(ast->children[0]->astType == at_identPattern &&
00214          (ast->children[1]->astType == at_lambda))
00215         HOIST(errStream, ast->children[1], hs, toppos, ast, 1, false);
00216       else
00217         HOIST(errStream, ast->children[1], hs, toppos, ast, 1, true);
00218       break;
00219     }
00220 
00221   case at_definstance:
00222     {
00223       HOIST(errStream, ast->children[1], hs, toppos, ast, 1, true);
00224       break;
00225     }
00226 
00227   case at_method_decls:
00228   case at_methods:
00229     {
00230       for(size_t c = 0; c < ast->children.size(); c++)
00231         HOIST(errStream, ast->children[c], hs, toppos, ast, c, true);
00232         
00233       break;
00234     }
00235   case at_method_decl: 
00236     {
00237       HOIST(errStream, ast->children[1], hs, toppos, ast, 1, true);       
00238       break;
00239     }
00240 
00241   case at_lambda:
00242     {
00243       AST *id = 0;
00244       if(hoistme) {
00245         assert(false);
00246         AST *lam = ast;
00247         id = AST::genSym(ast, "lam");
00248         id->identType = id_value;
00249         hs->append(new hstruct(toppos, id, lam));
00250       }
00251       HOIST(errStream, ast->children[1], hs, toppos, ast, 1, true);           
00252 
00253       // id is used here directly, trulyHoist makes copies of the `id' AST.
00254       if(hoistme)
00255         parent->children[chno] = id;
00256 
00257       break;
00258     }
00259 
00260   case at_tqexpr:
00261   case at_suspend:
00262   case at_begin:
00263   case at_select:  
00264   case at_apply:
00265   case at_ucon_apply:
00266   case at_struct_apply:
00267   case at_if:
00268   case at_and:
00269   case at_or:
00270   case at_cond:
00271   case at_cond_legs:
00272   case at_dup:
00273   case at_deref:
00274   case at_switchR:
00275   case at_sw_legs:
00276   case at_otherwise:
00277   case at_tryR:
00278   case at_throw:
00279   case at_array_length:
00280   case at_vector_length:
00281   case at_array_nth:
00282   case at_vector_nth:
00283   case at_vector:
00284   case at_array:
00285   case at_pair:
00286   case at_mkclosure:
00287   case at_makevector:    
00288   case at_cond_leg:
00289   case at_setbang:
00290   case at_sw_leg:
00291   case at_let:
00292   case at_letrec:
00293   case at_letStar:
00294   case at_letbindings:
00295   case at_letbinding:
00296   case at_do:
00297   case at_dotest:
00298     {
00299       // match agt_expr+
00300       for(size_t c = 0; c < ast->children.size(); c++)
00301         HOIST(errStream, ast->children[c], hs, toppos, ast, c, hoistme);
00302       break;
00303     }
00304   }
00305   return errFree;
00306 }
00307 
00308 bool
00309 trulyHoist(std::ostream& errStream, UocInfo *uoc,
00310            AST *ast,
00311            CVector<hstruct *> *hs)
00312 {
00313   // Just to be sure, verify hs-vector is sorted.
00314   if(hs->size() > 0)
00315     for(size_t i=0; i < (hs->size() - 1); i++) {    
00316       hstruct *hhs1 = (*hs)[i];
00317       hstruct *hhs2 = (*hs)[i+1];
00318       if(!(hhs1->toppos <= hhs2->toppos)) {
00319         errStream << hhs1->lambda->loc << ": Internal Compiler Error."
00320                   << " In function do_hoist, " 
00321                   << hhs1->toppos << " > " << hhs2->toppos << std::endl;
00322         return false;
00323       }
00324     }
00325 
00326 #if 0
00327   for(size_t i=0; i < hs->size(); i++) {
00328     hstruct *hhs = (*hs)[i];
00329     errStream << hhs->toppos << "  " << hhs->ident->s << ": "
00330               << hhs->lambda->asString()
00331               << std::endl;    
00332   }
00333 #endif
00334   
00335   size_t insertion_count = 0;
00336   AST *comp = ast->children[0];
00337   assert((comp->astType == at_module) || (comp->astType == at_interface));
00338   for(size_t i=0; i < hs->size(); /*empty*/) {
00339     size_t ipos = i;
00340     
00341     hstruct *hhs = (*hs)[i];    
00342     size_t toppos = hhs->toppos;    
00343     do {
00344       size_t pos = hhs->toppos + insertion_count;
00345       AST *topAst = comp->children[pos];
00346       
00347       AST *id = hhs->ident;
00348       AST *idUse = id->getDCopy();
00349       idUse->Flags |= ID_IS_GLOBAL;
00350       
00351       AST *proclaim = new AST(at_declValue, topAst->loc,
00352                                     idUse, 
00353                                     hhs->lambda->symType->asAST(topAst->loc));
00354       proclaim->addChild(new AST(at_constraints));
00355       comp->children.insert(pos, proclaim);
00356       insertion_count++; 
00357       i++;      
00358       hhs = (*hs)[i];
00359     }while((i < hs->size()) && (toppos == hhs->toppos));
00360     
00361     
00362     i = ipos;    
00363     hhs = (*hs)[i];    
00364     toppos = hhs->toppos;    
00365     do {
00366       size_t pos = hhs->toppos + insertion_count + 1; // Past the definition.
00367       AST *topAst = comp->children[pos-1];
00368       
00369       AST *id = hhs->ident;
00370       AST *idUse = id->getDCopy();
00371       idUse->Flags |= ID_IS_GLOBAL;
00372       
00373       AST *fun = new AST(at_define,  topAst->loc, 
00374                                new AST(at_identPattern, topAst->loc, idUse),
00375                                hhs->lambda);
00376       fun->addChild(new AST(at_constraints));
00377 
00378       comp->children.insert(pos, fun);
00379       insertion_count++;
00380       i++;
00381       hhs = (*hs)[i];
00382     }while((i < hs->size()) && (toppos == hhs->toppos));
00383   }
00384   return true;
00385 }
00386 
00387 bool
00388 UocInfo::fe_hoist(std::ostream& errStream, 
00389                   bool init, unsigned long flags)
00390 {
00391   CVector<hstruct *> *hs = new CVector<hstruct *>;
00392   bool errFree = true;
00393   
00394   CHKERR(errFree, hoist(errStream, ast, hs, 0, NULL, 0, true));
00395   
00396   if(!errFree)
00397     return false;
00398   
00399   CHKERR(errFree, trulyHoist(errStream, this, ast, hs));
00400 
00401   //CHKERR(errFree, markTail(errStream, this, ast, hs));
00402   
00403   //errStream << "Hoisted AST = " << ast->asString() << std::endl;
00404   CHKERR(errFree, RandT(errStream, this, true, 
00405                         PP_SYM_FLAGS, PP_TYP_FLAGS));
00406 
00407   return errFree;
00408 }
00409 

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