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 <string>
00044 #include "AST.hxx"
00045 #include "Environment.hxx"
00046 #include "Unify.hxx"
00047 #include "inter-pass.hxx"
00048 #include "Special.hxx"
00049 #include "Instantiate.hxx"
00050
00051 #include "BUILD/TransitionParser.hxx"
00052
00053 using namespace boost;
00054 using namespace sherpa;
00055
00056 static inline shared_ptr<AST>
00057 newGrandLet(shared_ptr<AST> ref)
00058 {
00059 shared_ptr<AST> lbs = AST::make(at_letbindings, ref->loc);
00060 shared_ptr<AST> res = AST::make(at_ident, ref->loc);
00061 res->s = res->fqn.ident = "NULL";
00062 shared_ptr<AST> grandLet = AST::make(at_letStar, ref->loc, lbs, res);
00063 return grandLet;
00064 }
00065
00066
00067 static inline shared_ptr<AST>
00068 getLastLB(shared_ptr<AST> grandLet)
00069 {
00070 shared_ptr<AST> lbs = grandLet->child(0);
00071 return lbs->child(lbs->children.size() - 1);
00072 }
00073
00078 static void
00079 addIL(shared_ptr<AST> identList, shared_ptr<AST> id)
00080 {
00081 identList->children.push_back(id);
00082 }
00083
00084
00085
00086
00087 static inline shared_ptr<AST>
00088 UseCase(shared_ptr<AST> ast)
00089 {
00090 if (ast->astType == at_ident) {
00091 if (!ast->symbolDef)
00092 return ast->Use();
00093 else
00094 return ast->getTrueCopy();
00095 }
00096 else
00097 return ast;
00098 }
00099
00100 static shared_ptr<AST>
00101 addLB(shared_ptr<AST> grandLet, shared_ptr<AST> identList,
00102 shared_ptr<AST> ast, AstFlags lbFlags = NO_FLAGS,
00103 shared_ptr<AST> id=GC_NULL, bool addToIL=true)
00104 {
00105 if (!id)
00106 id = AST::genSym(ast, "t");
00107 id->symType = ast->symType;
00108 shared_ptr<AST> ip = AST::make(at_identPattern, id->loc, id);
00109 shared_ptr<AST> lb = AST::make(at_letbinding, ip->loc, ip, ast);
00110
00111
00112 lb->flags |= lbFlags;
00113 grandLet->child(0)->children.push_back(lb);
00114 if (addToIL)
00115 addIL(identList, id);
00116 return UseCase(id);
00117 }
00118
00119 #if 0
00120 static bool
00121 warnTmp(std::ostream &errStream, shared_ptr<AST> ast)
00122 {
00123 switch(ast->astType) {
00124 case at_ident:
00125 case at_select:
00126 case at_array_nth:
00127 case at_vector_nth:
00128 case at_deref:
00129 return true;
00130
00131 case at_typeAnnotation:
00132 return warnTmp(errStream, ast->child(0));
00133
00134 default:
00135 if (!ast->symType->isRefType()) {
00136 errStream << ast->loc << ": WARNING:"
00137 << " expression causing a temporary value copy"
00138 << " appears in location context"
00139 << "Type of expression is: "
00140 << ast->symType->asString()
00141 << std::endl;
00142 return false;
00143 }
00144 else {
00145 return true;
00146 }
00147 }
00148 }
00149 #endif
00150
00151 #define SETGL(exp, gl) \
00152 do { \
00153 if ((gl)->child(0)->children.size()) \
00154 (exp) = (gl); \
00155 else \
00156 (exp) = FEXPR(gl); \
00157 } while (0)
00158
00159
00160 #define SSA(errStream, uoc, ast, grandLet, identList, \
00161 parent, chno, flags) \
00162 do { \
00163 answer = ssa((errStream), (uoc), (ast), (grandLet), \
00164 (identList), (parent), (chno), (flags)); \
00165 if (answer == false) \
00166 errorFree = false; \
00167 } while (0)
00168
00169
00170 bool
00171 isTrivialInit(shared_ptr<AST> ast)
00172 {
00173 switch(ast->astType) {
00174
00175 case at_boolLiteral:
00176 case at_charLiteral:
00177 case at_intLiteral:
00178 case at_floatLiteral:
00179 case at_stringLiteral:
00180 case at_unit:
00181 case at_lambda:
00182 {
00183 return true;
00184 }
00185
00186 case at_ident:
00187 {
00188 return ast->symType->isAtomic();
00189 }
00190
00191 case at_typeAnnotation:
00192 {
00193 return isTrivialInit(ast->child(0));
00194 }
00195
00196 case at_begin:
00197 {
00198 for (size_t c = 0; c < ast->children.size(); c++)
00199 if (!isTrivialInit(ast->child(c)))
00200 return false;
00201 return true;
00202 }
00203
00204 default:
00205 return false;
00206 }
00207 }
00208
00209
00210 bool
00211 ssa(std::ostream& errStream,
00212 shared_ptr<UocInfo> uoc,
00213 shared_ptr<AST> ast,
00214 shared_ptr<AST> grandLet,
00215 shared_ptr<AST> identList,
00216 shared_ptr<AST> parent,
00217 const size_t chno,
00218 unsigned long flags)
00219 {
00220 bool errorFree = true, answer = false;
00221 size_t c = 0;
00222
00223
00224
00225 switch(ast->astType) {
00226
00227 case at_Null:
00228 case at_boxedCat:
00229 case at_unboxedCat:
00230 case at_oc_closed:
00231 case at_oc_open:
00232 case at_opaqueCat:
00233 case agt_category:
00234 case at_AnyGroup:
00235 case agt_literal:
00236 case agt_tvar:
00237 case agt_var:
00238 case agt_definition:
00239 case agt_type:
00240 case agt_expr:
00241 case agt_expr_or_define:
00242 case agt_eform:
00243 case agt_type_definition:
00244 case agt_value_definition:
00245 case agt_openclosed:
00246 case at_letbindings:
00247 case at_letbinding:
00248 case at_loopbindings:
00249 case at_loopbinding:
00250 case at_looptest:
00251 case agt_CompilationUnit:
00252 case agt_tc_definition:
00253 case agt_if_definition:
00254 case agt_ow:
00255 case agt_qtype:
00256 case agt_fielditem:
00257 case at_localFrame:
00258 case at_frameBindings:
00259 case at_ifident:
00260 case at_declares:
00261 case at_declare:
00262 case at_tvlist:
00263 case at_constructors:
00264 case at_constructor:
00265 case at_fields:
00266 case at_field:
00267 case at_methdecl:
00268 case at_fill:
00269 case at_tcdecls:
00270 case at_tyfn:
00271 case at_tcapp:
00272 case at_method_decls:
00273 case at_method_decl:
00274 case at_usesel:
00275 case at_identList:
00276 case at_container:
00277 case agt_ucon:
00278 case agt_uselhs:
00279
00280 case at_exceptionType:
00281 case at_dummyType:
00282 case at_boxedType:
00283 case at_unboxedType:
00284 case at_byRefType:
00285 case at_arrayRefType:
00286 case at_fn:
00287 case at_fnargVec:
00288 case at_primaryType:
00289 case at_arrayType:
00290 case at_vectorType:
00291 case at_mutableType:
00292 case at_constType:
00293 case at_typeapp:
00294 case at_bitfieldType:
00295 case at_qualType:
00296 case at_constraints:
00297 case at_fieldType:
00298 case at_methType:
00299
00300 case at_cond_legs:
00301 case at_cond_leg:
00302 case at_usw_legs:
00303 case at_usw_leg:
00304 case at_condelse:
00305 case at_otherwise:
00306 case at_letGather:
00307 {
00308 errStream << ast->loc << "Internal Compiler Error. "
00309 << "Function SSA, unexpected astType: "
00310 << ast->tagName()
00311 << std::endl;
00312
00313 FEXPR(grandLet) = GC_NULL;
00314 errorFree = false;
00315 break;
00316 }
00317
00318 case at_identPattern:
00319 {
00320 if ((ast->child(0)->symbolDef) &&
00321 (ast->child(0)->isIdentType(idc_ctor)))
00322 break;
00323
00324 addIL(identList, ast->child(0));
00325 break;
00326 }
00327
00328 case at_interface:
00329 case at_module:
00330 {
00331
00332 for (c = (ast->astType == at_interface)?1:0;
00333 c < ast->children.size();
00334 c++) {
00335 shared_ptr<AST> defn = ast->child(c);
00336 SSA(errStream, uoc, defn, grandLet,
00337 identList, ast, c, flags);
00338 }
00339 break;
00340 }
00341
00342 case at_defunion:
00343 case at_defstruct:
00344 case at_defrepr:
00345 case at_declunion:
00346 case at_declstruct:
00347 case at_declrepr:
00348 case at_proclaim:
00349 case at_defexception:
00350 case at_deftypeclass:
00351 case at_definstance:
00352 case at_tcmethods:
00353 case at_tcmethod_binding:
00354 case at_importAs:
00355 case at_provide:
00356 case at_import:
00357 case at_ifsel:
00358
00359
00360
00361
00362
00363 case at_reprctrs:
00364 case at_reprctr:
00365 case at_reprrepr:
00366 case at_docString:
00367 {
00368 break;
00369 }
00370
00371 case at_boolLiteral:
00372 case at_charLiteral:
00373 case at_intLiteral:
00374 case at_floatLiteral:
00375 case at_stringLiteral:
00376 case at_unit:
00377 {
00378 FEXPR(grandLet) = ast;
00379 break;
00380 }
00381
00382 case at_ident:
00383 {
00384
00385
00386
00387 FEXPR(grandLet) = ast;
00388 break;
00389 }
00390
00391 case at_define:
00392 case at_recdef:
00393 {
00394 if (ast->child(1)->astType == at_lambda) {
00395 SSA(errStream, uoc, ast->child(1), grandLet, identList,
00396 ast, 1, flags);
00397 ast->flags |= DEF_IS_TRIVIAL_INIT;
00398 }
00399 else if (isTrivialInit(ast)) {
00400 ast->flags |= DEF_IS_TRIVIAL_INIT;
00401 }
00402 else {
00403 shared_ptr<AST> gl = newGrandLet(ast);
00404 identList = AST::make(at_identList, ast->loc);
00405
00406 SSA(errStream, uoc, ast->child(1), gl, identList,
00407 ast, 1, flags);
00408
00409 shared_ptr<AST> body = GC_NULL;
00410 SETGL(body, gl);
00411 assert(body);
00412 ast->child(1) = AST::make(at_container, ast->loc, identList, body);
00413 }
00414 break;
00415 }
00416
00417 case at_lambda:
00418 {
00419 shared_ptr<AST> gl = newGrandLet(ast);
00420 identList = AST::make(at_identList, ast->loc);
00421
00422 SSA(errStream, uoc, ast->child(0), gl, identList,
00423 ast, 0, flags);
00424 SSA(errStream, uoc, ast->child(1), gl, identList,
00425 ast, 1, flags);
00426
00427 shared_ptr<AST> body = GC_NULL;
00428 SETGL(body, gl);
00429 assert(body);
00430 ast->child(1) = AST::make(at_container, ast->loc, identList, body);
00431
00432
00433 break;
00434 }
00435
00436 case at_argVec:
00437 {
00438 break;
00439 }
00440
00441 case at_typeAnnotation:
00442 {
00443
00444 SSA(errStream, uoc, ast->child(0), grandLet, identList,
00445 ast, 0, flags);
00446 ast->child(0) = FEXPR(grandLet);
00447 FEXPR(grandLet) = ast;
00448
00449 break;
00450 }
00451
00452 case at_sizeof:
00453 case at_bitsizeof:
00454 {
00455 FEXPR(grandLet) = addLB(grandLet, identList, ast);
00456 break;
00457 }
00458
00459 case at_suspend:
00460 {
00461 shared_ptr<AST> gl = newGrandLet(ast);
00462 shared_ptr<AST> res = AST::genSym(ast, "t");
00463 SSA(errStream, uoc, ast->child(1), gl, identList,
00464 ast, 1, flags);
00465 FEXPR(gl) = addLB(gl, identList, FEXPR(gl),
00466 ID_IS_GLOBAL, res, true);
00467
00468 SETGL(ast->child(1), gl);
00469 shared_ptr<AST> topres = UseCase(res);
00470 FEXPR(grandLet) = addLB(grandLet, identList, ast,
00471 LB_IS_DUMMY, topres, false);
00472 break;
00473 }
00474
00475 case at_allocREF:
00476 {
00477 FEXPR(grandLet) = ast;
00478 break;
00479 }
00480
00481 case at_copyREF:
00482 case at_setClosure:
00483 {
00484 for (c=0; c < ast->children.size(); c++) {
00485 SSA(errStream, uoc, ast->child(c), grandLet, identList,
00486 ast, c, flags);
00487 ast->child(c) = FEXPR(grandLet);
00488 }
00489 FEXPR(grandLet) = addLB(grandLet, identList, ast,
00490 LB_IS_DUMMY);
00491 break;
00492 }
00493
00494 #ifdef HAVE_INDEXABLE_LENGTH_OPS
00495 case at_array_length:
00496 case at_array_ref_length:
00497 case at_vector_length:
00498 #endif
00499 case at_struct_apply:
00500 case at_object_apply:
00501 case at_ucon_apply:
00502 {
00503 for (c=0; c < ast->children.size(); c++) {
00504 SSA(errStream, uoc, ast->child(c), grandLet, identList,
00505 ast, c, flags);
00506 ast->child(c) = FEXPR(grandLet);
00507 }
00508 FEXPR(grandLet) = addLB(grandLet, identList, ast);
00509 break;
00510 }
00511
00512 case at_dup:
00513 case at_array:
00514 case at_vector:
00515 case at_MakeVector:
00516 case at_throw:
00517 case at_mkClosure:
00518 case at_mkArrayRef:
00519 {
00520 for (c=0; c < ast->children.size(); c++) {
00521 SSA(errStream, uoc, ast->child(c), grandLet, identList,
00522 ast, c, flags);
00523 ast->child(c) = FEXPR(grandLet);
00524 }
00525 FEXPR(grandLet) = addLB(grandLet, identList, ast,
00526 LB_POSTPONED);
00527 break;
00528 }
00529
00530 case at_fqCtr:
00531 {
00532 FEXPR(grandLet) = ast;
00533 break;
00534 }
00535
00536 case at_sel_ctr:
00537 {
00538 SSA(errStream, uoc, ast->child(0), grandLet, identList,
00539 ast, 0, flags);
00540 ast->child(0) = FEXPR(grandLet);
00541
00542 FEXPR(grandLet) = addLB(grandLet, identList, ast);
00543 break;
00544 }
00545
00546 case at_deref:
00547 case at_select:
00548 {
00549 SSA(errStream, uoc, ast->child(0), grandLet, identList,
00550 ast, 0, flags);
00551 ast->child(0) = FEXPR(grandLet);
00552 FEXPR(grandLet) = ast;
00553 break;
00554 }
00555
00556 case at_inner_ref:
00557 {
00558 shared_ptr<AST> expr = ast->child(0);
00559
00560 SSA(errStream, uoc, expr, grandLet, identList,
00561 ast, 0, flags);
00562 ast->child(0) = FEXPR(grandLet);
00563
00564 if (ast->flags & INNER_REF_NDX) {
00565 shared_ptr<AST> ndx = ast->child(1);
00566 SSA(errStream, uoc, ndx, grandLet, identList,
00567 ast, 1, flags);
00568 ast->child(1) = FEXPR(grandLet);
00569
00570
00571
00572
00573
00574
00575
00576 shared_ptr<AST> tempAst = GC_NULL;
00577 if (expr->symType->getBareType()->typeTag == ty_array_ref) {
00578
00579 assert(false);
00580 }
00581 if (expr->symType->getBareType()->typeTag == ty_vector) {
00582
00583 tempAst = AST::make(at_vector_nth, expr->loc,
00584 expr, ndx);
00585
00586 }
00587 else {
00588
00589 assert(expr->symType->getBareType()->typeTag == ty_ref);
00590 tempAst = AST::make(at_array_nth, expr->loc,
00591 AST::make(at_deref, expr->loc, expr), ndx);
00592 }
00593
00594
00595
00596
00597
00598
00599
00600 SSA(errStream, uoc, tempAst, grandLet, identList,
00601 GC_NULL, 0, flags);
00602
00603 }
00604
00605 FEXPR(grandLet) = ast;
00606 break;
00607 }
00608
00609 case at_nth:
00610
00611 assert(false);
00612 break;
00613
00614 case at_array_nth:
00615 case at_array_ref_nth:
00616 case at_vector_nth:
00617 {
00618 shared_ptr<AST> expr = ast->child(0);
00619 shared_ptr<AST> ndx = ast->child(1);
00620
00621 SSA(errStream, uoc, expr, grandLet, identList,
00622 ast, 0, flags);
00623 ast->child(0) = FEXPR(grandLet);
00624
00625 expr = ast->child(0);
00626
00627 SSA(errStream, uoc, ndx, grandLet, identList,
00628 ast, 1, flags);
00629 ast->child(1) = FEXPR(grandLet);
00630 ndx = ast->child(1);
00631
00632
00633 shared_ptr<AST> lt = AST::make(at_ident, ast->loc);
00634 shared_ptr<AST> unit = AST::make(at_unit, ast->loc);
00635 shared_ptr<AST> IOB = AST::make(at_ident, ast->loc);
00636
00637 lt->s = "__index_lt";
00638 lt->fqn = FQName("bitc.prelude", "__index_lt");
00639 lt->symType = Type::make(ty_fn,
00640 Type::make(ty_fnarg,
00641 Type::make(ty_word),
00642 Type::make(ty_word)),
00643 Type::make(ty_bool));
00644 InstMangle(lt);
00645
00646 IOB->s = "IndexBoundsError";
00647 IOB->fqn = FQName("bitc.prelude", "IndexBoundsError");
00648 IOB->symType = Type::make(ty_exn);
00649 InstMangle(IOB);
00650
00651 #ifdef HAVE_INDEXABLE_LENGTH_OPS
00652 AstType lenType =
00653 ((ast->astType == at_array_nth) ? at_array_length
00654 : ((ast->astType == at_array_ref_nth) ? at_array_ref_length
00655 : at_vector_length));
00656
00657 shared_ptr<AST> len = AST::make(lenType, ast->loc,
00658 UseCase(expr));
00659 #else
00660 shared_ptr<AST> lengthIdent =
00661 AST::make(at_ident, LToken(tk_BlkIdent, "length"));
00662 shared_ptr<AST> len = AST::make(at_select, ast->loc,
00663 UseCase(expr), lengthIdent);
00664 #endif
00665
00666 shared_ptr<AST> ltApp = AST::make(at_apply, ast->loc, lt, UseCase(ndx), len);
00667
00668 shared_ptr<AST> throwAst = AST::make(at_throw, ast->loc, IOB);
00669 shared_ptr<AST> ifAst = AST::make(at_if, ast->loc, ltApp, unit, throwAst);
00670 addLB(grandLet, identList, ifAst, LB_IS_DUMMY);
00671
00672 FEXPR(grandLet) = ast;
00673 break;
00674 }
00675
00676 case at_apply:
00677 {
00678 shared_ptr<AST> id = ast->child(0);
00679
00680 shared_ptr<Type> fn = id->symType->getBareType();
00681 assert(fn->isFnxn());
00682 shared_ptr<Type> argsType = fn->Args()->getType();
00683
00684 SSA(errStream, uoc, ast->child(0), grandLet, identList,
00685 ast, 0, flags);
00686 ast->child(0) = FEXPR(grandLet);
00687
00688 for (c=1; c < ast->children.size(); c++) {
00689
00690 SSA(errStream, uoc, ast->child(c), grandLet, identList,
00691 ast, c, flags);
00692
00693
00694
00695
00696
00697
00698
00699
00700 if ((argsType->CompFlags(c-1) & COMP_BYREF) &&
00701 ast->child(c)->isLiteral()) {
00702
00703
00704
00705 assert(!argsType->CompType(c-1)->isMutable());
00706
00707
00708
00709 FEXPR(grandLet) = addLB(grandLet, identList, ast->child(c));
00710 }
00711
00712 ast->child(c) = FEXPR(grandLet);
00713 }
00714
00715 if (id->flags & SELF_TAIL) {
00716 assert(id == ast->child(0));
00717 FEXPR(grandLet) = addLB(grandLet, identList, ast, LB_IS_DUMMY);
00718 }
00719 else {
00720 FEXPR(grandLet) = addLB(grandLet, identList, ast);
00721 }
00722 break;
00723 }
00724
00725 case at_setbang:
00726 {
00727 shared_ptr<AST> lhs = ast->child(0);
00728 SSA(errStream, uoc, lhs, grandLet, identList,
00729 ast, 0, flags);
00730 ast->child(0) = FEXPR(grandLet);
00731
00732 lhs = ast->child(0);
00733
00734 shared_ptr<AST> rhs = ast->child(1);
00735 SSA(errStream, uoc, rhs, grandLet, identList,
00736 ast, 1, flags);
00737 ast->child(1) = FEXPR(grandLet);
00738 rhs = ast->child(1);
00739
00740 FEXPR(grandLet) = addLB(grandLet, identList, ast,
00741 LB_POSTPONED);
00742
00743
00744
00745
00746
00747
00748 break;
00749 }
00750
00751 case at_begin:
00752 {
00753 for (c=0; c < ast->children.size(); c++) {
00754 SSA(errStream, uoc, ast->child(c), grandLet, identList,
00755 ast, c, flags);
00756 ast->child(c) = FEXPR(grandLet);
00757 }
00758
00759 break;
00760 }
00761
00762 case at_if:
00763 {
00764 SSA(errStream, uoc, ast->child(0), grandLet, identList,
00765 ast, 0, flags);
00766 ast->child(0) = FEXPR(grandLet);
00767
00768 shared_ptr<AST> res = AST::genSym(ast, "t");
00769 shared_ptr<AST> gl1 = newGrandLet(ast);
00770 shared_ptr<AST> gl2 = newGrandLet(ast);
00771
00772 SSA(errStream, uoc, ast->child(1), gl1, identList,
00773 ast, 1, flags);
00774 SSA(errStream, uoc, ast->child(2), gl2, identList,
00775 ast, 2, flags);
00776
00777 FEXPR(gl1) = addLB(gl1, identList, FEXPR(gl1),
00778 NO_FLAGS, res, true);
00779 FEXPR(gl2) = addLB(gl2, identList, FEXPR(gl2),
00780 NO_FLAGS, res, false);
00781 SETGL(ast->child(1), gl1);
00782 SETGL(ast->child(2), gl2);
00783
00784 shared_ptr<AST> topres = UseCase(res);
00785 FEXPR(grandLet) = addLB(grandLet, identList, ast, LB_IS_DUMMY, topres, false);
00786 break;
00787 }
00788
00789 case at_when:
00790 case at_unless:
00791 {
00792 SSA(errStream, uoc, ast->child(0), grandLet, identList,
00793 ast, 0, flags);
00794 ast->child(0) = FEXPR(grandLet);
00795
00796 shared_ptr<AST> res = AST::genSym(ast, "t");
00797 shared_ptr<AST> gl1 = newGrandLet(ast);
00798
00799 SSA(errStream, uoc, ast->child(1), gl1, identList,
00800 ast, 1, flags);
00801
00802 FEXPR(gl1) = addLB(gl1, identList, FEXPR(gl1),
00803 NO_FLAGS, res, true);
00804 SETGL(ast->child(1), gl1);
00805
00806 shared_ptr<AST> topres = UseCase(res);
00807 FEXPR(grandLet) = addLB(grandLet, identList, ast, LB_IS_DUMMY, topres, false);
00808 break;
00809 }
00810
00811 case at_and:
00812 {
00813 shared_ptr<AST> ifizedAST = AST::make(at_if, ast->child(0)->loc);
00814 shared_ptr<AST> ifAst = ifizedAST;
00815 shared_ptr<AST> prev = GC_NULL;
00816 for (c = 0; c < ast->children.size() - 1; c++) {
00817 shared_ptr<AST> falseAst = AST::make(at_boolLiteral, ast->child(c)->loc);
00818 falseAst->litValue.b = false;
00819 falseAst->s = "#f";
00820 falseAst->symType = Type::make(ty_bool);
00821
00822 ifAst->symType = ast->child(c)->symType;
00823 ifAst->children.push_back(ast->child(c));
00824 ifAst->children.push_back(AST::make(at_if, ast->child(c+1)->loc));
00825 ifAst->children.push_back(falseAst);
00826 prev = ifAst;
00827 ifAst = ifAst->child(1);
00828 }
00829
00830 if (prev)
00831 prev->child(1) = ifAst =
00832 ast->child(ast->children.size() -1);
00833 else
00834 ifAst = ast->child(ast->children.size() -1);
00835
00836 parent->child(chno) = ifizedAST;
00837 SSA(errStream, uoc, ifizedAST, grandLet, identList,
00838 parent, chno, flags);
00839 break;
00840 }
00841 case at_or:
00842 {
00843 shared_ptr<AST> ifizedAST = AST::make(at_if, ast->child(0)->loc);
00844 shared_ptr<AST> ifAst = ifizedAST;
00845 shared_ptr<AST> prev = GC_NULL;
00846 for (c = 0; c < ast->children.size() - 1; c++) {
00847 shared_ptr<AST> trueAst = AST::make(at_boolLiteral, ast->child(c)->loc);
00848 trueAst->litValue.b = true;
00849 trueAst->s = "#t";
00850 trueAst->symType = Type::make(ty_bool);
00851
00852 ifAst->symType = ast->child(c)->symType;
00853 ifAst->children.push_back(ast->child(c));
00854 ifAst->children.push_back(trueAst);
00855 ifAst->children.push_back(AST::make(at_if, ast->child(c+1)->loc));
00856 prev = ifAst;
00857 ifAst = ifAst->child(2);
00858 }
00859
00860 if (prev)
00861 prev->child(2) = ifAst =
00862 ast->child(ast->children.size() -1);
00863 else
00864 ifAst = ast->child(ast->children.size() -1);
00865
00866 parent->child(chno) = ifizedAST;
00867 SSA(errStream, uoc, ifizedAST, grandLet, identList,
00868 parent, chno, flags);
00869 break;
00870 }
00871
00872 case at_cond:
00873 {
00874 shared_ptr<AST> caselegs = ast->child(0);
00875 shared_ptr<AST> ow = ast->child(1)->child(0);
00876 shared_ptr<AST> ifizedAST = AST::make(at_if, caselegs->loc);
00877 shared_ptr<AST> ifAst = ifizedAST;
00878 shared_ptr<AST> prev = GC_NULL;
00879 for (c = 0; c < caselegs->children.size(); c++) {
00880 shared_ptr<AST> caseleg = caselegs->child(c);
00881 ifAst->loc = caseleg->loc;
00882 ifAst->symType = caseleg->symType;
00883 ifAst->children.push_back(caseleg->child(0));
00884 ifAst->children.push_back(caseleg->child(1));
00885
00886 ifAst->children.push_back(AST::make(at_if,
00887 caselegs->child(c)->loc));
00888 prev = ifAst;
00889 ifAst = ifAst->child(2);
00890 }
00891
00892 if (prev) {
00893 prev->child(2) = ifAst = ow;
00894 }
00895 else {
00896 ifAst = ow;
00897 }
00898
00899 parent->child(chno) = ifizedAST;
00900 SSA(errStream, uoc, ifizedAST, grandLet, identList,
00901 parent, chno, flags);
00902 break;
00903 }
00904
00905
00906 case at_labeledBlock:
00907 {
00908
00909 std::stringstream ss;
00910 ss << "__" << ast->child(0)->s << ast->child(0)->ID;
00911 std::string resultName = ss.str();
00912
00913 shared_ptr<AST> res =
00914 AST::make(at_ident, LToken(tk_BlkIdent, resultName));
00915 res->flags = ast->flags | ID_IS_GENSYM;
00916 res->identType = id_value;
00917 res->symType = ast->symType;
00918 res->scheme = ast->scheme;
00919 addIL(identList, res);
00920
00921 shared_ptr<AST> gl = newGrandLet(ast);
00922 SSA(errStream, uoc, ast->child(1), gl, identList,
00923 ast, 1, flags);
00924 FEXPR(gl) = addLB(gl, identList, FEXPR(gl), NO_FLAGS, res, false);
00925 SETGL(ast->child(1), gl);
00926 FEXPR(grandLet) = addLB(grandLet, identList, ast, LB_IS_DUMMY,
00927 res, false);
00928 break;
00929 }
00930
00931 case at_return_from:
00932 {
00933 shared_ptr<AST> labelDef = ast->child(0)->symbolDef;
00934
00935 std::stringstream ss;
00936 ss << "__" << labelDef->s << labelDef->ID;
00937 std::string resultName = ss.str();
00938
00939 shared_ptr<AST> res =
00940 AST::make(at_ident, LToken(tk_BlkIdent, resultName));
00941 res->flags = ast->flags | ID_IS_GENSYM;
00942 res->identType = id_value;
00943 res->symType = ast->symType;
00944 res->scheme = ast->scheme;
00945
00946 SSA(errStream, uoc, ast->child(1), grandLet, identList,
00947 ast, 1, flags);
00948
00949 FEXPR(grandLet) = addLB(grandLet, identList, FEXPR(grandLet),
00950 NO_FLAGS, res, false);
00951
00952 ast->child(1) = FEXPR(grandLet);
00953
00954 FEXPR(grandLet) = addLB(grandLet, identList, ast,
00955 LB_POSTPONED);
00956 break;
00957 }
00958
00959 case at_uswitch:
00960 case at_try:
00961 {
00962 shared_ptr<AST> res = AST::genSym(ast, "t");
00963 addIL(identList, res);
00964
00965
00966
00967
00968 if (ast->astType == at_try) {
00969 shared_ptr<AST> gl = newGrandLet(ast);
00970 SSA(errStream, uoc, ast->child(0), gl, identList,
00971 ast, 0, flags);
00972 FEXPR(gl) = addLB(gl, identList, FEXPR(gl), NO_FLAGS, res, false);
00973 SETGL(ast->child(0), gl);
00974 }
00975 else {
00976 SSA(errStream, uoc, ast->child(1), grandLet, identList,
00977 ast, 1, flags);
00978 ast->child(1) = FEXPR(grandLet);
00979 }
00980
00981 shared_ptr<AST> cases = ast->child(2);
00982
00983 for (c=0; c < cases->children.size(); c++) {
00984 shared_ptr<AST> theCase = cases->child(c);
00985 shared_ptr<AST> gl = newGrandLet(theCase);
00986
00987 addIL(identList, theCase->child(0));
00988
00989 SSA(errStream, uoc, theCase->child(1), gl,
00990 identList, theCase, 1, flags);
00991
00992 FEXPR(gl) = addLB(gl, identList, FEXPR(gl), NO_FLAGS, res, false);
00993 SETGL(theCase->child(1), gl);
00994 }
00995
00996
00997 shared_ptr<AST> ow = ast->child(3);
00998 if (ow->astType == at_otherwise) {
00999 shared_ptr<AST> owIdent = ow->child(0);
01000 shared_ptr<AST> owExpr = ow->child(1);
01001 shared_ptr<AST> gl = newGrandLet(owExpr);
01002
01003 addIL(identList, owIdent);
01004
01005 SSA(errStream, uoc, owExpr, gl, identList, ast, 2, flags);
01006 FEXPR(gl) = addLB(gl, identList, FEXPR(gl), NO_FLAGS, res, false);
01007 SETGL(ow->child(1), gl);
01008 }
01009 shared_ptr<AST> topres = UseCase(res);
01010 FEXPR(grandLet) = addLB(grandLet, identList, ast, LB_IS_DUMMY, topres, false);
01011 break;
01012 }
01013
01014 case at_letStar:
01015 {
01016 assert(false);
01017 break;
01018 }
01019
01020 case at_loop:
01021 {
01022 shared_ptr<AST> res = AST::genSym(ast, "t");
01023 shared_ptr<AST> gl;
01024 shared_ptr<AST> theIdent;
01025
01026 shared_ptr<AST> lbs = ast->child(0);
01027 for (size_t c = 0; c < lbs->children.size(); c++) {
01028 shared_ptr<AST> lb = lbs->child(c);
01029 assert(lb->child(0)->astType == at_identPattern);
01030 shared_ptr<AST> ident = lb->child(0)->child(0);
01031 addIL(identList, ident);
01032
01033 shared_ptr<AST> init = lb->child(1);
01034 gl = newGrandLet(ast);
01035 SSA(errStream, uoc, init, gl, identList, lb, 1, flags);
01036 theIdent = UseCase(ident);
01037 FEXPR(gl) = addLB(gl, identList, FEXPR(gl),
01038 NO_FLAGS, theIdent, false);
01039 SETGL(lb->child(1), gl);
01040 lb->flags |= LB_IS_DUMMY;
01041
01042 shared_ptr<AST> step = lb->child(2);
01043 gl = newGrandLet(ast);
01044 SSA(errStream, uoc, step, gl, identList, lb, 2, flags);
01045 theIdent = UseCase(ident);
01046 FEXPR(gl) = addLB(gl, identList, FEXPR(gl),
01047 NO_FLAGS, theIdent, false);
01048 SETGL(lb->child(2), gl);
01049 }
01050
01051
01052
01053 shared_ptr<AST> loopTest = ast->child(1);
01054 gl = newGrandLet(ast);
01055 SSA(errStream, uoc, loopTest->child(0), gl, identList,
01056 loopTest, 0, flags);
01057 SETGL(loopTest->child(0), gl);
01058
01059
01060 gl = newGrandLet(loopTest);
01061 SSA(errStream, uoc, loopTest->child(1), gl, identList,
01062 loopTest, 1, flags);
01063 FEXPR(gl) = addLB(gl, identList, FEXPR(gl),
01064 NO_FLAGS, res, true);
01065 SETGL(loopTest->child(1), gl);
01066
01067
01068
01069 gl = newGrandLet(ast);
01070 SSA(errStream, uoc, ast->child(2), gl, identList,
01071 ast, 2, flags);
01072 SETGL(ast->child(2), gl);
01073
01074 shared_ptr<AST> topres = UseCase(res);
01075 FEXPR(grandLet) = addLB(grandLet, identList, ast,
01076 LB_IS_DUMMY, topres, false);
01077 break;
01078 }
01079
01080 case at_let:
01081 case at_letrec:
01082 {
01083 shared_ptr<AST> res = AST::genSym(ast, "t");
01084
01085
01086 shared_ptr<AST> lbs = ast->child(0);
01087 for (size_t c = 0; c < lbs->children.size(); c++) {
01088 shared_ptr<AST> lb = lbs->child(c);
01089 assert(lb->child(0)->astType == at_identPattern);
01090 shared_ptr<AST> ident = lb->child(0)->child(0);
01091 shared_ptr<AST> gl = newGrandLet(ast);
01092 SSA(errStream, uoc, lb->child(1), gl, identList,
01093 lb, 1, flags);
01094 shared_ptr<AST> theIdent = ident;
01095 addIL(identList, theIdent);
01096
01097 FEXPR(gl) = addLB(gl, identList, FEXPR(gl),
01098 NO_FLAGS, theIdent, false);
01099 SETGL(lb->child(1), gl);
01100 lb->flags |= LB_IS_DUMMY;
01101 }
01102
01103
01104 shared_ptr<AST> gl = newGrandLet(ast);
01105 SSA(errStream, uoc, ast->child(1), gl, identList,
01106 ast, 1, flags);
01107 FEXPR(gl) = addLB(gl, identList, FEXPR(gl),
01108 NO_FLAGS, res, true);
01109 SETGL(ast->child(1), gl);
01110
01111 shared_ptr<AST> topres = UseCase(res);
01112 FEXPR(grandLet) = addLB(grandLet, identList, ast,
01113 LB_IS_DUMMY, topres, false);
01114 break;
01115 }
01116 }
01117 return errorFree;
01118 }
01119
01120
01121
01122
01123
01124 bool
01125 UocInfo::be_ssaTrans(std::ostream& errStream,
01126 bool init, unsigned long flags)
01127 {
01128 bool errFree = true;
01129
01130 shared_ptr<UocInfo> uoc = shared_from_this();
01131
01132 CHKERR(errFree, ssa(errStream, uoc, uoc->uocAst, GC_NULL,
01133 GC_NULL, uoc->uocAst, 0, flags));
01134
01135
01136
01137 CHKERR(errFree, uoc->RandT(errStream, true,
01138 CL_SYM_FLAGS, CL_TYP_FLAGS));
01139 return errFree;
01140 }
01141