diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-05-13 10:09:00 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-05-13 10:09:00 -0300 |
commit | af19d556355b6e79296811cb18fe511f8784b8f1 (patch) | |
tree | 2126e8dec5d21939bb2ff298f29f0d429c62d7db /lparser.c | |
parent | b55fded18c270412e127259a5f28c785620dbf1a (diff) | |
download | lua-af19d556355b6e79296811cb18fe511f8784b8f1.tar.gz lua-af19d556355b6e79296811cb18fe511f8784b8f1.tar.bz2 lua-af19d556355b6e79296811cb18fe511f8784b8f1.zip |
generic for also coded to make test at the end of the loop
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 34 |
1 files changed, 20 insertions, 14 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.180 2002/05/10 17:02:32 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.181 2002/05/10 19:22:11 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 | */ |
@@ -979,15 +979,16 @@ static void whilestat (LexState *ls, int line) { | |||
979 | int whileinit, blockinit, expinit; | 979 | int whileinit, blockinit, expinit; |
980 | expdesc v; | 980 | expdesc v; |
981 | BlockCnt bl; | 981 | BlockCnt bl; |
982 | next(ls); | 982 | next(ls); /* skip WHILE */ |
983 | whileinit = luaK_jump(fs); | 983 | whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */ |
984 | expinit = luaK_getlabel(fs); | 984 | expinit = luaK_getlabel(fs); |
985 | expr(ls, &v); | 985 | expr(ls, &v); /* parse condition */ |
986 | 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 */ |
987 | lineexp = ls->linenumber; | 987 | lineexp = ls->linenumber; |
988 | luaK_goiffalse(fs, &v); | 988 | luaK_goiffalse(fs, &v); |
989 | luaK_dischargejpc(fs); | 989 | luaK_concat(fs, &v.f, fs->jpc); |
990 | sizeexp = fs->pc - expinit; | 990 | fs->jpc = NO_JUMP; |
991 | sizeexp = fs->pc - expinit; /* size of expression code */ | ||
991 | if (sizeexp > MAXEXPWHILE) | 992 | if (sizeexp > MAXEXPWHILE) |
992 | luaX_syntaxerror(ls, "while condition too complex"); | 993 | luaX_syntaxerror(ls, "while condition too complex"); |
993 | for (i = 0; i < sizeexp; i++) /* save `exp' code */ | 994 | for (i = 0; i < sizeexp; i++) /* save `exp' code */ |
@@ -998,14 +999,15 @@ static void whilestat (LexState *ls, int line) { | |||
998 | blockinit = luaK_getlabel(fs); | 999 | blockinit = luaK_getlabel(fs); |
999 | block(ls); | 1000 | block(ls); |
1000 | luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */ | 1001 | luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */ |
1002 | /* move `exp' back to code */ | ||
1001 | if (v.t != NO_JUMP) v.t += fs->pc - expinit; | 1003 | if (v.t != NO_JUMP) v.t += fs->pc - expinit; |
1002 | if (v.f != NO_JUMP) v.f += fs->pc - expinit; | 1004 | if (v.f != NO_JUMP) v.f += fs->pc - expinit; |
1003 | for (i=0; i<sizeexp; i++) | 1005 | for (i=0; i<sizeexp; i++) |
1004 | luaK_code(fs, codeexp[i], lineexp); | 1006 | luaK_code(fs, codeexp[i], lineexp); |
1005 | luaK_patchlist(fs, v.t, blockinit); | ||
1006 | luaK_patchtohere(fs, v.f); | ||
1007 | check_match(ls, TK_END, TK_WHILE, line); | 1007 | check_match(ls, TK_END, TK_WHILE, line); |
1008 | leaveblock(fs); | 1008 | leaveblock(fs); |
1009 | luaK_patchlist(fs, v.t, blockinit); /* true conditions go back to loop */ | ||
1010 | luaK_patchtohere(fs, v.f); /* false conditions finish the loop */ | ||
1009 | } | 1011 | } |
1010 | 1012 | ||
1011 | 1013 | ||
@@ -1061,8 +1063,8 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1061 | block(ls); | 1063 | block(ls); |
1062 | luaK_patchtohere(fs, prep-1); | 1064 | luaK_patchtohere(fs, prep-1); |
1063 | endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); | 1065 | endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); |
1066 | luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ | ||
1064 | luaK_patchlist(fs, endfor, prep); | 1067 | luaK_patchlist(fs, endfor, prep); |
1065 | fs->f->lineinfo[endfor] = line; /* pretend that `OP_FOR' starts the loop */ | ||
1066 | } | 1068 | } |
1067 | 1069 | ||
1068 | 1070 | ||
@@ -1070,6 +1072,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1070 | /* forlist -> NAME {,NAME} IN explist1 DO body */ | 1072 | /* forlist -> NAME {,NAME} IN explist1 DO body */ |
1071 | FuncState *fs = ls->fs; | 1073 | FuncState *fs = ls->fs; |
1072 | expdesc e; | 1074 | expdesc e; |
1075 | int line; | ||
1073 | int nvars = 0; | 1076 | int nvars = 0; |
1074 | int prep; | 1077 | int prep; |
1075 | int base = fs->freereg; | 1078 | int base = fs->freereg; |
@@ -1081,16 +1084,19 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1081 | next(ls); | 1084 | next(ls); |
1082 | } | 1085 | } |
1083 | check(ls, TK_IN); | 1086 | check(ls, TK_IN); |
1087 | line = ls->linenumber; | ||
1084 | adjust_assign(ls, 3, explist1(ls, &e), &e); | 1088 | adjust_assign(ls, 3, explist1(ls, &e), &e); |
1085 | luaK_reserveregs(fs, nvars - 3); /* registers for other variables */ | 1089 | luaK_reserveregs(fs, nvars - 3); /* registers for other variables */ |
1086 | luaK_codeABC(fs, OP_TFORPREP, base, 0, 0); | 1090 | luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP); |
1087 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); | ||
1088 | adjustlocalvars(ls, nvars); /* scope for all variables */ | 1091 | adjustlocalvars(ls, nvars); /* scope for all variables */ |
1089 | prep = luaK_jump(fs); | ||
1090 | check(ls, TK_DO); | 1092 | check(ls, TK_DO); |
1093 | prep = luaK_getlabel(fs); | ||
1091 | block(ls); | 1094 | block(ls); |
1092 | luaK_patchlist(fs, luaK_jump(fs), prep-1); | 1095 | luaK_patchtohere(fs, prep-1); |
1093 | luaK_patchtohere(fs, prep); | 1096 | removevars(fs->ls, fs->nactvar - nvars); /* deactivate locals for next op. */ |
1097 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); | ||
1098 | luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ | ||
1099 | luaK_patchlist(fs, luaK_jump(fs), prep); | ||
1094 | } | 1100 | } |
1095 | 1101 | ||
1096 | 1102 | ||