diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-08-25 10:45:24 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-08-25 10:45:24 -0300 |
| commit | 121dc8af663c775404ace50c89344bbc94c48262 (patch) | |
| tree | d92ea13f559e2e5ce6099cf6d2b4435366880279 | |
| parent | a8675966eca71f005acd002df89053ee142ecef6 (diff) | |
| download | lua-121dc8af663c775404ace50c89344bbc94c48262.tar.gz lua-121dc8af663c775404ace50c89344bbc94c48262.tar.bz2 lua-121dc8af663c775404ace50c89344bbc94c48262.zip | |
cleaner code for 'if' construct
| -rw-r--r-- | lparser.c | 34 |
1 files changed, 14 insertions, 20 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 2.115 2011/07/27 18:09:01 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.116 2011/08/23 17:24:34 roberto Exp roberto $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -1360,38 +1360,32 @@ static void forstat (LexState *ls, int line) { | |||
| 1360 | } | 1360 | } |
| 1361 | 1361 | ||
| 1362 | 1362 | ||
| 1363 | static int test_then_block (LexState *ls) { | 1363 | static void test_then_block (LexState *ls, int *escapelist) { |
| 1364 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ | 1364 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ |
| 1365 | FuncState *fs = ls->fs; | ||
| 1365 | int condexit; | 1366 | int condexit; |
| 1366 | luaX_next(ls); /* skip IF or ELSEIF */ | 1367 | luaX_next(ls); /* skip IF or ELSEIF */ |
| 1367 | condexit = cond(ls); | 1368 | condexit = cond(ls); /* 'if' condition */ |
| 1368 | checknext(ls, TK_THEN); | 1369 | checknext(ls, TK_THEN); |
| 1369 | block(ls); /* `then' part */ | 1370 | block(ls); /* `then' part */ |
| 1370 | return condexit; | 1371 | if (ls->t.token == TK_ELSE || |
| 1372 | ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ | ||
| 1373 | luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ | ||
| 1374 | luaK_patchtohere(fs, condexit); /* 'if' condition jumps to here */ | ||
| 1371 | } | 1375 | } |
| 1372 | 1376 | ||
| 1373 | 1377 | ||
| 1374 | static void ifstat (LexState *ls, int line) { | 1378 | static void ifstat (LexState *ls, int line) { |
| 1375 | /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ | 1379 | /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ |
| 1376 | FuncState *fs = ls->fs; | 1380 | FuncState *fs = ls->fs; |
| 1377 | int flist; | 1381 | int escapelist = NO_JUMP; /* exit list for finished parts */ |
| 1378 | int escapelist = NO_JUMP; | 1382 | test_then_block(ls, &escapelist); /* IF cond THEN block */ |
| 1379 | flist = test_then_block(ls); /* IF cond THEN block */ | 1383 | while (ls->t.token == TK_ELSEIF) |
| 1380 | while (ls->t.token == TK_ELSEIF) { | 1384 | test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ |
| 1381 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 1385 | if (testnext(ls, TK_ELSE)) |
| 1382 | luaK_patchtohere(fs, flist); | ||
| 1383 | flist = test_then_block(ls); /* ELSEIF cond THEN block */ | ||
| 1384 | } | ||
| 1385 | if (ls->t.token == TK_ELSE) { | ||
| 1386 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | ||
| 1387 | luaK_patchtohere(fs, flist); | ||
| 1388 | luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ | ||
| 1389 | block(ls); /* `else' part */ | 1386 | block(ls); /* `else' part */ |
| 1390 | } | ||
| 1391 | else | ||
| 1392 | luaK_concat(fs, &escapelist, flist); | ||
| 1393 | luaK_patchtohere(fs, escapelist); | ||
| 1394 | check_match(ls, TK_END, TK_IF, line); | 1387 | check_match(ls, TK_END, TK_IF, line); |
| 1388 | luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ | ||
| 1395 | } | 1389 | } |
| 1396 | 1390 | ||
| 1397 | 1391 | ||
