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

Function replaceGeneratorWhile

src/ast/ast_generate.cpp:1290–1426  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1288 }
1289
1290 ExpressionPtr replaceGeneratorWhile ( ExprWhile * expr, const FunctionPtr & func ) {
1291 auto begin_loop_label = func->totalGenLabel ++;
1292 auto iter_end_loop_label = func->totalGenLabel ++;
1293 auto end_loop_label = func->totalGenLabel ++;
1294 ExprBlock * bodyBlock = nullptr;
1295 const bool hasFinally = expr->body->rtti_isBlock() &&
1296 !static_cast<ExprBlock*>(expr->body)->finalList.empty();
1297 // only introduce __broke / __returning flags when body has a finally —
1298 // otherwise classic break -> end, and return just exits the enclosing function
1299 string breakFlag, returnFlag, returnValueName;
1300 bool hasReturn = false;
1301 if ( hasFinally ) {
1302 breakFlag = "__broke_while_" + to_string(expr->at.line) + "_" + to_string(expr->at.column);
1303 hasReturn = bodyHasTopLevelReturn(expr->body);
1304 if ( hasReturn ) {
1305 returnFlag = "__returning_while_" + to_string(expr->at.line) + "_" + to_string(expr->at.column);
1306 returnValueName = "__return_value_while_" + to_string(expr->at.line) + "_" + to_string(expr->at.column);
1307 }
1308 }
1309 if ( expr->body->rtti_isBlock() ) {
1310 bodyBlock = static_cast<ExprBlock*>(expr->body->clone());
1311 giveBlockVariablesUniqueNames(bodyBlock);
1312 if ( hasFinally ) {
1313 // break -> set flag, goto iter_end (runs finally, then exits via flag check)
1314 // continue -> iter_end (runs finally, flag=false, loops back)
1315 // return -> spill value, set flag, goto iter_end (runs finally, then real return)
1316 replaceBreakContinueAndReturn(bodyBlock, iter_end_loop_label, iter_end_loop_label, breakFlag,
1317 iter_end_loop_label, returnFlag, returnValueName);
1318 } else {
1319 replaceBreakAndContinue(bodyBlock, end_loop_label, begin_loop_label);
1320 }
1321 }
1322 auto blk = new ExprBlock();
1323 blk->at = expr->at;
1324 blk->isCollapseable = true;
1325 // __broke = false (only when finally present)
1326 if ( hasFinally ) {
1327 auto leqt = new ExprLet();
1328 leqt->at = expr->at;
1329 leqt->atInit = expr->at;
1330 leqt->visibility = expr->at;
1331 auto bvar = new Variable();
1332 bvar->generated = true;
1333 bvar->at = expr->at;
1334 bvar->name = breakFlag;
1335 bvar->type = new TypeDecl(Type::tBool);
1336 bvar->init = new ExprConstBool(expr->at, false);
1337 leqt->variables.push_back(bvar);
1338 blk->list.push_back(leqt);
1339 }
1340 // __returning = false; __return_value : <func->result> (only when body has return)
1341 if ( hasReturn ) {
1342 auto leqt = new ExprLet();
1343 leqt->at = expr->at;
1344 leqt->atInit = expr->at;
1345 leqt->visibility = expr->at;
1346 auto rvar = new Variable();
1347 rvar->generated = true;

Callers 1

visitMethod · 0.85

Calls 10

to_stringFunction · 0.85
bodyHasTopLevelReturnFunction · 0.85
replaceBreakAndContinueFunction · 0.85
verifyGeneratedFunction · 0.85
isVoidMethod · 0.80
emptyMethod · 0.45
cloneMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected