simpler implementation of for loops
This commit is contained in:
13
lcode.c
13
lcode.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lcode.c,v 1.57 2001/01/19 13:20:30 roberto Exp roberto $
|
** $Id: lcode.c,v 1.58 2001/01/29 13:14:49 roberto Exp roberto $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -59,6 +59,17 @@ static void luaK_fixjump (FuncState *fs, int pc, int dest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** prep-for instructions (OP_FORPREP & OP_LFORPREP) have a negated jump,
|
||||||
|
** as they simulate the real jump...
|
||||||
|
*/
|
||||||
|
void luaK_fixfor (FuncState *fs, int pc, int dest) {
|
||||||
|
Instruction *jmp = &fs->f->code[pc];
|
||||||
|
int offset = dest-(pc+1);
|
||||||
|
SETARG_S(*jmp, -offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int luaK_getjump (FuncState *fs, int pc) {
|
static int luaK_getjump (FuncState *fs, int pc) {
|
||||||
int offset = GETARG_S(fs->f->code[pc]);
|
int offset = GETARG_S(fs->f->code[pc]);
|
||||||
if (offset == NO_JUMP) /* point to itself represents end of list */
|
if (offset == NO_JUMP) /* point to itself represents end of list */
|
||||||
|
|||||||
3
lcode.h
3
lcode.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lcode.h,v 1.17 2000/11/30 18:50:47 roberto Exp roberto $
|
** $Id: lcode.h,v 1.18 2000/12/04 18:33:40 roberto Exp roberto $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -53,6 +53,7 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1);
|
|||||||
int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2);
|
int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2);
|
||||||
int luaK_jump (FuncState *fs);
|
int luaK_jump (FuncState *fs);
|
||||||
void luaK_patchlist (FuncState *fs, int list, int target);
|
void luaK_patchlist (FuncState *fs, int list, int target);
|
||||||
|
void luaK_fixfor (FuncState *fs, int pc, int dest);
|
||||||
void luaK_concat (FuncState *fs, int *l1, int l2);
|
void luaK_concat (FuncState *fs, int *l1, int l2);
|
||||||
void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue);
|
void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue);
|
||||||
int luaK_getlabel (FuncState *fs);
|
int luaK_getlabel (FuncState *fs);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 1.125 2001/01/19 13:20:30 roberto Exp roberto $
|
** $Id: lparser.c,v 1.126 2001/01/29 13:14:49 roberto Exp roberto $
|
||||||
** LL(1) Parser and code generator for Lua
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -854,7 +854,7 @@ static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) {
|
|||||||
adjustlocalvars(ls, nvar); /* scope for control variables */
|
adjustlocalvars(ls, nvar); /* scope for control variables */
|
||||||
block(ls);
|
block(ls);
|
||||||
luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit);
|
luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit);
|
||||||
luaK_patchlist(fs, prep, luaK_getlabel(fs));
|
luaK_fixfor(fs, prep, luaK_getlabel(fs));
|
||||||
removelocalvars(ls, nvar);
|
removelocalvars(ls, nvar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
36
lvm.c
36
lvm.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 1.158 2001/01/26 18:43:22 roberto Exp roberto $
|
** $Id: lvm.c,v 1.159 2001/01/29 13:02:20 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -330,7 +330,7 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define dojump(pc, i) { int d = GETARG_S(i); pc += d; }
|
#define dojump(pc, i) ((pc) += GETARG_S(i))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Executes the given Lua function. Parameters are between [base,top).
|
** 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) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_FORPREP: {
|
case OP_FORPREP: {
|
||||||
|
int jmp = GETARG_S(i);
|
||||||
if (tonumber(top-1))
|
if (tonumber(top-1))
|
||||||
luaD_error(L, "`for' step must be a number");
|
luaD_error(L, "`for' step must be a number");
|
||||||
if (tonumber(top-2))
|
if (tonumber(top-2))
|
||||||
luaD_error(L, "`for' limit must be a number");
|
luaD_error(L, "`for' limit must be a number");
|
||||||
if (tonumber(top-3))
|
if (tonumber(top-3))
|
||||||
luaD_error(L, "`for' initial value must be a number");
|
luaD_error(L, "`for' initial value must be a number");
|
||||||
if (nvalue(top-1) > 0 ?
|
pc += -jmp; /* "jump" to loop end (delta is negated here) */
|
||||||
nvalue(top-3) > nvalue(top-2) :
|
goto forloop; /* do not increment index */
|
||||||
nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */
|
|
||||||
top -= 3; /* remove control variables */
|
|
||||||
dojump(pc, i); /* jump to loop end */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case OP_FORLOOP: {
|
case OP_FORLOOP: {
|
||||||
lua_assert(ttype(top-1) == LUA_TNUMBER);
|
lua_assert(ttype(top-1) == LUA_TNUMBER);
|
||||||
@@ -635,6 +631,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
|
|||||||
if (ttype(top-3) != LUA_TNUMBER)
|
if (ttype(top-3) != LUA_TNUMBER)
|
||||||
luaD_error(L, "`for' index must be a number");
|
luaD_error(L, "`for' index must be a number");
|
||||||
nvalue(top-3) += nvalue(top-1); /* increment index */
|
nvalue(top-3) += nvalue(top-1); /* increment index */
|
||||||
|
forloop:
|
||||||
if (nvalue(top-1) > 0 ?
|
if (nvalue(top-1) > 0 ?
|
||||||
nvalue(top-3) > nvalue(top-2) :
|
nvalue(top-3) > nvalue(top-2) :
|
||||||
nvalue(top-3) < nvalue(top-2))
|
nvalue(top-3) < nvalue(top-2))
|
||||||
@@ -644,24 +641,15 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_LFORPREP: {
|
case OP_LFORPREP: {
|
||||||
int n;
|
int jmp = GETARG_S(i);
|
||||||
Hash *t;
|
|
||||||
if (ttype(top-1) != LUA_TTABLE)
|
if (ttype(top-1) != LUA_TTABLE)
|
||||||
luaD_error(L, "`for' table must be a table");
|
luaD_error(L, "`for' table must be a table");
|
||||||
t = hvalue(top-1);
|
|
||||||
n = luaH_nexti(t, -1);
|
|
||||||
if (n == -1) { /* `empty' loop? */
|
|
||||||
top--; /* remove table */
|
|
||||||
dojump(pc, i); /* jump to loop end */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Node *node = node(t, n);
|
|
||||||
top += 3; /* index,key,value */
|
top += 3; /* index,key,value */
|
||||||
setnvalue(top-3, n); /* index */
|
setnvalue(top-3, -1); /* initial index */
|
||||||
setobj(top-2, key(node));
|
setnilvalue(top-2);
|
||||||
setobj(top-1, val(node));
|
setnilvalue(top-1);
|
||||||
}
|
pc += -jmp; /* "jump" to loop end (delta is negated here) */
|
||||||
break;
|
/* go through */
|
||||||
}
|
}
|
||||||
case OP_LFORLOOP: {
|
case OP_LFORLOOP: {
|
||||||
Hash *t = hvalue(top-4);
|
Hash *t = hvalue(top-4);
|
||||||
|
|||||||
Reference in New Issue
Block a user