Loop.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 <string>
00043 #include <sstream>
00044 #include <gmp.h>
00045 #include <errno.h>
00046 #include "Version.hxx"
00047 #include "UocInfo.hxx"
00048 #include "AST.hxx"
00049 #include "Environment.hxx"
00050 #include "Symtab.hxx"
00051 #include "inter-pass.hxx"
00052 #include "inter-pass.hxx"
00053 #include "backend.hxx"
00054 #include "Type.hxx"
00055 #include <sstream>
00056 
00057 using namespace sherpa;
00058 using namespace std;
00059 
00060 #define LOOPOK(errStream, ast, loops, noLVuse)                  \
00061 do{                                                             \
00062   answer = loopOK((errStream), (ast), (loops), (noLVuse));      \
00063   if(answer == false)                                           \
00064     errFree = false;                                            \
00065  }while(0)
00066 
00067 bool
00068 loopOK(std::ostream &errStream, GCPtr<AST> ast, 
00069        CVector< GCPtr<AST> > &loops, bool noLVuse)
00070 {
00071   bool errFree = true, answer = false;
00072 
00073   //errStream << "LoopChk: " << ast->asString() << std::endl;
00074   
00075   switch(ast->astType) {
00076     
00077   case at_Null:
00078   case at_AnyGroup:
00079   case at_version:
00080   case agt_literal:
00081   case agt_tvar:
00082   case agt_var:
00083   case agt_definition:
00084   case agt_type:
00085   case agt_bindingPattern:
00086   case agt_valuePattern:
00087   case agt_expr:
00088   case agt_eform:
00089   case agt_type_definition:
00090   case agt_value_definition:
00091   case at_letbindings:
00092   case at_letbinding:
00093   case agt_CompilationUnit:
00094   case at_ifident:
00095   case at_ifsel:
00096   case at_localFrame:
00097   case at_frameBindings:
00098   case agt_tc_definition:
00099   case agt_if_definition:
00100   case agt_category:
00101   case agt_tcdecl:
00102   case agt_use_cases:
00103   case agt_sometcreqs:
00104   case agt_ow:
00105   case at_irefCat:
00106   case at_refCat:
00107   case at_valCat:
00108   case at_opaqueCat:
00109   case at_tcdecls:
00110   case at_tyfn:
00111   case at_super:
00112   case at_tcreqs:
00113   case at_itcreqs:
00114   case at_tcreq:
00115   case at_method_decls:
00116   case at_method_decl: 
00117   case at_usesel:
00118   case at_use_case:
00119   case at_iuse_case:
00120   case at_identList:
00121   case at_container:
00122     {
00123       errStream << ast->loc.asString() << "Internal Compiler Error. " 
00124            << "Function loopOK, unexpected astType: " 
00125            << ast->astTypeName()
00126            << std::endl;
00127       
00128       errFree = false;
00129       break;
00130     } 
00131     
00132   case at_ident:
00133     {
00134       // Should this be checked?
00135       if(loops.size() && ast->symbolDef != NULL) {
00136         for(size_t i=0; i < loops.size() - 1; i++)
00137           if(ast->symbolDef == loops[i]) {
00138             errStream << ast->loc << ": Usage of loop variable " 
00139                       << ast->s << " violates nesting."
00140                       << " i = " << i
00141                       << " ## " << loops[i]->asString() << " ## " << ast->asString()
00142                       << std::endl;
00143             errFree = false;
00144             break;
00145           }
00146         
00147         if(ast->symbolDef == loops[loops.size()-1]) {
00148           if(noLVuse) {
00149             errStream << ast->loc << ": Loop variable " << ast->s 
00150                       << " is either escaping, or is at a non-tail position." 
00151                       << std::endl;
00152             errFree = false;
00153           }
00154           else {
00155             ast->markFlags(LOOP_APP);
00156           }
00157         }
00158       }
00159       break;
00160     }
00161     
00162 
00163 
00164   case at_unit:
00165   case at_boolLiteral:
00166   case at_charLiteral:
00167   case at_intLiteral:
00168   case at_floatLiteral:
00169   case at_stringLiteral:
00170   case at_bitfield:
00171   case at_deftypeclass:
00172   case at_definstance:
00173   case at_declunionr:
00174   case at_declstructr:
00175   case at_use:
00176   case at_import:
00177   case at_stateful_import:
00178   case at_provide:
00179   case at_stateful_provide:
00180   case at_declares:
00181   case at_declare:
00182   case at_tvlist:
00183   case at_methodType:
00184   case at_typeapp:
00185   case at_arrayType:
00186   case at_vectorType:
00187   case at_refType:
00188   case at_valType:
00189   case at_primaryType:
00190   case at_pairType:
00191   case at_cpairType:
00192   case at_fnargVec:
00193   case at_mutableType: 
00194   case at_defunion:
00195   case at_defstruct:
00196   case at_constructors:
00197   case at_fields:
00198   case at_constructor:
00199   case at_field:
00200   case at_defexception:
00201   case at_declValue:
00202   case at_fn: 
00203   case at_identPattern:
00204   case at_literalPattern:
00205   case at_unitPattern:
00206   case at_pairPattern:
00207   case at_cpairPattern:
00208   case at_applyPattern:
00209   case at_argVec:
00210     {
00211       break;
00212     }
00213     
00214   case at_start:
00215     {
00216       // match at_module/at_interface
00217       LOOPOK(errStream, ast->children[1], loops, noLVuse);
00218       break;
00219     }
00220 
00221   case at_interface:
00222   case at_module:
00223     {
00224       // match agt_definition*    
00225       size_t c = (ast->astType == at_module)?0:1;
00226       for(; c < ast->children.size(); c++)
00227         LOOPOK(errStream, ast->children[c], loops, noLVuse);
00228       break;
00229     }
00230 
00231 
00232   case at_define:
00233     {
00234       LOOPOK(errStream, ast->children[1], loops, noLVuse);
00235       break;
00236     }
00237 
00238   case at_tqexpr:
00239     {
00240       LOOPOK(errStream, ast->children[0], loops, noLVuse);
00241       break;
00242     }
00243     
00244   case at_ibegin:
00245   case at_begin:
00246     {
00247       // match agt_expr+
00248       for(size_t c = 0; c < ast->children.size() -1; c++)
00249         LOOPOK(errStream, ast->children[c], loops, true);
00250       LOOPOK(errStream, ast->children[ast->children.size() -1], 
00251              loops, noLVuse);
00252       break;
00253     }
00254     
00255   case at_select:
00256     {
00257       // match agt_expr
00258       LOOPOK(errStream, ast->children[0], loops, true);
00259       break; 
00260     }
00261 
00262   case at_lambda:
00263   case at_ilambda:
00264     {
00265       LOOPOK(errStream, ast->children[1], loops, true);      
00266       break;
00267     }
00268     
00269   case at_apply:
00270     {
00271       LOOPOK(errStream, ast->children[0], loops, noLVuse);
00272       for(size_t c = 1; c < ast->children.size(); c++)
00273         LOOPOK(errStream, ast->children[c], loops, true);
00274       break;
00275     }
00276     
00277   case at_ucon_apply:
00278   case at_struct_apply:
00279     {
00280       for(size_t c = 1; c < ast->children.size(); c++)
00281         LOOPOK(errStream, ast->children[c], loops, true);
00282       break;
00283     }
00284 
00285   case at_if:
00286     {
00287       // match agt_expr
00288       LOOPOK(errStream, ast->children[0], loops, true);
00289       LOOPOK(errStream, ast->children[1], loops, noLVuse);
00290       LOOPOK(errStream, ast->children[2], loops, noLVuse);
00291       break;
00292     }
00293     
00294   case at_and:
00295   case at_or:
00296   case at_deref:
00297   case at_array_length:
00298   case at_vector_length:
00299   case at_array_nth:
00300   case at_vector_nth:
00301   case at_vector:
00302   case at_array:
00303   case at_pair:
00304   case at_cpair:
00305   case at_makevector:    
00306   case at_setbang:
00307     {
00308       for(size_t c = 0; c < ast->children.size(); c++)
00309         LOOPOK(errStream, ast->children[c], loops, true);
00310       break;
00311     }
00312     
00313   case at_cond:
00314   case at_cond_legs:
00315   case at_case:
00316   case at_case_legs:
00317   case at_otherwise:
00318   case at_try:
00319   case at_throw:
00320     {
00321       for(size_t c = 0; c < ast->children.size(); c++)
00322         LOOPOK(errStream, ast->children[c], loops, noLVuse);
00323       break;
00324     }
00325 
00326   case at_cond_leg:
00327     {
00328       LOOPOK(errStream, ast->children[0], loops, true);
00329       LOOPOK(errStream, ast->children[1], loops, noLVuse);
00330       break;
00331     }
00332 
00333   case at_case_leg:
00334     {
00335       LOOPOK(errStream, ast->children[1], loops, noLVuse);
00336       break;
00337     }
00338     
00339   case at_let:
00340   case at_letrec:
00341   case at_letStar:
00342     {
00343       GCPtr<AST> lbs = ast->children[0];
00344       for(size_t c = 0; c < lbs->children.size(); c++) {
00345         GCPtr<AST> lb = lbs->children[c];
00346         LOOPOK(errStream, lb->children[1], loops, true);
00347       }
00348       
00349       LOOPOK(errStream, ast->children[1], loops, noLVuse);
00350       break;
00351     }
00352     
00353   case at_loop:
00354     {
00355       loops.append(ast->children[0]);
00356       GCPtr<AST> lbs = ast->children[1];
00357       for(size_t c = 0; c < lbs->children.size(); c++) {
00358         GCPtr<AST> lb = lbs->children[c];
00359         LOOPOK(errStream, lb->children[1], loops, true);
00360       }
00361       
00362       LOOPOK(errStream, ast->children[2], loops, false);
00363       loops.remove(loops.size() - 1);
00364       break;
00365     }
00366   }
00367   return errFree; 
00368 }
00369 
00370 bool
00371 UocInfo::do_loopchk(std::ostream& errStream,
00372                     bool init, unsigned long flags)
00373 {
00374     bool errFree = true;
00375     CVector< GCPtr<AST> > loops;
00376     errFree = loopOK(errStream, ast, loops, false);
00377     return errFree;
00378 }

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