Inferno
0.2
|
00001 00002 #include "steps/lower_control_flow.hpp" 00003 #include "tree/cpptree.hpp" 00004 #include "tree/sctree.hpp" 00005 #include "common/common.hpp" 00006 #include "sr/soft_patterns.hpp" 00007 #include "tree/typeof.hpp" 00008 #include "steps/uncombable.hpp" 00009 #include "inferno_patterns.hpp" 00010 00011 using namespace CPPTree; 00012 using namespace SCTree; 00013 using namespace Steps; 00014 00015 // Local nodes let us designate switch and for nodes as uncombable 00016 struct UncombableSwitch : Switch, Uncombable { NODE_FUNCTIONS_FINAL }; 00017 struct UncombableFor : For, Uncombable { NODE_FUNCTIONS_FINAL }; 00018 struct CombableFor : For { NODE_FUNCTIONS_FINAL }; 00019 struct UncombableBreak : Break, Uncombable { NODE_FUNCTIONS_FINAL }; 00020 struct CombableBreak : Break { NODE_FUNCTIONS_FINAL }; 00021 00022 00023 DetectUncombableSwitch::DetectUncombableSwitch() 00024 { 00025 MakeTreePtr< MatchAll<Switch> > s_all; 00026 MakeTreePtr< NotMatch<Switch> > sx_not; 00027 MakeTreePtr<UncombableSwitch> sx_uswitch; 00028 MakeTreePtr<Switch> s_switch; 00029 MakeTreePtr<Expression> expr; 00030 MakeTreePtr<Compound> comp; 00031 MakeTreePtr< Star<Declaration> > decls; 00032 MakeTreePtr< Star<Statement> > pre, post; 00033 MakeTreePtr< NotMatch<Statement> > x_not; 00034 MakeTreePtr<Break> x_break; 00035 MakeTreePtr<SwitchTarget> target; 00036 MakeTreePtr<UncombableSwitch> r_uswitch; 00037 00038 s_all->patterns = (sx_not, s_switch); 00039 sx_not->pattern = sx_uswitch; 00040 s_switch->body = comp; 00041 s_switch->condition = expr; 00042 comp->members = decls; 00043 comp->statements = (pre, x_not, target, post); 00044 x_not->pattern = x_break; 00045 00046 r_uswitch->body = comp; 00047 r_uswitch->condition = expr; 00048 00049 Configure( s_all, r_uswitch ); 00050 } 00051 00052 00053 // Turn all for into uncombablefor, so the next step can go the other 00054 // way, and can avoid a top-level NOT 00055 MakeAllForUncombable::MakeAllForUncombable() 00056 { 00057 MakeTreePtr< MatchAll<For> > s_all; 00058 MakeTreePtr< NotMatch<For> > s_not; 00059 MakeTreePtr<UncombableFor> sx_ufor; 00060 MakeTreePtr<For> s_for; 00061 MakeTreePtr<Statement> init; 00062 MakeTreePtr<Expression> test; 00063 MakeTreePtr<Statement> inc; 00064 MakeTreePtr<Statement> body; 00065 MakeTreePtr<UncombableFor> r_ufor; 00066 00067 s_all->patterns = (s_not, s_for); 00068 s_not->pattern = sx_ufor; 00069 s_for->initialisation = init; 00070 s_for->condition = test; 00071 s_for->increment = inc; 00072 s_for->body = body; 00073 00074 r_ufor->initialisation = init; 00075 r_ufor->condition = test; 00076 r_ufor->increment = inc; 00077 r_ufor->body = body; 00078 00079 Configure( s_all, r_ufor ); 00080 } 00081 00082 00083 DetectCombableFor::DetectCombableFor() 00084 { 00085 MakeTreePtr<UncombableFor> s_ufor; 00086 MakeTreePtr<Assign> init; 00087 MakeTreePtr< MatchAny<Operator> > test; 00088 MakeTreePtr<Less> lt; 00089 MakeTreePtr<LessOrEqual> le; 00090 MakeTreePtr<Greater> gt; 00091 MakeTreePtr<GreaterOrEqual> ge; 00092 MakeTreePtr<NotEqual> ne; 00093 MakeTreePtr<Integer> init_val, test_val, inc_val; 00094 MakeTreePtr< MatchAny<AssignmentOperator> > inc; 00095 MakeTreePtr<PostIncrement> postinc; 00096 MakeTreePtr<PreIncrement> preinc; 00097 MakeTreePtr<PostDecrement> postdec; 00098 MakeTreePtr<PreDecrement> predec; 00099 MakeTreePtr<AssignmentAdd> asadd; 00100 MakeTreePtr<AssignmentSubtract> assub; 00101 MakeTreePtr<Assign> assign1, assign2; 00102 MakeTreePtr<Add> add; 00103 MakeTreePtr<Subtract> sub; 00104 MakeTreePtr< NotMatch<Statement> > body; 00105 MakeTreePtr< Stuff<Statement> > astuff; 00106 MakeTreePtr<AssignmentOperator> assignop; 00107 00108 MakeTreePtr<CombableFor> r_for; 00109 MakeTreePtr< TransformOf<InstanceIdentifier> > loopvar( &TypeOf::instance ); 00110 MakeTreePtr<Integral> type; 00111 00112 s_ufor->initialisation = init; 00113 init->operands = (loopvar, init_val); 00114 s_ufor->condition = test; 00115 test->patterns = (gt, ge, lt, le, ne); 00116 gt->operands = (loopvar, test_val); 00117 ge->operands = (loopvar, test_val); 00118 lt->operands = (loopvar, test_val); 00119 le->operands = (loopvar, test_val); 00120 ne->operands = (loopvar, test_val); 00121 s_ufor->increment = inc; 00122 inc->patterns = (preinc, postinc, predec, postdec, asadd, assub, assign1, assign2); 00123 preinc->operands = (loopvar); 00124 postinc->operands = (loopvar); 00125 predec->operands = (loopvar); 00126 postdec->operands = (loopvar); 00127 asadd->operands = (loopvar, inc_val); 00128 assub->operands = (loopvar, inc_val); 00129 assign1->operands = (loopvar, add); 00130 add->operands = (loopvar, inc_val); 00131 assign2->operands = (loopvar, sub); 00132 sub->operands = (loopvar, inc_val); 00133 s_ufor->body = body; 00134 body->pattern = astuff; 00135 astuff->terminus = assignop; 00136 assignop->operands = (loopvar, MakeTreePtr< Star<Expression> >()); 00137 loopvar->pattern = type; 00138 00139 r_for->initialisation = init; 00140 r_for->condition = test; 00141 r_for->increment = inc; 00142 r_for->body = body; 00143 00144 Configure( s_ufor, r_for ); 00145 } 00146 00147 00148 // Turn all break into uncombable break, so the next step can go the other 00149 // way, and can avoid a top-level NOT 00150 MakeAllBreakUncombable::MakeAllBreakUncombable() 00151 { 00152 MakeTreePtr< NotMatch<Break> > s_not; 00153 MakeTreePtr<UncombableBreak> sx_ubreak; 00154 MakeTreePtr<Break> s_break; 00155 MakeTreePtr<Statement> init; 00156 MakeTreePtr<Expression> test; 00157 MakeTreePtr<Statement> inc; 00158 MakeTreePtr<Statement> body; 00159 MakeTreePtr<UncombableBreak> r_ubreak; 00160 00161 s_not->pattern = sx_ubreak; 00162 00163 Configure( s_not, r_ubreak ); 00164 } 00165 00166 00167 // Detect combable breaks - these are the ones at the top level of 00168 // a combable switch. Run the compound statemnts cleanup before this 00169 // to get breaks in compound blocks. But we do not accept breaks 00170 // under constructs like if 00171 DetectCombableBreak::DetectCombableBreak() 00172 { 00173 MakeTreePtr< MatchAll<Switch> > all; 00174 MakeTreePtr< NotMatch<Switch> > x_not; 00175 MakeTreePtr<UncombableSwitch> uswitch; 00176 MakeTreePtr<Switch> swtch; 00177 MakeTreePtr<Expression> expr; 00178 MakeTreePtr<Compound> comp; 00179 MakeTreePtr< Star<Declaration> > decls; 00180 MakeTreePtr< Star<Statement> > pre, post; 00181 MakeTreePtr< Overlay<Break> > over; 00182 MakeTreePtr<UncombableBreak> s_ubreak; 00183 MakeTreePtr<CombableBreak> r_break; 00184 00185 all->patterns = (x_not, swtch); 00186 x_not->pattern = uswitch; 00187 swtch->condition = expr; 00188 swtch->body = comp; 00189 comp->members = decls; 00190 comp->statements = (pre, over, post); 00191 over->through = s_ubreak; 00192 over->overlay = r_break; 00193 00194 Configure( all, swtch ); 00195 } 00196 00197 00198 ForToWhile::ForToWhile() 00199 { 00200 // Add new compunds inside and outside the While node, and place the For 00201 // node's statements and expressions in the appropriate places. 00202 // 00203 // Deal with continue by inserting a copy of the increment just before the 00204 // continue, and leave the continue in place. This avoids the need for 00205 // gotos in case that matters. Not ideal if the increment statement 00206 // is huge. 00207 // 00208 // Avoid matching continues that don't belong to use by using a recurse 00209 // restriction, like in BreakToGoto. 00210 // 00211 // We have to use the GreenGrass hack to prevent the slave spinning 00212 // forever. The continue in the slave search pattern has a GreenGrass 00213 // node under it indicating that it must be from the input program and 00214 // not one we just inserted on an earlier iteration. 00215 00216 MakeTreePtr<For> s_for; 00217 MakeTreePtr<Statement> forbody, inc, init; 00218 MakeTreePtr<Expression> cond; 00219 MakeTreePtr<While> r_while; 00220 MakeTreePtr<Compound> r_outer, r_body; 00221 MakeTreePtr< Stuff<Statement> > l_stuff; 00222 MakeTreePtr< Overlay<Statement> > l_overlay; 00223 MakeTreePtr< NotMatch<Statement> > l_s_not; 00224 MakeTreePtr< Loop > l_s_loop; 00225 00226 MakeTreePtr<Continue> l_s_cont; 00227 MakeTreePtr<Nop> l_r_nop; 00228 MakeTreePtr<BuildLabelIdentifier> r_cont_labelid("CONTINUE"); 00229 MakeTreePtr<Label> r_cont_label; 00230 MakeTreePtr<Goto> lr_goto; 00231 00232 l_stuff->terminus = l_overlay; 00233 l_overlay->through = l_s_cont; 00234 l_stuff->recurse_restriction = l_s_not; 00235 l_overlay->overlay = lr_goto; 00236 lr_goto->destination = r_cont_labelid; 00237 l_s_not->pattern = l_s_loop; 00238 MakeTreePtr< SlaveCompareReplace<Statement> > r_slave( forbody, l_stuff, l_stuff ); 00239 00240 s_for->body = forbody; 00241 s_for->initialisation = init; 00242 s_for->condition = cond; 00243 s_for->increment = inc; 00244 00245 r_outer->statements = (init, r_while); 00246 r_while->body = r_body; 00247 r_while->condition = cond; 00248 r_body->statements = (r_slave, r_cont_label, inc); 00249 r_cont_label->identifier = r_cont_labelid; 00250 00251 Configure( MakeCheckUncombable(s_for), r_outer ); 00252 } 00253 00254 WhileToDo::WhileToDo() 00255 { 00256 // Just need to insert an "if" statement for the case 00257 // where there are 0 iterations. 00258 MakeTreePtr<While> s_while; 00259 MakeTreePtr<Statement> body; 00260 MakeTreePtr<Expression> cond; 00261 MakeTreePtr<Nop> r_nop; 00262 MakeTreePtr<If> r_if; 00263 MakeTreePtr<Do> r_do; 00264 00265 s_while->body = body; 00266 s_while->condition = cond; 00267 00268 r_if->condition = cond; 00269 r_if->body = r_do; 00270 r_if->else_body = r_nop; 00271 r_do->condition = cond; 00272 r_do->body = body; 00273 00274 Configure( MakeCheckUncombable(s_while), r_if ); 00275 } 00276 00277 IfToIfGoto::IfToIfGoto() 00278 { 00279 // Identify a general if statements and build a compuond with the usual 00280 // laep-frogging gotos. Since we are converting from a general kind of if 00281 // to a more specific kind (the condiitonal goto pattern) we have to 00282 // exclude the conditional goto explicitly using and-not in the search 00283 // pattern. Otherwise we would spin forever expanding them over and over. 00284 MakeTreePtr< MatchAll<Statement> > s_and; 00285 MakeTreePtr<If> s_if, l_r_if, r_if; 00286 MakeTreePtr<Statement> body, else_body; 00287 MakeTreePtr<Expression> cond; 00288 MakeTreePtr< NotMatch<Statement> > l_r_not; 00289 MakeTreePtr<Goto> l_r_goto, r_goto, r_goto_else; 00290 MakeTreePtr<Nop> l_r_nop, r_nop; 00291 MakeTreePtr<Compound> r_comp; 00292 MakeTreePtr<LogicalNot> r_not; 00293 MakeTreePtr<BuildLabelIdentifier> r_labelid1("THEN"), r_labelid2("ELSE"); 00294 MakeTreePtr<Label> r_label1, r_label2; 00295 00296 s_and->patterns = (s_if, l_r_not); 00297 s_if->condition = cond; 00298 s_if->body = body; 00299 s_if->else_body = else_body; 00300 00301 // exclude if(x) goto y; 00302 l_r_not->pattern = l_r_if; 00303 l_r_if->body = l_r_goto; 00304 l_r_if->else_body = l_r_nop; 00305 00306 r_comp->statements = (r_if, body, r_goto_else, r_label1, else_body, r_label2); 00307 r_if->condition = r_not; 00308 r_not->operands = (cond); 00309 r_if->body = r_goto; 00310 r_if->else_body = r_nop; 00311 r_goto->destination = r_labelid1; 00312 r_goto_else->destination = r_labelid2; 00313 r_label1->identifier = r_labelid1; 00314 r_label2->identifier = r_labelid2; 00315 00316 Configure( MakeCheckUncombable(s_and), r_comp ); 00317 } 00318 00319 00320 SwitchToIfGoto::SwitchToIfGoto() 00321 { 00322 // Add a surrounding compound that declares a variable switch_value which 00323 // will hold the value passed to switch. Using slaves, replace case/default 00324 // with ordinary labels and, for each one, add a conditional goto (plain goto 00325 // for default) at the top of the funciton. Condition tests switch_value 00326 // against the case value or range where GCC's range-case has been used. 00327 // 00328 // The order in which we do things is important. We insert the gotos and 00329 // conditional gotos at the top of the block, so that they appear in 00330 // reverse order of the order in which we inserted them. We want the 00331 // plain goto that default produces to be at the bottom, so we do it last. 00332 // 00333 // The order of the conditional gotos that result from cases should not matter 00334 // because cases should not overlap. 00335 MakeTreePtr<Switch> s_switch; 00336 MakeTreePtr<Compound> r_comp; 00337 MakeTreePtr<Statement> body; 00338 MakeTreePtr<Type> cond_type; 00339 MakeTreePtr<Automatic> r_decl; 00340 MakeTreePtr<BuildInstanceIdentifier> id("switch_value"); 00341 MakeTreePtr< TransformOf<Expression> > s_cond( &TypeOf::instance ); 00342 00343 // SlaveSearchReplace for default 00344 MakeTreePtr<Compound> l1_s_body, l1_r_body; 00345 MakeTreePtr< Star<Declaration> > l1_decls; 00346 MakeTreePtr< Star<Statement> > l1_pre, l1_post; 00347 MakeTreePtr< Default > l1_s_default; 00348 MakeTreePtr< Label > l1_r_label; 00349 MakeTreePtr<BuildLabelIdentifier> l1_r_labelid("DEFAULT"); 00350 MakeTreePtr<Goto> l1_r_goto; 00351 00352 l1_s_body->members = l1_decls; 00353 l1_s_body->statements = (l1_pre, l1_s_default, l1_post); 00354 00355 l1_r_body->members = l1_decls; 00356 l1_r_body->statements = (l1_r_goto, l1_pre, l1_r_label, l1_post); 00357 l1_r_goto->destination = l1_r_labelid; 00358 l1_r_label->identifier = l1_r_labelid; 00359 00360 MakeTreePtr< SlaveCompareReplace<Statement> > r_slave1( body, l1_s_body, l1_r_body ); 00361 00362 // slave for normal case statements (single value) 00363 MakeTreePtr<Compound> l2_s_body, l2_r_body; 00364 MakeTreePtr< Star<Declaration> > l2_decls; 00365 MakeTreePtr< Star<Statement> > l2_pre, l2_post; 00366 MakeTreePtr< Case > l2_s_case; 00367 MakeTreePtr< Label > l2_r_label; 00368 MakeTreePtr<BuildLabelIdentifier> l2_r_labelid("CASE"); 00369 MakeTreePtr<If> l2_r_if; 00370 MakeTreePtr<Nop> l2_r_nop; 00371 MakeTreePtr<Goto> l2_r_goto; 00372 MakeTreePtr<Equal> l2_r_equal; 00373 MakeTreePtr<Expression> l2_exp; 00374 00375 l2_s_body->members = l2_decls; 00376 l2_s_body->statements = (l2_pre, l2_s_case, l2_post); 00377 l2_s_case->value = l2_exp; 00378 00379 l2_r_body->members = l2_decls; 00380 l2_r_body->statements = (l2_r_if, l2_pre, l2_r_label, l2_post); 00381 l2_r_if->condition = l2_r_equal; 00382 l2_r_if->body = l2_r_goto; 00383 l2_r_if->else_body = l2_r_nop; 00384 l2_r_equal->operands = (id, l2_exp); 00385 l2_r_goto->destination = l2_r_labelid; 00386 l2_r_label->identifier = l2_r_labelid; 00387 00388 MakeTreePtr< SlaveCompareReplace<Statement> > r_slave2( r_slave1, l2_s_body, l2_r_body ); 00389 00390 // SlaveSearchReplace for range cases (GCC extension) eg case 5..7: 00391 MakeTreePtr<Compound> l3_s_body, l3_r_body; 00392 MakeTreePtr< Star<Declaration> > l3_decls; 00393 MakeTreePtr< Star<Statement> > l3_pre, l3_post; 00394 MakeTreePtr< RangeCase > l3_s_case; 00395 MakeTreePtr< Label > l3_r_label; 00396 MakeTreePtr<BuildLabelIdentifier> l3_r_labelid("CASE"); 00397 MakeTreePtr<If> l3_r_if; 00398 MakeTreePtr<Nop> l3_r_nop; 00399 MakeTreePtr<Goto> l3_r_goto; 00400 MakeTreePtr<LogicalAnd> l3_r_and; 00401 MakeTreePtr<GreaterOrEqual> l3_r_ge; 00402 MakeTreePtr<LessOrEqual> l3_r_le; 00403 MakeTreePtr<Expression> l3_exp_lo, l3_exp_hi; 00404 00405 l3_s_body->members = l3_decls; 00406 l3_s_body->statements = (l3_pre, l3_s_case, l3_post); 00407 l3_s_case->value_lo = l3_exp_lo; 00408 l3_s_case->value_hi = l3_exp_hi; 00409 00410 l3_r_body->members = l3_decls; 00411 l3_r_body->statements = (l3_r_if, l3_pre, l3_r_label, l3_post); 00412 l3_r_if->condition = l3_r_and; 00413 l3_r_if->body = l3_r_goto; 00414 l3_r_if->else_body = l3_r_nop; 00415 l3_r_and->operands = (l3_r_ge, l3_r_le); 00416 l3_r_ge->operands = (id, l3_exp_lo); 00417 l3_r_le->operands = (id, l3_exp_hi); 00418 l3_r_goto->destination = l3_r_labelid; 00419 l3_r_label->identifier = l3_r_labelid; 00420 00421 MakeTreePtr< SlaveCompareReplace<Statement> > r_slave3( r_slave2, l3_s_body, l3_r_body ); 00422 00423 // Finish up master 00424 s_cond->pattern = cond_type; 00425 s_switch->body = body; // will only match when body is a compound 00426 s_switch->condition = s_cond; 00427 00428 r_decl->identifier = id; 00429 r_decl->type = cond_type; 00430 r_decl->initialiser = s_cond; 00431 r_comp->statements = (r_decl, r_slave3); 00432 00433 Configure( MakeCheckUncombable(s_switch), r_comp ); 00434 } 00435 00436 00437 DoToIfGoto::DoToIfGoto() 00438 { 00439 // Create a compound block, put the body of the loop in there with a Label 00440 // at the top and a conditional goto (if(x) goto y;) at the bottom, using the 00441 // same expression as the Do. continue just becomes a Goto directly to the If. 00442 // 00443 // We prevent the continue transformation from acting on continues in nested 00444 // blocks using the same method as seen in BreakToGoto. 00445 00446 MakeTreePtr<Do> s_do; 00447 MakeTreePtr<If> r_if; 00448 MakeTreePtr<Statement> body; 00449 MakeTreePtr<Expression> cond; 00450 MakeTreePtr<Goto> r_goto, l_r_goto; 00451 MakeTreePtr<Nop> r_nop; 00452 MakeTreePtr<Compound> r_comp; 00453 MakeTreePtr<BuildLabelIdentifier> r_labelid("NEXT"), l_r_cont_labelid("CONTINUE"); 00454 MakeTreePtr<Label> r_label, r_cont_label; 00455 MakeTreePtr< Stuff<Statement> > l_stuff; 00456 MakeTreePtr< Overlay<Statement> > l_overlay; 00457 MakeTreePtr<Continue> l_s_cont; 00458 MakeTreePtr< NotMatch<Statement> > l_s_not; 00459 MakeTreePtr< Loop > l_s_loop; 00460 00461 l_s_not->pattern = l_s_loop; 00462 l_overlay->through = l_s_cont; 00463 l_stuff->recurse_restriction = l_s_not; 00464 l_overlay->overlay = l_r_goto; 00465 l_r_goto->destination = l_r_cont_labelid; 00466 00467 MakeTreePtr< SlaveCompareReplace<Statement> > r_slave( body, l_stuff, l_stuff ); 00468 l_stuff->terminus = l_overlay; 00469 00470 s_do->condition = cond; 00471 s_do->body = body; 00472 00473 r_comp->statements = (r_label, r_slave, r_cont_label, r_if); 00474 r_label->identifier = r_labelid; 00475 r_cont_label->identifier = l_r_cont_labelid; 00476 r_if->condition = cond; 00477 r_if->body = r_goto; 00478 r_if->else_body = r_nop; 00479 r_goto->destination = r_labelid; 00480 00481 Configure( MakeCheckUncombable(s_do), r_comp ); 00482 } 00483 00484 BreakToGoto::BreakToGoto() 00485 { 00486 // We determine the right block to exit by: 00487 // 1. Creating an intermediate node Breakable, which is a base for 00488 // Switch and Loop (and hence For, While, Do). We search for this. 00489 // 2. The Break is reached via a Stuff node whose recurse 00490 // restriction is set to not recurse through any Breakable 00491 // blocks, so we won't find a Break that is not for us. 00492 MakeTreePtr<Breakable> breakable, sx_breakable; 00493 MakeTreePtr< Stuff<Statement> > stuff; 00494 MakeTreePtr< Overlay<Statement> > overlay; 00495 MakeTreePtr< NotMatch<Statement> > sx_not; 00496 MakeTreePtr<Break> s_break; 00497 MakeTreePtr<Goto> r_goto; 00498 MakeTreePtr<BuildLabelIdentifier> r_labelid("BREAK"); 00499 MakeTreePtr<Label> r_label; 00500 MakeTreePtr<Compound> r_comp; 00501 00502 sx_not->pattern = sx_breakable; 00503 stuff->terminus = overlay; 00504 overlay->through = s_break; 00505 stuff->recurse_restriction = sx_not; 00506 overlay->overlay = r_goto; 00507 r_goto->destination = r_labelid; 00508 breakable->body = stuff; 00509 00510 r_comp->statements = (breakable, r_label); 00511 r_label->identifier = r_labelid; 00512 00513 Configure( MakeCheckUncombable( breakable ), r_comp ); 00514 } 00515 00516 00517 LogicalAndToIf::LogicalAndToIf() 00518 { 00519 MakeTreePtr<LogicalAnd> s_and; 00520 MakeTreePtr<Expression> op1, op2; 00521 MakeTreePtr<CompoundExpression> r_comp; 00522 MakeTreePtr<BuildInstanceIdentifier> r_temp_id("andtemp"); 00523 MakeTreePtr<Temporary> r_temp; 00524 MakeTreePtr<Boolean> r_boolean; 00525 MakeTreePtr<If> r_if; 00526 MakeTreePtr<Assign> r_assign1, r_assign2; 00527 00528 s_and->operands = (op1, op2); 00529 00530 r_comp->members = (r_temp); 00531 r_temp->identifier = r_temp_id; 00532 r_temp->type= r_boolean; 00533 r_temp->initialiser = MakeTreePtr<Uninitialised>(); 00534 r_comp->statements = (r_assign1, r_if, r_temp_id); 00535 r_assign1->operands = (r_temp_id, op1); 00536 r_if->condition = r_temp_id; 00537 r_if->body = r_assign2; 00538 r_if->else_body = MakeTreePtr<Nop>(); 00539 r_assign2->operands = (r_temp_id, op2); 00540 00541 Configure( MakeCheckUncombable( s_and ), r_comp ); 00542 } 00543 00544 00545 LogicalOrToIf::LogicalOrToIf() 00546 { 00547 MakeTreePtr<LogicalOr> s_or; 00548 MakeTreePtr<Expression> op1, op2; 00549 MakeTreePtr<CompoundExpression> r_comp; 00550 MakeTreePtr<BuildInstanceIdentifier> r_temp_id("ortemp"); 00551 MakeTreePtr<Temporary> r_temp; 00552 MakeTreePtr<Boolean> r_boolean; 00553 MakeTreePtr<If> r_if; 00554 MakeTreePtr<Assign> r_assign1, r_assign2; 00555 00556 s_or->operands = (op1, op2); 00557 00558 r_comp->members = (r_temp); 00559 r_temp->identifier = r_temp_id; 00560 r_temp->type= r_boolean; 00561 r_temp->initialiser = MakeTreePtr<Uninitialised>(); 00562 r_comp->statements = (r_assign1, r_if, r_temp_id); 00563 r_assign1->operands = (r_temp_id, op1); 00564 r_if->condition = r_temp_id; 00565 r_if->body = MakeTreePtr<Nop>(); 00566 r_if->else_body = r_assign2; 00567 r_assign2->operands = (r_temp_id, op2); 00568 00569 Configure( MakeCheckUncombable(s_or), r_comp ); 00570 } 00571 00572 00573 MultiplexorToIf::MultiplexorToIf() 00574 { 00575 MakeTreePtr<Multiplexor> s_mux; 00576 MakeTreePtr<Expression> op1, op3; 00577 MakeTreePtr<CompoundExpression> r_comp; 00578 MakeTreePtr<BuildInstanceIdentifier> r_temp_id("muxtemp"); 00579 MakeTreePtr<Temporary> r_temp; 00580 MakeTreePtr< TransformOf<Expression> > op2( &TypeOf::instance ); 00581 MakeTreePtr<Type> type; 00582 MakeTreePtr<If> r_if; 00583 MakeTreePtr<Assign> r_assignt, r_assignf; 00584 00585 s_mux->operands = (op1, op2, op3); 00586 op2->pattern = type; 00587 00588 r_comp->members = (r_temp); 00589 r_temp->identifier = r_temp_id; 00590 r_temp->type= type; 00591 r_temp->initialiser = MakeTreePtr<Uninitialised>(); 00592 r_comp->statements = (r_if, r_temp_id); 00593 r_if->condition = op1; 00594 r_if->body = r_assignt; 00595 r_if->else_body = r_assignf; 00596 r_assignt->operands = (r_temp_id, op2); 00597 r_assignf->operands = (r_temp_id, op3); 00598 00599 Configure( MakeCheckUncombable(s_mux), r_comp ); 00600 } 00601 00602 00603 ExtractCallParams::ExtractCallParams() 00604 { 00605 MakeTreePtr<Call> s_call, r_call; 00606 MakeTreePtr<BuildInstanceIdentifier> r_temp_id("temp_%s"); 00607 MakeTreePtr<Temporary> r_temp; 00608 MakeTreePtr<CompoundExpression> r_ce; 00609 MakeTreePtr<Assign> r_assign; 00610 MakeTreePtr< Star<MapOperand> > params; 00611 MakeTreePtr<MapOperand> s_param, r_param; 00612 MakeTreePtr< TransformOf<Expression> > value( &TypeOf::instance ); 00613 MakeTreePtr<Type> type; 00614 MakeTreePtr<Expression> callee; 00615 MakeTreePtr<InstanceIdentifier> id; 00616 MakeTreePtr< MatchAll<Expression> > all; 00617 MakeTreePtr< NotMatch<Expression> > x_not; 00618 MakeTreePtr<InstanceIdentifier> x_id; 00619 00620 s_call->operands = (params, s_param); 00621 s_param->value = all; 00622 all->patterns = (value, x_not); 00623 s_param->identifier = id; 00624 value->pattern = type; 00625 s_call->callee = callee; 00626 x_not->pattern = x_id; // this restriction to become light-touch restriction 00627 00628 r_ce->members = (r_temp); 00629 r_temp->identifier = r_temp_id; 00630 r_temp_id->sources = (id); 00631 r_temp->initialiser = MakeTreePtr<Uninitialised>(); 00632 r_temp->type = type; 00633 r_ce->statements = (r_assign, r_call); 00634 r_assign->operands = (r_temp_id, value); 00635 r_call->operands = (params, r_param); 00636 r_param->value = r_temp_id; 00637 r_param->identifier = id; 00638 r_call->callee = callee; 00639 00640 Configure( MakeCheckUncombable(s_call), r_ce ); 00641 }