| 1437 | |
| 1438 | |
| 1439 | static void test_then_block(LexState *ls, int *escapelist) { |
| 1440 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ |
| 1441 | BlockCnt bl; |
| 1442 | FuncState *fs = ls->fs; |
| 1443 | expdesc v; |
| 1444 | int jf; /* instruction to skip 'then' code (if condition is false) */ |
| 1445 | luaX_next(ls); /* skip IF or ELSEIF */ |
| 1446 | expr(ls, &v); /* read condition */ |
| 1447 | checknext(ls, TK_THEN); |
| 1448 | if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { |
| 1449 | luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ |
| 1450 | enterblock(fs, &bl, 0); /* must enter block before 'goto' */ |
| 1451 | gotostat(ls, v.t); /* handle goto/break */ |
| 1452 | skipnoopstat(ls); /* skip other no-op statements */ |
| 1453 | if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ |
| 1454 | leaveblock(fs); |
| 1455 | return; /* and that is it */ |
| 1456 | } |
| 1457 | else /* must skip over 'then' part if condition is false */ |
| 1458 | jf = luaK_jump(fs); |
| 1459 | } |
| 1460 | else { /* regular case (not goto/break) */ |
| 1461 | luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ |
| 1462 | enterblock(fs, &bl, 0); |
| 1463 | jf = v.f; |
| 1464 | } |
| 1465 | statlist(ls); /* 'then' part */ |
| 1466 | if (ls->L->force_stopping) |
| 1467 | return; |
| 1468 | leaveblock(fs); |
| 1469 | if (ls->t.token == TK_ELSE || |
| 1470 | ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ |
| 1471 | luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ |
| 1472 | luaK_patchtohere(fs, jf); |
| 1473 | } |
| 1474 | |
| 1475 | |
| 1476 | static void ifstat(LexState *ls, int line) { |
no test coverage detected