MCPcopy Create free account
hub / github.com/GaijinEntertainment/daScript / replaceGeneratorFor

Function replaceGeneratorFor

src/ast/ast_generate.cpp:1433–1723  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1431 }
1432
1433 ExpressionPtr replaceGeneratorFor ( ExprFor * expr, const FunctionPtr & func ) {
1434 auto begin_loop_label = func->totalGenLabel ++;
1435 auto mid_loop_label = func->totalGenLabel ++;
1436 auto end_loop_label = func->totalGenLabel ++;
1437 ExprFor * forCopy = nullptr;
1438 ExprBlock * bodyBlock = nullptr;
1439 const bool hasFinally = expr->body->rtti_isBlock() &&
1440 !static_cast<ExprBlock*>(expr->body)->finalList.empty();
1441 string breakFlag, returnFlag, returnValueName;
1442 bool hasReturn = false;
1443 if ( hasFinally ) {
1444 breakFlag = "__broke_for_" + to_string(expr->at.line) + "_" + to_string(expr->at.column);
1445 hasReturn = bodyHasTopLevelReturn(expr->body);
1446 if ( hasReturn ) {
1447 returnFlag = "__returning_for_" + to_string(expr->at.line) + "_" + to_string(expr->at.column);
1448 returnValueName = "__return_value_for_" + to_string(expr->at.line) + "_" + to_string(expr->at.column);
1449 }
1450 }
1451 if ( expr->body->rtti_isBlock() ) {
1452 forCopy = static_cast<ExprFor*>(expr->clone());
1453 bodyBlock = static_cast<ExprBlock*>(forCopy->body);
1454 giveBlockVariablesUniqueNames(forCopy);
1455 if ( hasFinally ) {
1456 // break -> set flag, goto mid (finally runs, flag check -> end, iterator_close runs)
1457 // continue -> mid (finally runs, advances iterator, re-checks)
1458 // return -> spill value, set flag, goto mid (finally runs, then real return)
1459 replaceBreakContinueAndReturn(bodyBlock, mid_loop_label, mid_loop_label, breakFlag,
1460 mid_loop_label, returnFlag, returnValueName);
1461 } else {
1462 replaceBreakAndContinue(bodyBlock, end_loop_label, mid_loop_label);
1463 }
1464 expr = forCopy;
1465 }
1466 auto blk = new ExprBlock();
1467 blk->at = expr->at;
1468 blk->isCollapseable = true;
1469 auto gtel = new ExprGoto(expr->at, end_loop_label);
1470 auto btel = new ExprBlock();
1471 btel->at = expr->at;
1472 btel->list.push_back(gtel);
1473 // names
1474 string loopVar = "_loop_at_" + to_string(expr->at.line) + "_" + to_string(expr->at.column);
1475 vector<string> srcNames, pVarNames;
1476 for ( size_t si=0, sis=expr->sources.size(); si!=sis; ++si ) {
1477 srcNames.push_back("_source_" + to_string(si) + "_at_" + to_string(expr->at.line) + "_" + to_string(expr->at.column));
1478 pVarNames.push_back("_pvar_" + to_string(si) + "_at_" + to_string(expr->at.line) + "_" + to_string(expr->at.column));
1479 }
1480 auto leqt = new ExprLet();
1481 leqt->at = expr->at;
1482 leqt->atInit = expr->at;
1483 leqt->visibility = expr->visibility;
1484 auto lvar = new Variable();
1485 lvar->generated = true;
1486 lvar->at = expr->at;
1487 lvar->name = loopVar;
1488 lvar->type = new TypeDecl(Type::tBool);
1489 lvar->init = new ExprConstBool(expr->at, true);
1490 leqt->variables.push_back(lvar);

Callers 1

visitMethod · 0.85

Calls 14

to_stringFunction · 0.85
bodyHasTopLevelReturnFunction · 0.85
replaceBreakAndContinueFunction · 0.85
srcNeedTempVarFunction · 0.85
replaceRef2PtrFunction · 0.85
verifyGeneratedFunction · 0.85
isVoidMethod · 0.80
isGoodIteratorTypeMethod · 0.80
emptyMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected