MCPcopy Create free account
hub / github.com/EmmyLua/EmmyLuaDebugger / forstat

Function forstat

third-party/lua-5.2.4/src/lparser.c:1356–1637  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1354
1355
1356static void forstat (LexState *ls, int line) {
1357 /* forstat -> FOR (fornum | forlist) END */
1358 FuncState *fs = ls->fs;
1359 TString *varname;
1360 BlockCnt bl;
1361 enterblock(fs, &bl, 1); /* scope for loop and control variables */
1362 luaX_next(ls); /* skip `for' */
1363 varname = str_checkname(ls); /* first variable name */
1364 switch (ls->t.token) {
1365 case '=': fornum(ls, varname, line); break;
1366 case ',': case TK_IN: forlist(ls, varname); break;
1367 default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
1368 }
1369 check_match(ls, TK_END, TK_FOR, line);
1370 leaveblock(fs); /* loop scope (`break' jumps to this point) */
1371}
1372
1373
1374static void test_then_block (LexState *ls, int *escapelist) {
1375 /* test_then_block -> [IF | ELSEIF] cond THEN block */
1376 BlockCnt bl;
1377 FuncState *fs = ls->fs;
1378 expdesc v;
1379 int jf; /* instruction to skip 'then' code (if condition is false) */
1380 luaX_next(ls); /* skip IF or ELSEIF */
1381 expr(ls, &v); /* read condition */
1382 checknext(ls, TK_THEN);
1383 if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
1384 luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
1385 enterblock(fs, &bl, 0); /* must enter block before 'goto' */
1386 gotostat(ls, v.t); /* handle goto/break */
1387 skipnoopstat(ls); /* skip other no-op statements */
1388 if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
1389 leaveblock(fs);
1390 return; /* and that is it */
1391 }
1392 else /* must skip over 'then' part if condition is false */
1393 jf = luaK_jump(fs);
1394 }
1395 else { /* regular case (not goto/break) */
1396 luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
1397 enterblock(fs, &bl, 0);
1398 jf = v.f;
1399 }
1400 statlist(ls); /* `then' part */
1401 leaveblock(fs);
1402 if (ls->t.token == TK_ELSE ||
1403 ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */
1404 luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */
1405 luaK_patchtohere(fs, jf);
1406}
1407
1408
1409static void ifstat (LexState *ls, int line) {
1410 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
1411 FuncState *fs = ls->fs;
1412 int escapelist = NO_JUMP; /* exit list for finished parts */
1413 test_then_block(ls, &escapelist); /* IF cond THEN block */

Callers 1

statementFunction · 0.70

Calls 7

enterblockFunction · 0.70
luaX_nextFunction · 0.70
str_checknameFunction · 0.70
fornumFunction · 0.70
forlistFunction · 0.70
luaX_syntaxerrorFunction · 0.70
leaveblockFunction · 0.70

Tested by

no test coverage detected