00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
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
00217 LOOPOK(errStream, ast->children[1], loops, noLVuse);
00218 break;
00219 }
00220
00221 case at_interface:
00222 case at_module:
00223 {
00224
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
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
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
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 }