refize.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 <stdlib.h>
00039 #include <dirent.h>
00040 #include <fstream>
00041 #include <iostream>
00042 #include <sstream>
00043 #include <string>
00044 #include <libsherpa/UExcept.hxx>
00045 #include <libsherpa/CVector.hxx>
00046 #include <libsherpa/avl.hxx>
00047 #include <assert.h>
00048 #include "AST.hxx"
00049 #include "Type.hxx"
00050 #include "backend.hxx"
00051 #include "Symtab.hxx"
00052 #include "Unify.hxx"
00053 #include "inter-pass.hxx"
00054 
00055 using namespace sherpa;
00056 
00057 #define NULL_MODE 0x0u
00058 #define LOCAL_MODE 0x2u  // Parameters
00059 #define USE_MODE 0x3u
00060 
00061 
00062 
00063 static void
00064 refSub(AST *ast, AST *from, AST *parent, const size_t chno)
00065 {
00066   switch(ast->astType) {
00067   case at_ident:
00068     {
00069       if(ast->symbolDef == from) {
00070         AST *deref = new AST(at_deref, ast->loc, ast);
00071         parent->children[chno] = deref;
00072       }
00073       break;
00074     }
00075     
00076   default:
00077     {
00078       for(size_t i=0; i<ast->children.size(); i++)
00079         refSub(ast->children[i], from, ast, i);
00080     }
00081   }
00082 }
00083 
00084 
00085 
00086 //WARNING: **REQUIRES** answer and errFree.
00087 #define REFIZE(a, b, c, d) do{                                  \
00088     answer = refize((a), (b), (c), (d));                        \
00089     if(answer == false)                                         \
00090       errFree = false;                                          \
00091   }while(0)
00092 
00093   
00094 bool
00095 refize(std::ostream& errStream,
00096        AST *ast, AST *parent, 
00097        const size_t chno)
00098 {
00099   size_t c;
00100   bool errFree = true, answer = true;
00101   switch(ast->astType) {
00102   case at_Null:
00103   case at_AnyGroup:
00104   case at_version:
00105   case agt_literal:
00106   case agt_tvar:
00107   case agt_var:
00108   case agt_definition:
00109   case agt_type:
00110   case agt_bindingPattern:
00111   case agt_valuePattern:
00112   case agt_expr:
00113   case agt_eform:
00114   case agt_type_definition:
00115   case agt_value_definition:
00116   case agt_CompilationUnit:
00117   case at_ifident:
00118   case at_ifsel:
00119   case at_localFrame:
00120   case at_frameBindings:
00121   case agt_tc_definition:
00122   case agt_if_definition:
00123   case agt_category:
00124   case agt_tcdecl:
00125   case agt_ow:
00126   case at_refCat:
00127   case at_valCat:
00128   case at_opaqueCat:
00129   case at_tcdecls:
00130   case at_tyfn:
00131   case at_super:
00132   case at_tcreqs:
00133   case at_tcreq:
00134   case at_method_decls:
00135   case at_method_decl: 
00136   case at_usesel:
00137   case at_use_case:
00138   case at_identList:
00139   case at_container:
00140     {
00141       errStream << ast->loc.asString() << "Internal Compiler Error. " 
00142            << "Function refize, unexpected astType: " 
00143            << ast->astTypeName()
00144            << std::endl;
00145       
00146       errFree = false;
00147       break;
00148     } 
00149 
00150   case at_unit:
00151   case at_boolLiteral:
00152   case at_charLiteral:
00153   case at_intLiteral:
00154   case at_floatLiteral:
00155   case at_stringLiteral:
00156   case at_bitfield:
00157   case at_ident:
00158   case at_defexception:
00159   case at_deftypeclass:
00160   case at_definstance:
00161   case at_declunionr:
00162   case at_declstructr:
00163   case at_defstruct:
00164   case at_defunion:
00165   case at_declValue:
00166   case at_use:
00167   case at_import:
00168   case at_stateful_import:
00169   case at_provide:
00170   case at_stateful_provide:
00171   case at_declares:
00172   case at_declare:
00173   case at_tvlist:
00174   case at_constructors:
00175   case at_constructor:
00176   case at_fields:
00177   case at_field:
00178   case at_fn:
00179   case at_arrayType:
00180   case at_vectorType:
00181   case at_typeapp:
00182   case at_refType:
00183   case at_valType:
00184   case at_primaryType:
00185   case at_pairType:
00186   case at_fnargVec:
00187   case at_mutableType:
00188   case at_methodType:
00189   case at_identPattern:
00190   case at_literalPattern:
00191   case at_unitPattern:
00192   case at_pairPattern:
00193   case at_applyPattern:    
00194   case at_argVec:
00195   case at_letbindings:
00196   case at_letbinding:
00197     {
00198       break;
00199     }
00200 
00201   case at_start:
00202     {
00203       // match at_module/at_interface
00204       REFIZE(errStream, ast->children[1], ast, 1);
00205       break;
00206     }
00207 
00208   case at_interface:
00209   case at_module:
00210     {
00211       // match agt_definition*    
00212       c = (ast->astType == at_module)?0:1;
00213       while (c < ast->children.size()) {
00214         REFIZE(errStream, ast->children[c], ast, c);
00215         c++;
00216       }
00217       break;
00218     }
00219 
00220   case at_define:
00221     {
00222       // match agt_expr
00223       REFIZE(errStream, ast->children[1], ast, 1);
00224       break;
00225     }
00226 
00227   case at_lambda:
00228     {      
00229       // AST *argVec = ast->children[0];
00230       AST *body = ast->children[1];
00231       REFIZE(errStream, body, ast, 1);      
00232       
00233 #if 0
00234       CVector<AST *> *argIds = new CVector<AST *>;
00235       for(size_t i=0; i<argVec->children.size(); i++)
00236         argVec->children[i]->getIds(errStream, argIds, true);
00237       
00238       for(size_t i=0; i<argIds->size(); i++) {  
00239         AST *argPat = (*argIds)[i];
00240         AST *arg = argPat->children[0];
00241         AST *argtyp = argPat->children[1];
00242         if(!arg->symType->isRefType()) {
00243           if(argtyp != NULL) {
00244             AST *refType = new AST(at_refType, argtyp->loc, argtyp);
00245             argPat->children[1] = refType;
00246           }
00247           AST *deref = new AST(at_deref, arg->loc, arg);          
00248           refSub(body, arg, ast, 1);
00249         }
00250       }
00251 #endif      
00252       break;
00253     }
00254 
00255   case at_apply:
00256     {      
00257       AST *fn = ast->children[0];
00258       // Not handling need to do some work
00259       REFIZE(errStream, fn, ast, 0);
00260       
00261       for(size_t c = 1; c < ast->children.size(); c++) {
00262         AST *arg = ast->children[c];
00263         REFIZE(errStream, arg, ast, c);
00264 #if 0
00265         // Fix this if needed, dup is now a keyword
00266         if(arg->symType->getType()->kind != ty_ref ||
00267            fn->symType->getType()->kind == ty_tvar) {
00268           AST *dupIdent = new AST(at_ident, arg->loc);  
00269           // This needs to use a non-maskable name ex "#dup"
00270           // which can be bound in the prelude, in addition to dup
00271           dupIdent->s = depIdent->fqn.ident = "dup";
00272           AST *dupedArg = new AST(at_apply, arg->loc, 
00273                                         dupIdent, arg);
00274           ast->children[c] = dupedArg;
00275         }
00276 #endif  
00277       }      
00278       
00279       break;
00280     }
00281     
00282 
00283   case at_tqexpr:
00284   case at_begin:
00285   case at_do:
00286   case at_dotest:
00287   case at_select:  
00288   case at_ucon_apply:
00289   case at_struct_apply:
00290   case at_if:
00291   case at_and:
00292   case at_or:
00293   case at_cond:
00294   case at_cond_legs:
00295   case at_deref:
00296   case at_dup:
00297   case at_case:
00298   case at_case_legs:
00299   case at_otherwise:
00300   case at_try:
00301   case at_throw:
00302   case at_array_length:
00303   case at_vector_length:
00304   case at_array_nth:
00305   case at_vector_nth:
00306   case at_vector:
00307   case at_array:
00308   case at_pair:
00309   case at_makevector:    
00310   case at_cond_leg:
00311   case at_setbang:
00312   case at_case_leg:
00313     {
00314       // match agt_expr+
00315       c = 0;
00316       while (c < ast->children.size()) {
00317         REFIZE(errStream, ast->children[c], ast, c);
00318         c++;
00319       }      
00320       break;
00321     }
00322 
00323   case at_letStar:
00324     {
00325       assert(false);
00326       break;
00327     }
00328 
00329   case at_let:
00330   case at_letrec:
00331     {
00332       AST *lbs = ast->children[0];
00333      
00334       //  errStream << "Before: " << ast->asString() << std::endl;
00335       
00336       // This assumes that letSimp pass has been done
00337       for (size_t c = 0; c < lbs->children.size(); c++) {
00338         AST *lb = lbs->children[c];
00339         AST *ip = lb->children[0];
00340         AST *expr = lb->children[1];
00341         REFIZE(errStream, expr, lb, 1);
00342         AST *id = ip->children[0];
00343         
00344         if(!id->symType->isRefType()) {
00345           id->identFlags |= ID_IS_REFIZED;
00346           assert(false);
00347           // Fix this if needed, dup is now a keyword
00348           AST *dupIdent = new AST(at_ident, expr->loc);
00349           dupIdent->s = dupIdent->fqn.ident = "dup";
00350           AST *dup = new AST(at_apply, expr->loc, 
00351                                    dupIdent, expr);
00352           lb->children[1] = dup;        
00353           
00354           // Fix the type qualifier if there is one
00355           AST *tq = ip->children[1];
00356           if(tq != NULL) {
00357             AST *refType = new AST(at_refType, tq->loc, tq);
00358             ip->children[1] = refType;
00359           }
00360         }
00361       }
00362       
00363       REFIZE(errStream, ast->children[1], ast, 1);
00364       
00365       if(ast->astType == at_letrec)
00366         for (size_t c = 0; c < lbs->children.size(); c++) {
00367           AST *lbc = lbs->children[c];    
00368           AST *idc = lbc->children[0]->children[0];
00369           if(idc->identFlags & ID_IS_REFIZED) {
00370             for (size_t d = 1; d < lbs->children.size(); d++) {
00371               AST *lbd = lbs->children[d];
00372               AST *exprd = lbd->children[1];
00373               refSub(exprd, idc, lbd, 1);
00374             }
00375           }
00376         }
00377 
00378       for (size_t c = 0; c < lbs->children.size(); c++) {
00379         AST *lb = lbs->children[c];
00380          AST *id = lb->children[0]->children[0];
00381         if(id->identFlags & ID_IS_REFIZED)
00382           refSub(ast->children[1], id, ast, 1);
00383       }
00384       
00385       //  errStream << "After:  " << ast->asString() << std::endl;
00386       break;
00387     }
00388   }
00389   return errFree;
00390 }
00391 
00392 bool
00393 UocInfo::do_refize(std::ostream& errStream, 
00394                    bool init, unsigned long flags)
00395 {
00396   // This pass not needed under bootstrap-assumptions.
00397   return true; 
00398 
00399   bool errFree = refize(errStream, ast, NULL, 0);
00400   errFree = RandT(errStream, this, true,
00401                   NO_RESOLVE_DECL, DEF_DECL_NO_MATCH);
00402   return errFree;
00403 }
00404 

Generated on Fri May 18 07:59:17 2012 for BitC Compiler by  doxygen 1.4.7