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 <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
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
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
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
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
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
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
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(); ) {
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;
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
00402
00403
00404 CHKERR(errFree, RandT(errStream, this, true,
00405 PP_SYM_FLAGS, PP_TYP_FLAGS));
00406
00407 return errFree;
00408 }
00409