diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-04-09 16:47:44 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-04-09 16:47:44 -0300 |
commit | 7b65328c8e89ecc999e47d00288bfa4cf6692cdc (patch) | |
tree | 4bff202763e7389ca40a44003703376d32eeaf78 | |
parent | d2e05589d738c3a1b563879435d5cc0830719fd1 (diff) | |
download | lua-7b65328c8e89ecc999e47d00288bfa4cf6692cdc.tar.gz lua-7b65328c8e89ecc999e47d00288bfa4cf6692cdc.tar.bz2 lua-7b65328c8e89ecc999e47d00288bfa4cf6692cdc.zip |
new semantics for `generic for' (with state)
-rw-r--r-- | ldebug.c | 5 | ||||
-rw-r--r-- | lopcodes.c | 4 | ||||
-rw-r--r-- | lopcodes.h | 7 | ||||
-rw-r--r-- | lparser.c | 24 | ||||
-rw-r--r-- | lvm.c | 26 |
5 files changed, 35 insertions, 31 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 1.105 2002/03/25 17:47:14 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.106 2002/04/04 17:21:31 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -347,8 +347,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
347 | break; | 347 | break; |
348 | } | 348 | } |
349 | case OP_TFORLOOP: { | 349 | case OP_TFORLOOP: { |
350 | checkreg(pt, a+c); | 350 | checkreg(pt, a+2+c); |
351 | checkreg(pt, a+2); /* at least 2 for table generators */ | ||
352 | check(pc+2 < pt->sizecode); /* check skip */ | 351 | check(pc+2 < pt->sizecode); /* check skip */ |
353 | break; | 352 | break; |
354 | } | 353 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.c,v 1.13 2002/03/21 20:32:22 roberto Exp roberto $ | 2 | ** $Id: lopcodes.c,v 1.14 2002/03/25 17:47:14 roberto Exp roberto $ |
3 | ** extracted automatically from lopcodes.h by mkprint.lua | 3 | ** extracted automatically from lopcodes.h by mkprint.lua |
4 | ** DO NOT EDIT | 4 | ** DO NOT EDIT |
5 | ** See Copyright Notice in lua.h | 5 | ** See Copyright Notice in lua.h |
@@ -49,6 +49,7 @@ const char *const luaP_opnames[] = { | |||
49 | "RETURN", | 49 | "RETURN", |
50 | "FORLOOP", | 50 | "FORLOOP", |
51 | "TFORLOOP", | 51 | "TFORLOOP", |
52 | "OP_TFORPREP", | ||
52 | "SETLIST", | 53 | "SETLIST", |
53 | "SETLISTO", | 54 | "SETLISTO", |
54 | "CLOSE", | 55 | "CLOSE", |
@@ -98,6 +99,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
98 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ | 99 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ |
99 | ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_FORLOOP */ | 100 | ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_FORLOOP */ |
100 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_TFORLOOP */ | 101 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_TFORLOOP */ |
102 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_TFORPREP */ | ||
101 | ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLIST */ | 103 | ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLIST */ |
102 | ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLISTO */ | 104 | ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLISTO */ |
103 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */ | 105 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.92 2002/03/21 20:32:22 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.93 2002/03/25 17:47:14 roberto Exp roberto $ |
3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -173,8 +173,9 @@ OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see (3)) */ | |||
173 | 173 | ||
174 | OP_FORLOOP,/* A sBc R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBc */ | 174 | OP_FORLOOP,/* A sBc R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBc */ |
175 | 175 | ||
176 | OP_TFORLOOP,/* A C R(A+1), ... ,R(A+C) := R(A)(); | 176 | OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); |
177 | if R(A+1) ~= nil then pc++ */ | 177 | if R(A+2) ~= nil then pc++ */ |
178 | OP_TFORPREP,/* A if type(R(A)) == table then R(A+1):=R(A), R(A):=next */ | ||
178 | 179 | ||
179 | OP_SETLIST,/* A Bc R(A)[Bc-Bc%FPF+i] := R(A+i), 1 <= i <= Bc%FPF+1 */ | 180 | OP_SETLIST,/* A Bc R(A)[Bc-Bc%FPF+i] := R(A+i), 1 <= i <= Bc%FPF+1 */ |
180 | OP_SETLISTO,/* A Bc */ | 181 | OP_SETLISTO,/* A Bc */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.173 2002/03/25 17:47:14 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.174 2002/04/02 20:34:15 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 | */ |
@@ -331,6 +331,7 @@ static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) { | |||
331 | bl->upval = 0; | 331 | bl->upval = 0; |
332 | bl->previous = fs->bl; | 332 | bl->previous = fs->bl; |
333 | fs->bl = bl; | 333 | fs->bl = bl; |
334 | lua_assert(fs->freereg == fs->nactloc); | ||
334 | } | 335 | } |
335 | 336 | ||
336 | 337 | ||
@@ -1028,24 +1029,25 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1028 | 1029 | ||
1029 | 1030 | ||
1030 | static void forlist (LexState *ls, TString *indexname) { | 1031 | static void forlist (LexState *ls, TString *indexname) { |
1031 | /* forlist -> NAME {,NAME} IN exp1 DO body */ | 1032 | /* forlist -> NAME {,NAME} IN explist1 DO body */ |
1032 | FuncState *fs = ls->fs; | 1033 | FuncState *fs = ls->fs; |
1034 | expdesc e; | ||
1033 | int nvars = 0; | 1035 | int nvars = 0; |
1034 | int prep; | 1036 | int prep; |
1035 | int base = fs->freereg; | 1037 | int base = fs->freereg; |
1036 | new_localvarstr(ls, "(for generator)", 0); | 1038 | new_localvarstr(ls, "(for generator)", nvars++); |
1037 | new_localvar(ls, indexname, ++nvars); | 1039 | new_localvarstr(ls, "(for state)", nvars++); |
1040 | new_localvar(ls, indexname, nvars++); | ||
1038 | while (optional(ls, ',')) { | 1041 | while (optional(ls, ',')) { |
1039 | new_localvar(ls, str_checkname(ls), ++nvars); | 1042 | new_localvar(ls, str_checkname(ls), nvars++); |
1040 | next(ls); | 1043 | next(ls); |
1041 | } | 1044 | } |
1042 | check(ls, TK_IN); | 1045 | check(ls, TK_IN); |
1043 | exp1(ls); /* table */ | 1046 | adjust_assign(ls, 3, explist1(ls, &e), &e); |
1044 | luaK_checkstack(fs, 2); /* at least two slots, to traverse tables */ | 1047 | luaK_reserveregs(fs, nvars - 3); /* registers for other variables */ |
1045 | luaK_reserveregs(fs, nvars); /* registers for vars */ | 1048 | luaK_codeABC(fs, OP_TFORPREP, base, 0, 0); |
1046 | luaK_codeABC(fs, OP_LOADNIL, base+1, base+nvars, 0); | 1049 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); |
1047 | adjustlocalvars(ls, nvars+1); /* scope for control variables */ | 1050 | adjustlocalvars(ls, nvars); /* scope for all variables */ |
1048 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); | ||
1049 | prep = luaK_jump(fs); | 1051 | prep = luaK_jump(fs); |
1050 | check(ls, TK_DO); | 1052 | check(ls, TK_DO); |
1051 | block(ls); | 1053 | block(ls); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.222 2002/03/22 16:54:31 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.223 2002/03/25 17:47:14 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -549,21 +549,21 @@ StkId luaV_execute (lua_State *L) { | |||
549 | break; | 549 | break; |
550 | } | 550 | } |
551 | case OP_TFORLOOP: { | 551 | case OP_TFORLOOP: { |
552 | setobj(ra+4, ra+2); | ||
553 | setobj(ra+3, ra+1); | ||
554 | setobj(ra+2, ra); | ||
555 | L->top = ra+5; | ||
556 | luaD_call(L, ra+2, GETARG_C(i) + 1); | ||
557 | L->top = L->ci->top; | ||
558 | if (ttype(ra+2) != LUA_TNIL) pc++; /* skip jump (keep looping) */ | ||
559 | break; | ||
560 | } | ||
561 | case OP_TFORPREP: { | ||
552 | if (ttype(ra) == LUA_TTABLE) { | 562 | if (ttype(ra) == LUA_TTABLE) { |
553 | Table *t = hvalue(ra); | ||
554 | if (luaH_next(L, t, ra+1)) | ||
555 | pc++; /* skip jump (keep looping) */ | ||
556 | } | ||
557 | else if (ttype(ra) == LUA_TFUNCTION) { | ||
558 | setobj(ra+1, ra); | 563 | setobj(ra+1, ra); |
559 | L->top = ra+2; /* no arguments */ | 564 | setsvalue(ra, luaS_new(L, "next")); |
560 | luaD_call(L, ra+1, GETARG_C(i)); | 565 | luaV_gettable(L, gt(L), ra, ra); |
561 | L->top = L->ci->top; | ||
562 | if (ttype(ra+1) != LUA_TNIL) | ||
563 | pc++; /* skip jump (keep looping) */ | ||
564 | } | 566 | } |
565 | else | ||
566 | luaD_error(L, "`for' generator must be a table or function"); | ||
567 | break; | 567 | break; |
568 | } | 568 | } |
569 | case OP_SETLIST: | 569 | case OP_SETLIST: |