diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-29 13:26:40 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-29 13:26:40 -0200 |
| commit | 3b6f8bfbe688fdd0f1c17bd023140804155624f3 (patch) | |
| tree | 9cb2bedcaded8e46e9cd471f7247ddce2916d633 | |
| parent | caf01b5bfa33617b7bb2c40292f74599f6030eba (diff) | |
| download | lua-3b6f8bfbe688fdd0f1c17bd023140804155624f3.tar.gz lua-3b6f8bfbe688fdd0f1c17bd023140804155624f3.tar.bz2 lua-3b6f8bfbe688fdd0f1c17bd023140804155624f3.zip | |
simpler implementation of for loops
| -rw-r--r-- | lcode.c | 13 | ||||
| -rw-r--r-- | lcode.h | 3 | ||||
| -rw-r--r-- | lparser.c | 4 | ||||
| -rw-r--r-- | lvm.c | 38 |
4 files changed, 29 insertions, 29 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.57 2001/01/19 13:20:30 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.58 2001/01/29 13:14:49 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -59,6 +59,17 @@ static void luaK_fixjump (FuncState *fs, int pc, int dest) { | |||
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | 61 | ||
| 62 | /* | ||
| 63 | ** prep-for instructions (OP_FORPREP & OP_LFORPREP) have a negated jump, | ||
| 64 | ** as they simulate the real jump... | ||
| 65 | */ | ||
| 66 | void luaK_fixfor (FuncState *fs, int pc, int dest) { | ||
| 67 | Instruction *jmp = &fs->f->code[pc]; | ||
| 68 | int offset = dest-(pc+1); | ||
| 69 | SETARG_S(*jmp, -offset); | ||
| 70 | } | ||
| 71 | |||
| 72 | |||
| 62 | static int luaK_getjump (FuncState *fs, int pc) { | 73 | static int luaK_getjump (FuncState *fs, int pc) { |
| 63 | int offset = GETARG_S(fs->f->code[pc]); | 74 | int offset = GETARG_S(fs->f->code[pc]); |
| 64 | if (offset == NO_JUMP) /* point to itself represents end of list */ | 75 | if (offset == NO_JUMP) /* point to itself represents end of list */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.h,v 1.17 2000/11/30 18:50:47 roberto Exp roberto $ | 2 | ** $Id: lcode.h,v 1.18 2000/12/04 18:33:40 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -53,6 +53,7 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1); | |||
| 53 | int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2); | 53 | int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2); |
| 54 | int luaK_jump (FuncState *fs); | 54 | int luaK_jump (FuncState *fs); |
| 55 | void luaK_patchlist (FuncState *fs, int list, int target); | 55 | void luaK_patchlist (FuncState *fs, int list, int target); |
| 56 | void luaK_fixfor (FuncState *fs, int pc, int dest); | ||
| 56 | void luaK_concat (FuncState *fs, int *l1, int l2); | 57 | void luaK_concat (FuncState *fs, int *l1, int l2); |
| 57 | void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue); | 58 | void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue); |
| 58 | int luaK_getlabel (FuncState *fs); | 59 | int luaK_getlabel (FuncState *fs); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.125 2001/01/19 13:20:30 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.126 2001/01/29 13:14:49 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -854,7 +854,7 @@ static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) { | |||
| 854 | adjustlocalvars(ls, nvar); /* scope for control variables */ | 854 | adjustlocalvars(ls, nvar); /* scope for control variables */ |
| 855 | block(ls); | 855 | block(ls); |
| 856 | luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); | 856 | luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); |
| 857 | luaK_patchlist(fs, prep, luaK_getlabel(fs)); | 857 | luaK_fixfor(fs, prep, luaK_getlabel(fs)); |
| 858 | removelocalvars(ls, nvar); | 858 | removelocalvars(ls, nvar); |
| 859 | } | 859 | } |
| 860 | 860 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.158 2001/01/26 18:43:22 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.159 2001/01/29 13:02:20 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 | */ |
| @@ -330,7 +330,7 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | |||
| 330 | 330 | ||
| 331 | 331 | ||
| 332 | 332 | ||
| 333 | #define dojump(pc, i) { int d = GETARG_S(i); pc += d; } | 333 | #define dojump(pc, i) ((pc) += GETARG_S(i)) |
| 334 | 334 | ||
| 335 | /* | 335 | /* |
| 336 | ** Executes the given Lua function. Parameters are between [base,top). | 336 | ** Executes the given Lua function. Parameters are between [base,top). |
| @@ -615,19 +615,15 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 615 | break; | 615 | break; |
| 616 | } | 616 | } |
| 617 | case OP_FORPREP: { | 617 | case OP_FORPREP: { |
| 618 | int jmp = GETARG_S(i); | ||
| 618 | if (tonumber(top-1)) | 619 | if (tonumber(top-1)) |
| 619 | luaD_error(L, "`for' step must be a number"); | 620 | luaD_error(L, "`for' step must be a number"); |
| 620 | if (tonumber(top-2)) | 621 | if (tonumber(top-2)) |
| 621 | luaD_error(L, "`for' limit must be a number"); | 622 | luaD_error(L, "`for' limit must be a number"); |
| 622 | if (tonumber(top-3)) | 623 | if (tonumber(top-3)) |
| 623 | luaD_error(L, "`for' initial value must be a number"); | 624 | luaD_error(L, "`for' initial value must be a number"); |
| 624 | if (nvalue(top-1) > 0 ? | 625 | pc += -jmp; /* "jump" to loop end (delta is negated here) */ |
| 625 | nvalue(top-3) > nvalue(top-2) : | 626 | goto forloop; /* do not increment index */ |
| 626 | nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */ | ||
| 627 | top -= 3; /* remove control variables */ | ||
| 628 | dojump(pc, i); /* jump to loop end */ | ||
| 629 | } | ||
| 630 | break; | ||
| 631 | } | 627 | } |
| 632 | case OP_FORLOOP: { | 628 | case OP_FORLOOP: { |
| 633 | lua_assert(ttype(top-1) == LUA_TNUMBER); | 629 | lua_assert(ttype(top-1) == LUA_TNUMBER); |
| @@ -635,6 +631,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 635 | if (ttype(top-3) != LUA_TNUMBER) | 631 | if (ttype(top-3) != LUA_TNUMBER) |
| 636 | luaD_error(L, "`for' index must be a number"); | 632 | luaD_error(L, "`for' index must be a number"); |
| 637 | nvalue(top-3) += nvalue(top-1); /* increment index */ | 633 | nvalue(top-3) += nvalue(top-1); /* increment index */ |
| 634 | forloop: | ||
| 638 | if (nvalue(top-1) > 0 ? | 635 | if (nvalue(top-1) > 0 ? |
| 639 | nvalue(top-3) > nvalue(top-2) : | 636 | nvalue(top-3) > nvalue(top-2) : |
| 640 | nvalue(top-3) < nvalue(top-2)) | 637 | nvalue(top-3) < nvalue(top-2)) |
| @@ -644,24 +641,15 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 644 | break; | 641 | break; |
| 645 | } | 642 | } |
| 646 | case OP_LFORPREP: { | 643 | case OP_LFORPREP: { |
| 647 | int n; | 644 | int jmp = GETARG_S(i); |
| 648 | Hash *t; | ||
| 649 | if (ttype(top-1) != LUA_TTABLE) | 645 | if (ttype(top-1) != LUA_TTABLE) |
| 650 | luaD_error(L, "`for' table must be a table"); | 646 | luaD_error(L, "`for' table must be a table"); |
| 651 | t = hvalue(top-1); | 647 | top += 3; /* index,key,value */ |
| 652 | n = luaH_nexti(t, -1); | 648 | setnvalue(top-3, -1); /* initial index */ |
| 653 | if (n == -1) { /* `empty' loop? */ | 649 | setnilvalue(top-2); |
| 654 | top--; /* remove table */ | 650 | setnilvalue(top-1); |
| 655 | dojump(pc, i); /* jump to loop end */ | 651 | pc += -jmp; /* "jump" to loop end (delta is negated here) */ |
| 656 | } | 652 | /* go through */ |
| 657 | else { | ||
| 658 | Node *node = node(t, n); | ||
| 659 | top += 3; /* index,key,value */ | ||
| 660 | setnvalue(top-3, n); /* index */ | ||
| 661 | setobj(top-2, key(node)); | ||
| 662 | setobj(top-1, val(node)); | ||
| 663 | } | ||
| 664 | break; | ||
| 665 | } | 653 | } |
| 666 | case OP_LFORLOOP: { | 654 | case OP_LFORLOOP: { |
| 667 | Hash *t = hvalue(top-4); | 655 | Hash *t = hvalue(top-4); |
