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 <assert.h>
00039 #include <stdint.h>
00040 #include <stdlib.h>
00041 #include <dirent.h>
00042 #include <fstream>
00043 #include <iostream>
00044 #include <sstream>
00045 #include <string>
00046 #include <set>
00047
00048 #include <libsherpa/UExcept.hxx>
00049
00050 #include "Options.hxx"
00051 #include "UocInfo.hxx"
00052 #include "AST.hxx"
00053 #include "Type.hxx"
00054 #include "TypeInfer.hxx"
00055 #include "inter-pass.hxx"
00056
00057 using namespace std;
00058 using namespace boost;
00059 using namespace sherpa;
00060
00061 typedef set<shared_ptr<AST> > AstSet;
00062
00067 static void
00068 clearusedef(shared_ptr<AST> ast)
00069 {
00070 ast->flags &= ~(ID_IS_CLOSED|ID_IS_CAPTURED|ID_NEEDS_HEAPIFY);
00071
00072 for (size_t c=0; c < ast->children.size(); c++)
00073 clearusedef(ast->child(c));
00074 }
00075
00076
00077
00078 static bool
00079 used(shared_ptr<AST> id, shared_ptr<AST> ast)
00080 {
00081 if (ast->astType == at_ident && ast->symbolDef == id) {
00082 assert(ast != id);
00083 assert(!id->symbolDef);
00084 return true;
00085 }
00086
00087 for (size_t i=0; i < ast->children.size(); i++)
00088 if (used(id, ast->child(i)))
00089 return true;
00090
00091 return false;
00092 }
00093
00094
00099 static bool
00100 findusedef(std::ostream &errStream,
00101 shared_ptr<AST> topAst, shared_ptr<AST> ast, const int mode,
00102
00103
00104 AstSet& boundVars,
00105
00106
00107 AstSet& freeVars)
00108 {
00109 bool errFree = true;
00110 switch(ast->astType) {
00111 case at_letGather:
00112 assert(false);
00113
00114 case at_Null:
00115 case at_AnyGroup:
00116 case agt_literal:
00117 case agt_tvar:
00118 case agt_var:
00119 case agt_definition:
00120 case agt_type:
00121 case agt_expr:
00122 case agt_expr_or_define:
00123 case agt_eform:
00124 case agt_type_definition:
00125 case agt_value_definition:
00126 case agt_openclosed:
00127 case at_letbindings:
00128 case at_letbinding:
00129 case at_loopbindings:
00130 case at_loopbinding:
00131 case agt_CompilationUnit:
00132 case at_ifident:
00133 case at_localFrame:
00134 case at_frameBindings:
00135 case agt_tc_definition:
00136 case agt_if_definition:
00137 case agt_category:
00138 case agt_ow:
00139 case agt_qtype:
00140 case agt_fielditem:
00141 case at_unboxedCat:
00142 case at_boxedCat:
00143 case at_oc_closed:
00144 case at_oc_open:
00145 case at_opaqueCat:
00146 case at_tcdecls:
00147 case at_tyfn:
00148 case at_usesel:
00149 case at_identList:
00150 case at_container:
00151 case at_defrepr:
00152
00153
00154
00155
00156
00157 case at_reprctrs:
00158 case at_reprctr:
00159 case at_reprrepr:
00160 case at_unit:
00161 case at_boolLiteral:
00162 case at_charLiteral:
00163 case at_intLiteral:
00164 case at_floatLiteral:
00165 case at_stringLiteral:
00166 case at_bitfieldType:
00167 case at_declunion:
00168 case at_declstruct:
00169 case at_declrepr:
00170 case at_importAs:
00171 case at_provide:
00172 case at_import:
00173 case at_ifsel:
00174 case at_declares:
00175 case at_declare:
00176 case at_tvlist:
00177 case at_docString:
00178 case agt_ucon:
00179 case agt_uselhs:
00180 break;
00181
00182
00183 case at_ident:
00184 {
00185
00186
00187
00188
00189 switch(mode) {
00190
00191 case TYPE_MODE:
00192 break;
00193
00194 case LOCAL_MODE:
00195 boundVars.insert(ast);
00196 break;
00197
00198 case USE_MODE:
00199 {
00200 if (!ast->symbolDef)
00201 std::cerr << "Warning: No definition for "
00202 << ast->fqn << std::endl;
00203
00204
00205
00206 if (ast->symbolDef->isGlobal())
00207 break;
00208
00209 if (boundVars.find(ast->symbolDef) != boundVars.end())
00210 break;
00211
00212 if (Options::noAlloc) {
00213 errStream << ast->loc << ": "
00214 << "Usage of identifier " << ast->s
00215 << " mandates closure conversion -- "
00216 << "disallowed in noAlloc mode"
00217 << std::endl;
00218 errFree = false;
00219 }
00220
00221 ast->flags |= ID_IS_CLOSED;
00222 ast->symbolDef->flags |= ID_IS_CAPTURED;
00223
00224 if(ast->flags & ARG_BYREF) {
00225 errStream << ast->loc << ": Non-Capturable by-ref variable "
00226 << ast->s
00227 << " captured in a closure."
00228 << std::endl;
00229 errFree = false;
00230 }
00231
00232 if(ast->symType->isNonEscaping()) {
00233 errStream << ast->loc << ": Variable " << ast->s
00234 << " with Non-Capturable type "
00235 << ast->symType->asBlockString()
00236 << " captured in a closure."
00237 << std::endl;
00238 return false;
00239 }
00240
00241 if (ast->symbolDef->getType()->needsCaptureConversion()) {
00242 ast->flags |= ID_NEEDS_HEAPIFY;
00243 ast->symbolDef->flags |= ID_NEEDS_HEAPIFY;
00244 }
00245
00246 DEBUG(CLCONV) std::cerr << "Append " << ast->symbolDef->fqn
00247 << " to freeVars" << std::endl;
00248
00249 freeVars.insert(ast->symbolDef);
00250 break;
00251 }
00252 case NULL_MODE:
00253 default:
00254 break;
00255 }
00256 break;
00257 }
00258
00259 case at_deftypeclass:
00260 {
00261 CHKERR(errFree, findusedef(errStream, topAst, ast->child(3),
00262 TYPE_MODE, boundVars, freeVars));
00263 break;
00264 }
00265
00266 case at_definstance:
00267 {
00268 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00269 TYPE_MODE, boundVars, freeVars));
00270 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00271 USE_MODE, boundVars, freeVars));
00272 CHKERR(errFree, findusedef(errStream, topAst, ast->child(2),
00273 TYPE_MODE, boundVars, freeVars));
00274 break;
00275 }
00276
00277 case at_method_decl:
00278 {
00279 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00280 USE_MODE, boundVars, freeVars));
00281 break;
00282 }
00283
00284 case at_defunion:
00285 case at_defstruct:
00286 {
00287 CHKERR(errFree, findusedef(errStream, topAst, ast->child(4),
00288 TYPE_MODE, boundVars, freeVars));
00289 break;
00290 }
00291
00292 case at_proclaim:
00293 {
00294 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00295 TYPE_MODE, boundVars, freeVars));
00296 break;
00297 }
00298
00299 case at_fn:
00300 case at_methType:
00301 {
00302 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00303 TYPE_MODE, boundVars, freeVars));
00304 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00305 TYPE_MODE, boundVars, freeVars));
00306 break;
00307 }
00308
00309 case at_define:
00310 case at_recdef:
00311 {
00312 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00313 USE_MODE, boundVars, freeVars));
00314 break;
00315 }
00316
00317 case at_identPattern:
00318 {
00319 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00320 mode, boundVars, freeVars));
00321 break;
00322 }
00323
00324 case at_typeAnnotation:
00325 {
00326 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00327 USE_MODE, boundVars, freeVars));
00328 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00329 TYPE_MODE, boundVars, freeVars));
00330 break;
00331 }
00332
00333 case at_suspend:
00334 {
00335 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00336 USE_MODE, boundVars, freeVars));
00337 break;
00338 }
00339
00340 case at_fqCtr:
00341 {
00342 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00343 TYPE_MODE, boundVars, freeVars));
00344 break;
00345 }
00346
00347 case at_sizeof:
00348 case at_bitsizeof:
00349 {
00350 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00351 TYPE_MODE, boundVars, freeVars));
00352 break;
00353 }
00354
00355 case at_select:
00356 case at_sel_ctr:
00357 {
00358 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00359 USE_MODE, boundVars, freeVars));
00360 break;
00361 }
00362
00363 case at_lambda:
00364 {
00365 if (ast == topAst) {
00366 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00367 LOCAL_MODE, boundVars, freeVars));
00368 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00369 USE_MODE, boundVars, freeVars));
00370 }
00371 else {
00372 AstSet freeVars;
00373 AstSet boundVars;
00374
00375 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00376 LOCAL_MODE, boundVars, freeVars));
00377 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00378 USE_MODE, boundVars, freeVars));
00379 }
00380
00381 break;
00382 }
00383
00384 case at_interface:
00385 case at_module:
00386 {
00387 for (size_t c=0; c < ast->children.size(); c++)
00388 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00389 NULL_MODE, boundVars, freeVars));
00390 break;
00391 }
00392 case at_tcmethods:
00393 case at_tcmethod_binding:
00394 {
00395 for (size_t c=0; c < ast->children.size(); c++)
00396 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00397 USE_MODE, boundVars, freeVars));
00398 break;
00399 }
00400
00401 case at_method_decls:
00402 case at_tcapp:
00403 case at_typeapp:
00404 case at_exceptionType:
00405 case at_dummyType:
00406 case at_arrayType:
00407 case at_vectorType:
00408 case at_boxedType:
00409 case at_byRefType:
00410 case at_arrayRefType:
00411 case at_unboxedType:
00412 case at_primaryType:
00413 case at_fnargVec:
00414 case at_mutableType:
00415 case at_constType:
00416 case at_qualType:
00417 case at_constraints:
00418 case at_constructors:
00419 case at_fields:
00420 case at_fill:
00421 {
00422 for (size_t c=0; c < ast->children.size(); c++)
00423 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00424 TYPE_MODE, boundVars, freeVars));
00425 break;
00426 }
00427
00428 case at_methdecl:
00430 case at_constructor:
00431 case at_field:
00432 case at_fieldType:
00433 case at_defexception:
00434 {
00435 for (size_t c=1; c<ast->children.size();c++)
00436 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00437 TYPE_MODE, boundVars, freeVars));
00438 break;
00439 }
00440
00441 case at_argVec:
00442 {
00443 for (size_t c=0; c<ast->children.size();c++)
00444 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00445 LOCAL_MODE, boundVars, freeVars));
00446 break;
00447 }
00448
00449 case at_setbang:
00450 {
00451 for (size_t c=0; c<ast->children.size();c++)
00452 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00453 USE_MODE, boundVars, freeVars));
00454 break;
00455 }
00456
00457 case at_begin:
00458 case at_allocREF:
00459 case at_setClosure:
00460 case at_copyREF:
00461 case at_mkClosure:
00462 case at_and:
00463 case at_or:
00464 case at_cond:
00465 case at_cond_legs:
00466 case at_condelse:
00467 case at_dup:
00468 case at_deref:
00469 case at_usw_legs:
00470 case at_throw:
00471 #ifdef HAVE_INDEXABLE_LENGTH_OPS
00472 case at_array_length:
00473 case at_array_ref_length:
00474 case at_vector_length:
00475 #endif
00476 case at_array_nth:
00477 case at_array_ref_nth:
00478 case at_vector_nth:
00479 case at_vector:
00480 case at_array:
00481 case at_MakeVector:
00482 case at_mkArrayRef:
00483 case at_apply:
00484 {
00485 for (size_t c=0; c<ast->children.size();c++)
00486 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00487 USE_MODE, boundVars, freeVars));
00488 break;
00489 }
00490
00491 case at_nth:
00492
00493 assert(false);
00494 break;
00495
00496 case at_labeledBlock:
00497 case at_return_from:
00498 {
00499 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00500 USE_MODE, boundVars, freeVars));
00501 break;
00502 }
00503
00504 case at_uswitch:
00505 case at_try:
00506 {
00507 for (size_t c=0; c<ast->children.size();c++)
00508 if (c != IGNORE(ast))
00509 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00510 USE_MODE, boundVars, freeVars));
00511 break;
00512 }
00513
00514 case at_inner_ref:
00515 {
00516 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00517 USE_MODE, boundVars, freeVars));
00518
00519 if (ast->flags & INNER_REF_NDX)
00520 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00521 USE_MODE, boundVars, freeVars));
00522
00523 break;
00524 }
00525
00526 case at_ucon_apply:
00527 case at_struct_apply:
00528 case at_object_apply:
00529 {
00530 for (size_t c=1; c<ast->children.size();c++)
00531 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00532 USE_MODE, boundVars, freeVars));
00533 break;
00534 }
00535
00536 case at_if:
00537 case at_when:
00538 case at_unless:
00539 {
00540 for (size_t c=0; c<ast->children.size();c++)
00541 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00542 USE_MODE, boundVars, freeVars));
00543 break;
00544 }
00545
00546 case at_cond_leg:
00547 {
00548 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00549 USE_MODE, boundVars, freeVars));
00550 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00551 USE_MODE, boundVars, freeVars));
00552 break;
00553 }
00554
00555 case at_otherwise:
00556 case at_usw_leg:
00557 {
00558 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00559 LOCAL_MODE, boundVars, freeVars));
00560 for (size_t c=1; c<ast->children.size();c++)
00561 CHKERR(errFree, findusedef(errStream, topAst, ast->child(c),
00562 USE_MODE, boundVars, freeVars));
00563 break;
00564 }
00565
00566 case at_loop:
00567 {
00568 shared_ptr<AST> lbs = ast->child(0);
00569
00570 for (size_t c = 0; c < lbs->children.size(); c++) {
00571 shared_ptr<AST> lb = lbs->child(c);
00572 CHKERR(errFree, findusedef(errStream, topAst, lb->child(1),
00573 USE_MODE, boundVars, freeVars));
00574 }
00575
00576
00577 for (size_t c = 0; c < lbs->children.size(); c++) {
00578 shared_ptr<AST> lb = lbs->child(c);
00579 CHKERR(errFree, findusedef(errStream, topAst, lb->child(0),
00580 LOCAL_MODE, boundVars, freeVars));
00581 }
00582
00583
00584 for (size_t c = 0; c < lbs->children.size(); c++) {
00585 shared_ptr<AST> lb = lbs->child(c);
00586 CHKERR(errFree, findusedef(errStream, topAst, ast->child(2),
00587 USE_MODE, boundVars, freeVars));
00588 }
00589
00590
00591 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00592 USE_MODE, boundVars, freeVars));
00593
00594 CHKERR(errFree, findusedef(errStream, topAst, ast->child(2),
00595 USE_MODE, boundVars, freeVars));
00596 break;
00597 }
00598
00599 case at_looptest:
00600 {
00601 CHKERR(errFree, findusedef(errStream, topAst, ast->child(0),
00602 USE_MODE, boundVars, freeVars));
00603 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00604 USE_MODE, boundVars, freeVars));
00605 break;
00606 }
00607
00608 case at_letStar:
00609 case at_let:
00610 case at_letrec:
00611 {
00612 shared_ptr<AST> lbs = ast->child(0);
00613
00614
00615 for (size_t c = 0; c < lbs->children.size(); c++) {
00616 shared_ptr<AST> lb = lbs->child(c);
00617
00618 CHKERR(errFree, findusedef(errStream, topAst, lb->child(1),
00619 USE_MODE, boundVars, freeVars));
00620 CHKERR(errFree, findusedef(errStream, topAst, lb->child(0),
00621 LOCAL_MODE, boundVars, freeVars));
00622 }
00623
00624 CHKERR(errFree, findusedef(errStream, topAst, ast->child(1),
00625 USE_MODE, boundVars, freeVars));
00626 break;
00627 }
00628 }
00629
00630 return errFree;
00631 }
00632
00633 shared_ptr<AST>
00634 cl_rewrite_captured_idents(shared_ptr<AST> ast, shared_ptr<AST> clenvName)
00635 {
00636 for (size_t c = 0; c < ast->children.size(); c++)
00637 ast->child(c) =
00638 cl_rewrite_captured_idents(ast->child(c), clenvName);
00639
00640 switch(ast->astType) {
00641 case at_ident:
00642 {
00643 if (ast->flags & ID_IS_CLOSED) {
00644 shared_ptr<AST> clUse = AST::make(at_select, ast->loc);
00645 clUse->addChild(clenvName->getDeepCopy());
00646 clUse->addChild(ast);
00647
00648 ast = clUse;
00649 }
00650
00651 break;
00652 }
00653 default:
00654 break;
00655 }
00656
00657 return ast;
00658 }
00659
00660
00661 static shared_ptr<AST>
00662 getClenvUse(shared_ptr<AST> ast, shared_ptr<AST> clenvName,
00663 std::vector<std::string>& tvs)
00664 {
00665 shared_ptr<AST> clType;
00666 if (tvs.size()) {
00667 shared_ptr<AST> typeApp = AST::make(at_typeapp, ast->loc);
00668 typeApp->addChild(clenvName->Use());
00669
00670 for (size_t i=0; i<tvs.size(); i++) {
00671 shared_ptr<AST> tv = AST::make(at_ident, ast->loc);
00672 tv->identType = id_tvar;
00673 tv->s = tv->fqn.ident = tvs[i];
00674 typeApp->addChild(tv);
00675 }
00676
00677 clType = typeApp;
00678 }
00679 else
00680 clType = clenvName->Use();
00681
00682 return clType;
00683 }
00684
00685
00686 #if 0
00687 static void
00688 rewriteMyCapture(shared_ptr<AST> ast, shared_ptr<AST> me, shared_ptr<AST> him)
00689 {
00690 if (ast->astType == at_set_closure) {
00691 shared_ptr<AST> envApp = ast->child(1);
00692 for (size_t c=1; c < envApp->children.size(); c++)
00693 if (envApp->child(c)->symbolDef == me)
00694 envApp->child(c) = him->Use();
00695 return;
00696 }
00697
00698 for (size_t c=0; c < ast->children.size(); c++)
00699 rewriteMyCapture(ast->child(c), me, him);
00700 }
00701 #endif
00702
00703
00704
00705
00706
00707 static shared_ptr<AST>
00708 cl_convert_ast(shared_ptr<AST> ast,
00709 std::vector<shared_ptr<AST> >& outAsts,
00710 bool shouldHoist)
00711 {
00712 bool hoistChildren = true;
00713
00714
00715 if (ast->astType == at_define || ast->astType == at_recdef) {
00716 hoistChildren = false;
00717
00718 shared_ptr<AST> ident = ast->getID();
00719 if (!ident->decl) {
00720 shared_ptr<AST> proclaim = AST::make(at_proclaim, ast->loc,
00721 ident->getDeepCopy(),
00722 cl_convert_ast(ident->symType->asAST(ast->loc),
00723 outAsts, hoistChildren),
00724 AST::make(at_constraints, ast->loc));
00725
00726 if (ident->externalName.size())
00727 proclaim->child(0)->flags |= DEF_IS_EXTERNAL;
00728
00729 ast->flags |= PROCLAIM_IS_INTERNAL;
00730 outAsts.push_back(proclaim);
00731 }
00732 }
00733
00734
00735 for (size_t c = 0; c < ast->children.size(); c++)
00736 ast->child(c) =
00737 cl_convert_ast(ast->child(c), outAsts, hoistChildren);
00738
00739
00740 switch(ast->astType) {
00741 case at_letrec:
00742 {
00743 shared_ptr<AST> lbs = ast->child(0);
00744 shared_ptr<AST> expr = ast->child(1);
00745
00746
00747 shared_ptr<AST> ccs = AST::make(at_begin, expr->loc);
00748
00749 for (size_t c=0; c < lbs->children.size(); c++) {
00750 shared_ptr<AST> lb = lbs->child(c);
00751 shared_ptr<AST> id = lb->child(0)->child(0);
00752
00753 shared_ptr<AST> rhs = lb->child(1);
00754
00755
00756
00757
00758 if (used(id, lbs)) {
00759 assert(id->flags & ID_IS_CAPTURED);
00760 shared_ptr<AST> qual =
00761 id->symType->getBareType()->asAST(rhs->loc);
00762 qual = cl_convert_ast(qual, outAsts, hoistChildren);
00763 shared_ptr<AST> ac = AST::make(at_allocREF, rhs->loc, qual);
00764 shared_ptr<AST> cc = AST::make(at_copyREF, rhs->loc, id->Use(), rhs);
00765 ccs->children.push_back(cc);
00766 lb->child(1) = ac;
00767 }
00768 }
00769
00770 ccs->addChild(expr);
00771
00772 ast->child(1) = ccs;
00773
00774 break;
00775 }
00776
00777 case at_lambda:
00778 {
00779 AstSet freeVars;
00780 AstSet boundVars;
00781
00782 shared_ptr<AST> clenvName = GC_NULL;
00783 shared_ptr<TvPrinter> tvP = TvPrinter::make();
00784
00785 DEBUG(CLCONV) std::cerr << "Processing lambda. " << std::endl;
00786
00787
00788
00789
00790 findusedef(std::cerr, ast, ast, NULL_MODE, boundVars, freeVars);
00791
00792 std::vector<std::string> tvs;
00793
00794
00795
00796 bool needsClosure = !freeVars.empty();
00797 if (needsClosure) {
00798
00799 DEBUG(CLCONV) std::cerr << "Need to generate closure struct. "
00800 << std::endl;
00801
00803
00804 shared_ptr<AST> defStruct = AST::make(at_defstruct, ast->loc);
00805
00806
00807 clenvName = AST::genSym(ast, "clenv");
00808 clenvName->identType = id_struct;
00809 clenvName->flags |= (ID_IS_GLOBAL);
00810 defStruct->addChild(clenvName);
00811
00812
00813 shared_ptr<AST> tvlist = AST::make(at_tvlist, ast->loc);
00814 defStruct->addChild(tvlist);
00815
00816 defStruct->addChild(AST::make(at_boxedCat));
00817
00818 defStruct->addChild(AST::make(at_declares));
00819
00820 shared_ptr<AST> fields = AST::make(at_fields, ast->loc);
00821 defStruct->addChild(fields);
00822
00823 defStruct->addChild(AST::make(at_constraints, ast->loc));
00824
00825 for (AstSet::iterator fv = freeVars.begin();
00826 fv != freeVars.end(); ++fv) {
00827 assert((*fv)->astType == at_ident);
00828 shared_ptr<AST> field = AST::make(at_field, ast->loc);
00829 shared_ptr<AST> ident = AST::make(at_ident, ast->loc);
00830 ident->s = ident->fqn.ident = (*fv)->s;
00831
00832 field->addChild(ident);
00833 shared_ptr<AST> fvType = (*fv)->symType->asAST(ast->loc, tvP);
00834 fvType = cl_convert_ast(fvType, outAsts, hoistChildren);
00835 field->addChild(fvType);
00836
00837 fields->addChild(field);
00838 }
00839
00840
00841
00842
00843
00844 tvs = tvP->getAllTvarStrings();
00845
00846 for (size_t i=0; i < tvs.size(); i++) {
00847 shared_ptr<AST> tv = AST::make(at_ident, tvlist->loc);
00848 tv->identType = id_tvar;
00849 tv->s = tv->fqn.ident = tvs[i];
00850 tvlist->children.push_back(tv);
00851 }
00852
00853
00854
00855 outAsts.push_back(defStruct);
00856 }
00857
00859 if (shouldHoist) {
00860 DEBUG(CLCONV) std::cerr << "Need to hoist this lambda. "
00861 << std::endl;
00862 DEBUG(CLCONV) ast->PrettyPrint(std::cerr);
00863
00864
00865
00866
00867 shared_ptr<AST> newDef = AST::make(at_recdef, ast->loc);
00868
00869 shared_ptr<AST> lamName = AST::genSym(ast, "lam");
00870 lamName->identType = id_value;
00871 lamName->flags |= ID_IS_GLOBAL;
00872
00873 shared_ptr<AST> lamType = ast->symType->asAST(ast->loc);
00874
00875
00876
00877 lamType = cl_convert_ast(lamType, outAsts, hoistChildren);
00878 shared_ptr<AST> lamPat = AST::make(at_identPattern, ast->loc,
00879 lamName, lamType);
00880 newDef->addChild(lamPat);
00881 newDef->addChild(ast);
00882 newDef->addChild(AST::make(at_constraints));
00883
00884 if (needsClosure) {
00885 newDef->flags |= LAM_NEEDS_TRANS;
00886
00887
00888
00889 shared_ptr<AST> argVec = ast->child(0);
00890 shared_ptr<AST> body = ast->child(1);
00891 shared_ptr<AST> clArgName = AST::make(at_ident, ast->loc);
00892 clArgName->s = clArgName->fqn.ident = "__clArg";
00893 shared_ptr<AST> clArgPat = AST::make(at_identPattern, ast->loc, clArgName);
00894
00895
00896 shared_ptr<AST> clType = getClenvUse(ast, clenvName, tvs);
00897
00898 lamType->child(0)->children.insert(lamType->child(0)->children.begin(),
00899 clType);
00900 clArgPat->addChild(clType->getDeepCopy());
00901 argVec->children.insert(argVec->children.begin(), clArgPat);
00902
00903 ast->child(1) = cl_rewrite_captured_idents(body, clArgName);
00904 }
00905
00906
00907 outAsts.push_back(newDef);
00908
00909 DEBUG(CLCONV) ast->PrettyPrint(newDef);
00910
00911
00912
00913 shared_ptr<AST> lamUse = lamName->Use();
00914 if (freeVars.size()) {
00915 shared_ptr<AST> mkEnv = AST::make(at_struct_apply, ast->loc);
00916 mkEnv->addChild(clenvName->Use());
00917 for (AstSet::iterator fv = freeVars.begin();
00918 fv != freeVars.end(); ++fv)
00919 mkEnv->addChild((*fv)->Use());
00920
00921 shared_ptr<AST> mkClo = AST::make(at_mkClosure, ast->loc, mkEnv, lamUse);
00922 ast = mkClo;
00923 }
00924 else {
00925 ast = lamUse;
00926 }
00927 }
00928 break;
00929 }
00930
00931 default:
00932 {
00933 break;
00934 }
00935 }
00936
00937 return ast;
00938 }
00939
00940 void
00941 cl_convert(shared_ptr<UocInfo> uoc)
00942 {
00943 std::vector<shared_ptr<AST> > outAsts;
00944
00945 shared_ptr<AST> modOrIf = uoc->uocAst;
00946
00947 for (size_t c = 0;c < modOrIf->children.size(); c++) {
00948 shared_ptr<AST> child = modOrIf->child(c);
00949
00950 child = cl_convert_ast(child, outAsts, true);
00951 outAsts.push_back(child);
00952 }
00953
00954 modOrIf->children = outAsts;
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976 shared_ptr<AST>
00977 cl_heapify(shared_ptr<AST> ast)
00978 {
00979 switch(ast->astType) {
00980 case at_lambda:
00981 {
00982
00983
00984
00985 shared_ptr<AST> args = ast->child(0);
00986 shared_ptr<AST> body = ast->child(1);
00987
00988 shared_ptr<AST> bindings = AST::make(at_letbindings, body->loc);
00989
00990
00991 body = AST::make(at_let, body->loc, bindings, body);
00992 body->addChild(AST::make(at_constraints));
00993
00994 bool atleastOneHeapified = false;
00995
00996
00997
00998 for (size_t i = 0; i < args->children.size(); i++) {
00999 shared_ptr<AST> arg = args->child(i)->child(0);
01000 if ((arg->flags & ID_NEEDS_HEAPIFY) == 0)
01001 continue;
01002
01003 atleastOneHeapified = true;
01004
01005
01006
01007 shared_ptr<AST> newArg = AST::make(at_ident, arg->loc);
01008 newArg->s = newArg->fqn.ident = arg->s;
01009 args->child(i)->child(0) = newArg;
01010
01011
01012
01013 shared_ptr<AST> letIdent = arg;
01014 shared_ptr<AST> letExpr = newArg->Use();
01015 shared_ptr<AST> identPattern = AST::make(at_identPattern, arg->loc, letIdent);
01016
01017 shared_ptr<AST> theBinding = AST::make(at_letbinding, arg->loc,
01018 identPattern, letExpr);
01019 bindings->addChild(theBinding);
01020 }
01021
01022 if (atleastOneHeapified)
01023 ast->child(1) = body;
01024
01025
01026 ast->child(1) = cl_heapify(ast->child(1));
01027 break;
01028 }
01029
01030 case at_letbinding:
01031 {
01032 shared_ptr<AST> bpattern = ast->child(0);
01033 shared_ptr<AST> expr = ast->child(1);
01034
01035 assert(bpattern->astType == at_identPattern);
01036 shared_ptr<AST> ident = bpattern->child(0);
01037
01038 DEBUG(CLCONV) std::cerr << "Let binding for " << ident->s << std::endl;
01039
01040
01041 expr = cl_heapify(expr);
01042
01043 if (ident->flags & ID_NEEDS_HEAPIFY) {
01044
01045
01046 DEBUG(CLCONV) std::cerr << " Needs dup " << ident->s << std::endl;
01047
01048 assert (ident->flags & ID_IS_CAPTURED);
01049 expr = AST::make(at_dup, expr->loc, expr);
01050
01051
01052
01053
01054
01055 if (bpattern->children.size() == 2)
01056 bpattern->child(1) =
01057 AST::make(at_boxedType, bpattern->loc, bpattern->child(1));
01058 }
01059
01060 ast->child(1) = expr;
01061 break;
01062 }
01063
01064 case at_ident:
01065 {
01066
01067
01068
01069 DEBUG(CLCONV) std::cerr << "Processing " << ast->loc << ": "
01070 << ast->s << std::endl;
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081 shared_ptr<AST> def = (ast->symbolDef) ? ast->symbolDef : ast;
01082
01083 DEBUG(CLCONV) if (def->flags & ID_NEEDS_HEAPIFY)
01084 std::cerr << " needs heapify" << std::endl;
01085 DEBUG(CLCONV) if (def->flags & ID_IS_CAPTURED)
01086 std::cerr << " closed" << std::endl;
01087
01088 if (def->flags & ID_NEEDS_HEAPIFY) {
01089 DEBUG(CLCONV) std::cerr << "Needs deref " << ast->s << std::endl;
01090 ast = AST::make(at_deref, ast->loc, ast);
01091 }
01092 break;
01093 }
01094
01095 case at_uswitch:
01096 case at_try:
01097 {
01098 for (size_t c = 0; c < ast->children.size(); c++)
01099 if (c != IGNORE(ast))
01100 ast->child(c) = cl_heapify(ast->child(c));
01101 break;
01102 }
01103
01104 default:
01105 {
01106 for (size_t c = 0; c < ast->children.size(); c++)
01107 ast->child(c) = cl_heapify(ast->child(c));
01108 break;
01109 }
01110 }
01111
01112 return ast;
01113 }
01114
01115 bool
01116 UocInfo::be_clconv(std::ostream& errStream,
01117 bool init, unsigned long flags)
01118 {
01119 bool errFree = true;
01120
01121 AstSet freeVars;
01122 AstSet boundVars;
01123
01124 DEBUG(CLCONV) std::cerr << "findusedef 1" << std::endl;
01125
01126 CHKERR(errFree, findusedef(errStream, uocAst, uocAst,
01127 NULL_MODE, boundVars, freeVars));
01128
01129 if (!errFree)
01130 return false;
01131
01132 DEBUG(CLCONV) PrettyPrint(errStream, true);
01133
01134 DEBUG(CLCONV) std::cerr << "cl_heapify" << std::endl;
01135 uocAst = cl_heapify(uocAst);
01136
01137 DEBUG(CLCONV) PrettyPrint(errStream, true);
01138
01139 DEBUG(CLCONV) std::cerr << "RandT 1" << std::endl;
01140
01141 CHKERR(errFree,
01142 RandT(errStream, true, REF_SYM_FLAGS, REF_TYP_FLAGS));
01143 assert(errFree);
01144
01145 DEBUG(CLCONV) std::cerr << "findusedef 2" << std::endl;
01146
01147
01148 clearusedef(uocAst);
01149 findusedef(errStream, uocAst, uocAst, NULL_MODE,
01150 boundVars, freeVars);
01151
01152 DEBUG(CLCONV) PrettyPrint(errStream);
01153
01154 DEBUG(CLCONV) std::cerr << "cl_convert" << std::endl;
01155 cl_convert(shared_from_this());
01156
01157 DEBUG(CLCONV) PrettyPrint(errStream);
01158
01159 DEBUG(CLCONV) std::cerr << "RandT 2" << std::endl;
01160
01161 CHKERR(errFree,
01162 RandT(errStream, true, CL_SYM_FLAGS, CL_TYP_FLAGS));
01163
01164 if (!errFree)
01165 std::cerr << uocAst->asString();
01166 assert(errFree);
01167
01168 return true;
01169 }
01170
01171