diff options
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 26 |
1 files changed, 14 insertions, 12 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.179 2002/05/07 17:36:56 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.180 2002/05/10 17:02:32 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 | */ |
@@ -367,7 +367,7 @@ static void open_func (LexState *ls, FuncState *fs) { | |||
367 | ls->fs = fs; | 367 | ls->fs = fs; |
368 | fs->pc = 0; | 368 | fs->pc = 0; |
369 | fs->lasttarget = 0; | 369 | fs->lasttarget = 0; |
370 | fs->jlt = NO_JUMP; | 370 | fs->jpc = NO_JUMP; |
371 | fs->freereg = 0; | 371 | fs->freereg = 0; |
372 | fs->nk = 0; | 372 | fs->nk = 0; |
373 | fs->h = luaH_new(ls->L, 0, 0); | 373 | fs->h = luaH_new(ls->L, 0, 0); |
@@ -391,7 +391,6 @@ static void close_func (LexState *ls) { | |||
391 | Proto *f = fs->f; | 391 | Proto *f = fs->f; |
392 | removevars(ls, 0); | 392 | removevars(ls, 0); |
393 | luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */ | 393 | luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */ |
394 | luaK_getlabel(fs); /* close eventual list of pending jumps */ | ||
395 | lua_assert(G(L)->roottable == fs->h); | 394 | lua_assert(G(L)->roottable == fs->h); |
396 | G(L)->roottable = fs->h->next; | 395 | G(L)->roottable = fs->h->next; |
397 | luaH_free(L, fs->h); | 396 | luaH_free(L, fs->h); |
@@ -977,30 +976,33 @@ static void whilestat (LexState *ls, int line) { | |||
977 | int i; | 976 | int i; |
978 | int sizeexp; | 977 | int sizeexp; |
979 | FuncState *fs = ls->fs; | 978 | FuncState *fs = ls->fs; |
980 | int while_init = luaK_getlabel(fs); | 979 | int whileinit, blockinit, expinit; |
981 | expdesc v; | 980 | expdesc v; |
982 | BlockCnt bl; | 981 | BlockCnt bl; |
983 | next(ls); | 982 | next(ls); |
983 | whileinit = luaK_jump(fs); | ||
984 | expinit = luaK_getlabel(fs); | ||
984 | expr(ls, &v); | 985 | expr(ls, &v); |
985 | if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */ | 986 | if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */ |
986 | lineexp = ls->linenumber; | 987 | lineexp = ls->linenumber; |
987 | luaK_goiffalse(fs, &v); | 988 | luaK_goiffalse(fs, &v); |
988 | sizeexp = fs->pc - while_init; | 989 | luaK_dischargejpc(fs); |
990 | sizeexp = fs->pc - expinit; | ||
989 | if (sizeexp > MAXEXPWHILE) | 991 | if (sizeexp > MAXEXPWHILE) |
990 | luaX_syntaxerror(ls, "while condition too complex"); | 992 | luaX_syntaxerror(ls, "while condition too complex"); |
991 | fs->pc = while_init; /* remove `exp' code */ | ||
992 | luaK_getlabel(fs); | ||
993 | for (i = 0; i < sizeexp; i++) /* save `exp' code */ | 993 | for (i = 0; i < sizeexp; i++) /* save `exp' code */ |
994 | codeexp[i] = fs->f->code[while_init + i]; | 994 | codeexp[i] = fs->f->code[expinit + i]; |
995 | luaK_jump(fs); | 995 | fs->pc = expinit; /* remove `exp' code */ |
996 | enterblock(fs, &bl, 1); | 996 | enterblock(fs, &bl, 1); |
997 | check(ls, TK_DO); | 997 | check(ls, TK_DO); |
998 | blockinit = luaK_getlabel(fs); | ||
998 | block(ls); | 999 | block(ls); |
999 | luaK_patchtohere(fs, while_init); /* initial jump jumps to here */ | 1000 | luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */ |
1000 | luaK_moveexp(&v, fs->pc - while_init); /* correct pointers */ | 1001 | if (v.t != NO_JUMP) v.t += fs->pc - expinit; |
1002 | if (v.f != NO_JUMP) v.f += fs->pc - expinit; | ||
1001 | for (i=0; i<sizeexp; i++) | 1003 | for (i=0; i<sizeexp; i++) |
1002 | luaK_code(fs, codeexp[i], lineexp); | 1004 | luaK_code(fs, codeexp[i], lineexp); |
1003 | luaK_patchlist(fs, v.t, while_init+1); | 1005 | luaK_patchlist(fs, v.t, blockinit); |
1004 | luaK_patchtohere(fs, v.f); | 1006 | luaK_patchtohere(fs, v.f); |
1005 | check_match(ls, TK_END, TK_WHILE, line); | 1007 | check_match(ls, TK_END, TK_WHILE, line); |
1006 | leaveblock(fs); | 1008 | leaveblock(fs); |