diff options
-rw-r--r-- | ljumptab.h | 2 | ||||
-rw-r--r-- | lopcodes.c | 2 | ||||
-rw-r--r-- | lopcodes.h | 4 | ||||
-rw-r--r-- | lopnames.h | 2 | ||||
-rw-r--r-- | lparser.c | 42 | ||||
-rw-r--r-- | lvm.c | 147 | ||||
-rw-r--r-- | manual/manual.of | 124 | ||||
-rw-r--r-- | testes/code.lua | 4 | ||||
-rw-r--r-- | testes/db.lua | 2 | ||||
-rw-r--r-- | testes/nextvar.lua | 73 |
10 files changed, 215 insertions, 187 deletions
@@ -99,8 +99,6 @@ static void *disptab[NUM_OPCODES] = { | |||
99 | &&L_OP_RETURN, | 99 | &&L_OP_RETURN, |
100 | &&L_OP_RETURN0, | 100 | &&L_OP_RETURN0, |
101 | &&L_OP_RETURN1, | 101 | &&L_OP_RETURN1, |
102 | &&L_OP_FORLOOP1, | ||
103 | &&L_OP_FORPREP1, | ||
104 | &&L_OP_FORLOOP, | 102 | &&L_OP_FORLOOP, |
105 | &&L_OP_FORPREP, | 103 | &&L_OP_FORPREP, |
106 | &&L_OP_TFORPREP, | 104 | &&L_OP_TFORPREP, |
@@ -93,8 +93,6 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
93 | ,opmode(0, 1, 0, 0, iABC) /* OP_RETURN */ | 93 | ,opmode(0, 1, 0, 0, iABC) /* OP_RETURN */ |
94 | ,opmode(0, 0, 0, 0, iABC) /* OP_RETURN0 */ | 94 | ,opmode(0, 0, 0, 0, iABC) /* OP_RETURN0 */ |
95 | ,opmode(0, 0, 0, 0, iABC) /* OP_RETURN1 */ | 95 | ,opmode(0, 0, 0, 0, iABC) /* OP_RETURN1 */ |
96 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORLOOP1 */ | ||
97 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORPREP1 */ | ||
98 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORLOOP */ | 96 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORLOOP */ |
99 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORPREP */ | 97 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORPREP */ |
100 | ,opmode(0, 0, 0, 0, iABx) /* OP_TFORPREP */ | 98 | ,opmode(0, 0, 0, 0, iABx) /* OP_TFORPREP */ |
@@ -280,10 +280,6 @@ OP_RETURN,/* A B C return R(A), ... ,R(A+B-2) (see note) */ | |||
280 | OP_RETURN0,/* return */ | 280 | OP_RETURN0,/* return */ |
281 | OP_RETURN1,/* A return R(A) */ | 281 | OP_RETURN1,/* A return R(A) */ |
282 | 282 | ||
283 | OP_FORLOOP1,/* A Bx R(A)++; | ||
284 | if R(A) <= R(A+1) then { pc-=Bx; R(A+3)=R(A) } */ | ||
285 | OP_FORPREP1,/* A Bx R(A)--; pc+=Bx */ | ||
286 | |||
287 | OP_FORLOOP,/* A Bx R(A)+=R(A+2); | 283 | OP_FORLOOP,/* A Bx R(A)+=R(A+2); |
288 | if R(A) <?= R(A+1) then { pc-=Bx; R(A+3)=R(A) } */ | 284 | if R(A) <?= R(A+1) then { pc-=Bx; R(A+3)=R(A) } */ |
289 | OP_FORPREP,/* A Bx R(A)-=R(A+2); pc+=Bx */ | 285 | OP_FORPREP,/* A Bx R(A)-=R(A+2); pc+=Bx */ |
@@ -84,8 +84,6 @@ static const char *const opnames[] = { | |||
84 | "RETURN", | 84 | "RETURN", |
85 | "RETURN0", | 85 | "RETURN0", |
86 | "RETURN1", | 86 | "RETURN1", |
87 | "FORLOOP1", | ||
88 | "FORPREP1", | ||
89 | "FORLOOP", | 87 | "FORLOOP", |
90 | "FORPREP", | 88 | "FORPREP", |
91 | "TFORPREP", | 89 | "TFORPREP", |
@@ -1371,18 +1371,14 @@ static void repeatstat (LexState *ls, int line) { | |||
1371 | 1371 | ||
1372 | /* | 1372 | /* |
1373 | ** Read an expression and generate code to put its results in next | 1373 | ** Read an expression and generate code to put its results in next |
1374 | ** stack slot. Return true if expression is a constant integer and, | 1374 | ** stack slot. |
1375 | ** if 'i' is not-zero, its value is equal to 'i'. | ||
1376 | ** | 1375 | ** |
1377 | */ | 1376 | */ |
1378 | static int exp1 (LexState *ls, int i) { | 1377 | static void exp1 (LexState *ls) { |
1379 | expdesc e; | 1378 | expdesc e; |
1380 | int res; | ||
1381 | expr(ls, &e); | 1379 | expr(ls, &e); |
1382 | res = luaK_isKint(&e) && (i == 0 || i == e.u.ival); | ||
1383 | luaK_exp2nextreg(ls->fs, &e); | 1380 | luaK_exp2nextreg(ls->fs, &e); |
1384 | lua_assert(e.k == VNONRELOC); | 1381 | lua_assert(e.k == VNONRELOC); |
1385 | return res; | ||
1386 | } | 1382 | } |
1387 | 1383 | ||
1388 | 1384 | ||
@@ -1403,31 +1399,29 @@ static void fixforjump (FuncState *fs, int pc, int dest, int back) { | |||
1403 | 1399 | ||
1404 | 1400 | ||
1405 | /* | 1401 | /* |
1406 | ** Generate code for a 'for' loop. 'kind' can be zero (a common for | 1402 | ** Generate code for a 'for' loop. |
1407 | ** loop), one (a basic for loop, with integer values and increment of | ||
1408 | ** 1), or two (a generic for loop). | ||
1409 | */ | 1403 | */ |
1410 | static void forbody (LexState *ls, int base, int line, int nvars, int kind) { | 1404 | static void forbody (LexState *ls, int base, int line, int nvars, int isgen) { |
1411 | /* forbody -> DO block */ | 1405 | /* forbody -> DO block */ |
1412 | static OpCode forprep[3] = {OP_FORPREP, OP_FORPREP1, OP_TFORPREP}; | 1406 | static OpCode forprep[2] = {OP_FORPREP, OP_TFORPREP}; |
1413 | static OpCode forloop[3] = {OP_FORLOOP, OP_FORLOOP1, OP_TFORLOOP}; | 1407 | static OpCode forloop[2] = {OP_FORLOOP, OP_TFORLOOP}; |
1414 | BlockCnt bl; | 1408 | BlockCnt bl; |
1415 | FuncState *fs = ls->fs; | 1409 | FuncState *fs = ls->fs; |
1416 | int prep, endfor; | 1410 | int prep, endfor; |
1417 | checknext(ls, TK_DO); | 1411 | checknext(ls, TK_DO); |
1418 | prep = luaK_codeABx(fs, forprep[kind], base, 0); | 1412 | prep = luaK_codeABx(fs, forprep[isgen], base, 0); |
1419 | enterblock(fs, &bl, 0); /* scope for declared variables */ | 1413 | enterblock(fs, &bl, 0); /* scope for declared variables */ |
1420 | adjustlocalvars(ls, nvars); | 1414 | adjustlocalvars(ls, nvars); |
1421 | luaK_reserveregs(fs, nvars); | 1415 | luaK_reserveregs(fs, nvars); |
1422 | block(ls); | 1416 | block(ls); |
1423 | leaveblock(fs); /* end of scope for declared variables */ | 1417 | leaveblock(fs); /* end of scope for declared variables */ |
1424 | fixforjump(fs, prep, luaK_getlabel(fs), 0); | 1418 | fixforjump(fs, prep, luaK_getlabel(fs), 0); |
1425 | if (kind == 2) { /* generic for? */ | 1419 | if (isgen) { /* generic for? */ |
1426 | luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); | 1420 | luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); |
1427 | luaK_fixline(fs, line); | 1421 | luaK_fixline(fs, line); |
1428 | base += 2; /* base for 'OP_TFORLOOP' (skips function and state) */ | 1422 | base += 2; /* base for 'OP_TFORLOOP' (skips function and state) */ |
1429 | } | 1423 | } |
1430 | endfor = luaK_codeABx(fs, forloop[kind], base, 0); | 1424 | endfor = luaK_codeABx(fs, forloop[isgen], base, 0); |
1431 | fixforjump(fs, endfor, prep + 1, 1); | 1425 | fixforjump(fs, endfor, prep + 1, 1); |
1432 | luaK_fixline(fs, line); | 1426 | luaK_fixline(fs, line); |
1433 | } | 1427 | } |
@@ -1437,26 +1431,22 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1437 | /* fornum -> NAME = exp,exp[,exp] forbody */ | 1431 | /* fornum -> NAME = exp,exp[,exp] forbody */ |
1438 | FuncState *fs = ls->fs; | 1432 | FuncState *fs = ls->fs; |
1439 | int base = fs->freereg; | 1433 | int base = fs->freereg; |
1440 | int basicfor = 1; /* true if it is a "basic" 'for' (integer + 1) */ | ||
1441 | new_localvarliteral(ls, "(for index)"); | 1434 | new_localvarliteral(ls, "(for index)"); |
1442 | new_localvarliteral(ls, "(for limit)"); | 1435 | new_localvarliteral(ls, "(for limit)"); |
1443 | new_localvarliteral(ls, "(for step)"); | 1436 | new_localvarliteral(ls, "(for step)"); |
1444 | new_localvar(ls, varname); | 1437 | new_localvar(ls, varname); |
1445 | checknext(ls, '='); | 1438 | checknext(ls, '='); |
1446 | if (!exp1(ls, 0)) /* initial value not an integer? */ | 1439 | exp1(ls); /* initial value */ |
1447 | basicfor = 0; /* not a basic 'for' */ | ||
1448 | checknext(ls, ','); | 1440 | checknext(ls, ','); |
1449 | exp1(ls, 0); /* limit */ | 1441 | exp1(ls); /* limit */ |
1450 | if (testnext(ls, ',')) { | 1442 | if (testnext(ls, ',')) |
1451 | if (!exp1(ls, 1)) /* optional step not 1? */ | 1443 | exp1(ls); /* optional step */ |
1452 | basicfor = 0; /* not a basic 'for' */ | ||
1453 | } | ||
1454 | else { /* default step = 1 */ | 1444 | else { /* default step = 1 */ |
1455 | luaK_int(fs, fs->freereg, 1); | 1445 | luaK_int(fs, fs->freereg, 1); |
1456 | luaK_reserveregs(fs, 1); | 1446 | luaK_reserveregs(fs, 1); |
1457 | } | 1447 | } |
1458 | adjustlocalvars(ls, 3); /* control variables */ | 1448 | adjustlocalvars(ls, 3); /* control variables */ |
1459 | forbody(ls, base, line, 1, basicfor); | 1449 | forbody(ls, base, line, 1, 0); |
1460 | } | 1450 | } |
1461 | 1451 | ||
1462 | 1452 | ||
@@ -1484,7 +1474,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1484 | adjust_assign(ls, 4, explist(ls, &e), &e); | 1474 | adjust_assign(ls, 4, explist(ls, &e), &e); |
1485 | adjustlocalvars(ls, 4); /* control variables */ | 1475 | adjustlocalvars(ls, 4); /* control variables */ |
1486 | luaK_checkstack(fs, 3); /* extra space to call generator */ | 1476 | luaK_checkstack(fs, 3); /* extra space to call generator */ |
1487 | forbody(ls, base, line, nvars - 4, 2); | 1477 | forbody(ls, base, line, nvars - 4, 1); |
1488 | } | 1478 | } |
1489 | 1479 | ||
1490 | 1480 | ||
@@ -1633,7 +1623,7 @@ static void tocloselocalstat (LexState *ls) { | |||
1633 | luaO_pushfstring(ls->L, "unknown attribute '%s'", getstr(attr))); | 1623 | luaO_pushfstring(ls->L, "unknown attribute '%s'", getstr(attr))); |
1634 | new_localvar(ls, str_checkname(ls)); | 1624 | new_localvar(ls, str_checkname(ls)); |
1635 | checknext(ls, '='); | 1625 | checknext(ls, '='); |
1636 | exp1(ls, 0); | 1626 | exp1(ls); |
1637 | markupval(fs, fs->nactvar); | 1627 | markupval(fs, fs->nactvar); |
1638 | fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ | 1628 | fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ |
1639 | adjustlocalvars(ls, 1); | 1629 | adjustlocalvars(ls, 1); |
@@ -148,35 +148,34 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | |||
148 | 148 | ||
149 | /* | 149 | /* |
150 | ** Try to convert a 'for' limit to an integer, preserving the semantics | 150 | ** Try to convert a 'for' limit to an integer, preserving the semantics |
151 | ** of the loop. (The following explanation assumes a non-negative step; | 151 | ** of the loop. (The following explanation assumes a positive step; |
152 | ** it is valid for negative steps mutatis mutandis.) | 152 | ** it is valid for negative steps mutatis mutandis.) |
153 | ** If the limit is an integer or can be converted to an integer, | 153 | ** If the limit is an integer or can be converted to an integer, |
154 | ** rounding down, that is it. | 154 | ** rounding down, that is it. |
155 | ** Otherwise, check whether the limit can be converted to a float. If | 155 | ** Otherwise, check whether the limit can be converted to a float. If |
156 | ** the number is too large, it is OK to set the limit as LUA_MAXINTEGER, | 156 | ** the float is too large, clip it to LUA_MAXINTEGER. If the float |
157 | ** which means no limit. If the number is too negative, the loop | 157 | ** is too negative, the loop should not run, because any initial |
158 | ** should not run, because any initial integer value is larger than the | 158 | ** integer value is greater than such limit; so, it sets 'stopnow'. |
159 | ** limit. So, it sets the limit to LUA_MININTEGER. 'stopnow' corrects | 159 | ** (For this latter case, no integer limit would be correct; even a |
160 | ** the extreme case when the initial value is LUA_MININTEGER, in which | 160 | ** limit of LUA_MININTEGER would run the loop once for an initial |
161 | ** case the LUA_MININTEGER limit would still run the loop once. | 161 | ** value equal to LUA_MININTEGER.) |
162 | */ | 162 | */ |
163 | static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, | 163 | static int forlimit (const TValue *lim, lua_Integer *p, lua_Integer step, |
164 | int *stopnow) { | 164 | int *stopnow) { |
165 | *stopnow = 0; /* usually, let loops run */ | 165 | *stopnow = 0; /* usually, let loops run */ |
166 | if (ttisinteger(obj)) | 166 | if (!luaV_tointeger(lim, p, (step < 0 ? 2 : 1))) { |
167 | *p = ivalue(obj); | ||
168 | else if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) { | ||
169 | /* not coercible to in integer */ | 167 | /* not coercible to in integer */ |
170 | lua_Number n; /* try to convert to float */ | 168 | lua_Number flim; /* try to convert to float */ |
171 | if (!tonumber(obj, &n)) /* cannot convert to float? */ | 169 | if (!tonumber(lim, &flim)) /* cannot convert to float? */ |
172 | return 0; /* not a number */ | 170 | return 0; /* not a number */ |
173 | if (luai_numlt(0, n)) { /* if true, float is larger than max integer */ | 171 | /* 'flim' is a float out of integer bounds */ |
174 | *p = LUA_MAXINTEGER; | 172 | if (luai_numlt(0, flim)) { /* if it is positive, it is too large */ |
175 | if (step < 0) *stopnow = 1; | 173 | *p = LUA_MAXINTEGER; /* truncate */ |
174 | if (step < 0) *stopnow = 1; /* initial value must be less than it */ | ||
176 | } | 175 | } |
177 | else { /* float is less than min integer */ | 176 | else { /* it is less than min integer */ |
178 | *p = LUA_MININTEGER; | 177 | *p = LUA_MININTEGER; /* truncate */ |
179 | if (step >= 0) *stopnow = 1; | 178 | if (step > 0) *stopnow = 1; /* initial value must be greater than it */ |
180 | } | 179 | } |
181 | } | 180 | } |
182 | return 1; | 181 | return 1; |
@@ -1636,85 +1635,87 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1636 | } | 1635 | } |
1637 | return; | 1636 | return; |
1638 | } | 1637 | } |
1639 | vmcase(OP_FORLOOP1) { | ||
1640 | lua_Integer idx = intop(+, ivalue(s2v(ra)), 1); /* increment index */ | ||
1641 | lua_Integer limit = ivalue(s2v(ra + 1)); | ||
1642 | if (idx <= limit) { | ||
1643 | pc -= GETARG_Bx(i); /* jump back */ | ||
1644 | chgivalue(s2v(ra), idx); /* update internal index... */ | ||
1645 | setivalue(s2v(ra + 3), idx); /* ...and external index */ | ||
1646 | } | ||
1647 | updatetrap(ci); | ||
1648 | vmbreak; | ||
1649 | } | ||
1650 | vmcase(OP_FORPREP1) { | ||
1651 | TValue *init = s2v(ra); | ||
1652 | TValue *plimit = s2v(ra + 1); | ||
1653 | lua_Integer ilimit, initv; | ||
1654 | int stopnow; | ||
1655 | if (unlikely(!forlimit(plimit, &ilimit, 1, &stopnow))) { | ||
1656 | savestate(L, ci); /* for the error message */ | ||
1657 | luaG_forerror(L, plimit, "limit"); | ||
1658 | } | ||
1659 | initv = (stopnow ? 0 : ivalue(init)); | ||
1660 | setivalue(plimit, ilimit); | ||
1661 | setivalue(init, intop(-, initv, 1)); | ||
1662 | pc += GETARG_Bx(i); | ||
1663 | vmbreak; | ||
1664 | } | ||
1665 | vmcase(OP_FORLOOP) { | 1638 | vmcase(OP_FORLOOP) { |
1666 | if (ttisinteger(s2v(ra))) { /* integer loop? */ | 1639 | if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ |
1667 | lua_Integer step = ivalue(s2v(ra + 2)); | 1640 | lua_Unsigned count = l_castS2U(ivalue(s2v(ra))); |
1668 | lua_Integer idx = intop(+, ivalue(s2v(ra)), step); /* new index */ | 1641 | if (count > 0) { /* still more iterations? */ |
1669 | lua_Integer limit = ivalue(s2v(ra + 1)); | 1642 | lua_Integer step = ivalue(s2v(ra + 2)); |
1670 | if ((0 < step) ? (idx <= limit) : (limit <= idx)) { | 1643 | lua_Integer idx = ivalue(s2v(ra + 3)); |
1644 | idx = intop(+, idx, step); /* add step to index */ | ||
1645 | chgivalue(s2v(ra), count - 1); /* update counter... */ | ||
1646 | setivalue(s2v(ra + 3), idx); /* ...and index */ | ||
1671 | pc -= GETARG_Bx(i); /* jump back */ | 1647 | pc -= GETARG_Bx(i); /* jump back */ |
1672 | chgivalue(s2v(ra), idx); /* update internal index... */ | ||
1673 | setivalue(s2v(ra + 3), idx); /* ...and external index */ | ||
1674 | } | 1648 | } |
1675 | } | 1649 | } |
1676 | else { /* floating loop */ | 1650 | else { /* floating loop */ |
1677 | lua_Number step = fltvalue(s2v(ra + 2)); | 1651 | lua_Number step = fltvalue(s2v(ra + 2)); |
1678 | lua_Number limit = fltvalue(s2v(ra + 1)); | 1652 | lua_Number limit = fltvalue(s2v(ra + 1)); |
1679 | lua_Number idx = fltvalue(s2v(ra)); | 1653 | lua_Number idx = fltvalue(s2v(ra + 3)); |
1680 | idx = luai_numadd(L, idx, step); /* inc. index */ | 1654 | idx = luai_numadd(L, idx, step); /* inc. index */ |
1681 | if (luai_numlt(0, step) ? luai_numle(idx, limit) | 1655 | if (luai_numlt(0, step) ? luai_numle(idx, limit) |
1682 | : luai_numle(limit, idx)) { | 1656 | : luai_numle(limit, idx)) { |
1657 | setfltvalue(s2v(ra + 3), idx); /* update index */ | ||
1683 | pc -= GETARG_Bx(i); /* jump back */ | 1658 | pc -= GETARG_Bx(i); /* jump back */ |
1684 | chgfltvalue(s2v(ra), idx); /* update internal index... */ | ||
1685 | setfltvalue(s2v(ra + 3), idx); /* ...and external index */ | ||
1686 | } | 1659 | } |
1687 | } | 1660 | } |
1688 | updatetrap(ci); | 1661 | updatetrap(ci); /* allows a signal to break the loop */ |
1689 | vmbreak; | 1662 | vmbreak; |
1690 | } | 1663 | } |
1691 | vmcase(OP_FORPREP) { | 1664 | vmcase(OP_FORPREP) { |
1692 | TValue *init = s2v(ra); | 1665 | TValue *pinit = s2v(ra); |
1693 | TValue *plimit = s2v(ra + 1); | 1666 | TValue *plimit = s2v(ra + 1); |
1694 | TValue *pstep = s2v(ra + 2); | 1667 | TValue *pstep = s2v(ra + 2); |
1695 | lua_Integer ilimit; | 1668 | lua_Integer ilimit; |
1696 | int stopnow; | 1669 | int stopnow; |
1697 | if (ttisinteger(init) && ttisinteger(pstep) && | 1670 | savestate(L, ci); /* in case of errors */ |
1671 | if (ttisinteger(pinit) && ttisinteger(pstep) && | ||
1698 | forlimit(plimit, &ilimit, ivalue(pstep), &stopnow)) { | 1672 | forlimit(plimit, &ilimit, ivalue(pstep), &stopnow)) { |
1699 | /* all values are integer */ | 1673 | /* integer loop */ |
1700 | lua_Integer initv = (stopnow ? 0 : ivalue(init)); | 1674 | lua_Integer init = ivalue(pinit); |
1701 | setivalue(plimit, ilimit); | 1675 | lua_Integer step = ivalue(pstep); |
1702 | setivalue(init, intop(-, initv, ivalue(pstep))); | 1676 | setivalue(s2v(ra + 3), init); /* control variable */ |
1677 | if (step == 0) | ||
1678 | luaG_runerror(L, "'for' step is zero"); | ||
1679 | else if (stopnow) | ||
1680 | pc += GETARG_Bx(i) + 1; /* skip the loop */ | ||
1681 | else if (step > 0) { /* ascending loop? */ | ||
1682 | if (init > ilimit) | ||
1683 | pc += GETARG_Bx(i) + 1; /* skip the loop */ | ||
1684 | else { | ||
1685 | lua_Unsigned count = l_castS2U(ilimit) - l_castS2U(init); | ||
1686 | if (step != 1) /* avoid division in the too common case */ | ||
1687 | count /= l_castS2U(step); | ||
1688 | setivalue(s2v(ra), count); | ||
1689 | } | ||
1690 | } | ||
1691 | else { /* descending loop */ | ||
1692 | if (init < ilimit) | ||
1693 | pc += GETARG_Bx(i) + 1; /* skip the loop */ | ||
1694 | else { | ||
1695 | lua_Unsigned count = l_castS2U(init) - l_castS2U(ilimit); | ||
1696 | count /= -l_castS2U(step); | ||
1697 | setivalue(s2v(ra), count); | ||
1698 | } | ||
1699 | } | ||
1703 | } | 1700 | } |
1704 | else { /* try making all values floats */ | 1701 | else { /* try making all values floats */ |
1705 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; | 1702 | lua_Number init; lua_Number flimit; lua_Number step; |
1706 | savestate(L, ci); /* in case of errors */ | 1703 | if (unlikely(!tonumber(plimit, &flimit))) |
1707 | if (unlikely(!tonumber(plimit, &nlimit))) | ||
1708 | luaG_forerror(L, plimit, "limit"); | 1704 | luaG_forerror(L, plimit, "limit"); |
1709 | setfltvalue(plimit, nlimit); | 1705 | setfltvalue(plimit, flimit); |
1710 | if (unlikely(!tonumber(pstep, &nstep))) | 1706 | if (unlikely(!tonumber(pstep, &step))) |
1711 | luaG_forerror(L, pstep, "step"); | 1707 | luaG_forerror(L, pstep, "step"); |
1712 | setfltvalue(pstep, nstep); | 1708 | setfltvalue(pstep, step); |
1713 | if (unlikely(!tonumber(init, &ninit))) | 1709 | if (unlikely(!tonumber(pinit, &init))) |
1714 | luaG_forerror(L, init, "initial value"); | 1710 | luaG_forerror(L, pinit, "initial value"); |
1715 | setfltvalue(init, luai_numsub(L, ninit, nstep)); | 1711 | if (step == 0) |
1712 | luaG_runerror(L, "'for' step is zero"); | ||
1713 | if (luai_numlt(0, step) ? luai_numlt(flimit, init) | ||
1714 | : luai_numlt(init, flimit)) | ||
1715 | pc += GETARG_Bx(i) + 1; /* skip the loop */ | ||
1716 | else | ||
1717 | setfltvalue(s2v(ra + 3), init); /* control variable */ | ||
1716 | } | 1718 | } |
1717 | pc += GETARG_Bx(i); | ||
1718 | vmbreak; | 1719 | vmbreak; |
1719 | } | 1720 | } |
1720 | vmcase(OP_TFORPREP) { | 1721 | vmcase(OP_TFORPREP) { |
diff --git a/manual/manual.of b/manual/manual.of index 8a8ebad5..b7ced443 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
@@ -594,7 +594,7 @@ controls how long the collector waits before starting a new cycle. | |||
594 | The collector starts a new cycle when the use of memory | 594 | The collector starts a new cycle when the use of memory |
595 | hits @M{n%} of the use after the previous collection. | 595 | hits @M{n%} of the use after the previous collection. |
596 | Larger values make the collector less aggressive. | 596 | Larger values make the collector less aggressive. |
597 | Values smaller than 100 mean the collector will not wait to | 597 | Values less than 100 mean the collector will not wait to |
598 | start a new cycle. | 598 | start a new cycle. |
599 | A value of 200 means that the collector waits for the total memory in use | 599 | A value of 200 means that the collector waits for the total memory in use |
600 | to double before starting a new cycle. | 600 | to double before starting a new cycle. |
@@ -608,7 +608,7 @@ how many elements it marks or sweeps for each | |||
608 | kilobyte of memory allocated. | 608 | kilobyte of memory allocated. |
609 | Larger values make the collector more aggressive but also increase | 609 | Larger values make the collector more aggressive but also increase |
610 | the size of each incremental step. | 610 | the size of each incremental step. |
611 | You should not use values smaller than 100, | 611 | You should not use values less than 100, |
612 | because they make the collector too slow and | 612 | because they make the collector too slow and |
613 | can result in the collector never finishing a cycle. | 613 | can result in the collector never finishing a cycle. |
614 | The default value is 100; the maximum value is 1000. | 614 | The default value is 100; the maximum value is 1000. |
@@ -1004,7 +1004,7 @@ the escape sequence @T{\u{@rep{XXX}}} | |||
1004 | (note the mandatory enclosing brackets), | 1004 | (note the mandatory enclosing brackets), |
1005 | where @rep{XXX} is a sequence of one or more hexadecimal digits | 1005 | where @rep{XXX} is a sequence of one or more hexadecimal digits |
1006 | representing the character code point. | 1006 | representing the character code point. |
1007 | This code point can be any value smaller than @M{2@sp{31}}. | 1007 | This code point can be any value less than @M{2@sp{31}}. |
1008 | (Lua uses the original UTF-8 specification here.) | 1008 | (Lua uses the original UTF-8 specification here.) |
1009 | 1009 | ||
1010 | Literal strings can also be defined using a long format | 1010 | Literal strings can also be defined using a long format |
@@ -1370,73 +1370,49 @@ because now @Rw{return} is the last statement in its (inner) block. | |||
1370 | The @Rw{for} statement has two forms: | 1370 | The @Rw{for} statement has two forms: |
1371 | one numerical and one generic. | 1371 | one numerical and one generic. |
1372 | 1372 | ||
1373 | @sect4{@title{The numerical @Rw{for} loop} | ||
1374 | |||
1373 | The numerical @Rw{for} loop repeats a block of code while a | 1375 | The numerical @Rw{for} loop repeats a block of code while a |
1374 | control variable runs through an arithmetic progression. | 1376 | control variable goes through an arithmetic progression. |
1375 | It has the following syntax: | 1377 | It has the following syntax: |
1376 | @Produc{ | 1378 | @Produc{ |
1377 | @producname{stat}@producbody{@Rw{for} @bnfNter{Name} @bnfter{=} | 1379 | @producname{stat}@producbody{@Rw{for} @bnfNter{Name} @bnfter{=} |
1378 | exp @bnfter{,} exp @bnfopt{@bnfter{,} exp} @Rw{do} block @Rw{end}} | 1380 | exp @bnfter{,} exp @bnfopt{@bnfter{,} exp} @Rw{do} block @Rw{end}} |
1379 | } | 1381 | } |
1380 | The @emph{block} is repeated for @emph{name} starting at the value of | 1382 | The given identifier (@bnfNter{Name}) defines the control variable, |
1381 | the first @emph{exp}, until it passes the second @emph{exp} by steps of the | 1383 | which is local to the loop body (@emph{block}). |
1382 | third @emph{exp}. | 1384 | |
1383 | More precisely, a @Rw{for} statement like | 1385 | The loop starts by evaluating once the three control expressions; |
1384 | @verbatim{ | 1386 | they must all result in numbers. |
1385 | for v = @rep{e1}, @rep{e2}, @rep{e3} do @rep{block} end | 1387 | Their values are called respectively |
1386 | } | 1388 | the @emph{initial value}, the @emph{limit}, and the @emph{step}. |
1387 | is equivalent to the code: | 1389 | If the step is absent, it defaults @N{to 1}. |
1388 | @verbatim{ | 1390 | Then the loop body is repeated with the value of the control variable |
1389 | do | 1391 | going through an arithmetic progression, |
1390 | local @rep{var}, @rep{limit}, @rep{step} = tonumber(@rep{e1}), tonumber(@rep{e2}), tonumber(@rep{e3}) | 1392 | starting at the initial value, |
1391 | if not (@rep{var} and @rep{limit} and @rep{step}) then error() end | 1393 | with a common difference given by the step, |
1392 | @rep{var} = @rep{var} - @rep{step} | 1394 | until that value passes the limit. |
1393 | while true do | 1395 | A negative step makes a decreasing sequence; |
1394 | @rep{var} = @rep{var} + @rep{step} | 1396 | a step equal to zero raises an error. |
1395 | if (@rep{step} >= 0 and @rep{var} > @rep{limit}) or (@rep{step} < 0 and @rep{var} < @rep{limit}) then | 1397 | If the initial value is already greater than the limit |
1396 | break | 1398 | (or less than, if the step is negative), the body is not executed. |
1397 | end | 1399 | |
1398 | local v = @rep{var} | 1400 | If both the initial value and the step are integers, |
1399 | @rep{block} | 1401 | the loop is done with integers; |
1400 | end | 1402 | in this case, the range of the control variable is limited |
1401 | end | 1403 | by the range of integers. |
1402 | } | 1404 | Otherwise, the loop is done with floats. |
1403 | 1405 | (Beware of floating-point accuracy in this case.) | |
1404 | Note the following: | 1406 | |
1405 | @itemize{ | 1407 | You should not change the value of the control variable |
1406 | 1408 | during the loop. | |
1407 | @item{ | ||
1408 | All three control expressions are evaluated only once, | ||
1409 | before the loop starts. | ||
1410 | They must all result in numbers. | ||
1411 | } | ||
1412 | |||
1413 | @item{ | ||
1414 | @T{@rep{var}}, @T{@rep{limit}}, and @T{@rep{step}} are invisible variables. | ||
1415 | The names shown here are for explanatory purposes only. | ||
1416 | } | ||
1417 | |||
1418 | @item{ | ||
1419 | If the third expression (the step) is absent, | ||
1420 | then a step @N{of 1} is used. | ||
1421 | } | ||
1422 | |||
1423 | @item{ | ||
1424 | You can use @Rw{break} and @Rw{goto} to exit a @Rw{for} loop. | ||
1425 | } | ||
1426 | |||
1427 | @item{ | ||
1428 | The loop variable @T{v} is local to the loop body. | ||
1429 | If you need its value after the loop, | 1409 | If you need its value after the loop, |
1430 | assign it to another variable before exiting the loop. | 1410 | assign it to another variable before exiting the loop. |
1431 | } | ||
1432 | 1411 | ||
1433 | @item{ | ||
1434 | The values in @rep{var}, @rep{limit}, and @rep{step} | ||
1435 | can be integers or floats. | ||
1436 | All operations on them respect the usual rules in Lua. | ||
1437 | } | 1412 | } |
1438 | 1413 | ||
1439 | } | 1414 | @sect4{@title{The generic @Rw{for} loop} |
1415 | |||
1440 | 1416 | ||
1441 | The generic @Rw{for} statement works over functions, | 1417 | The generic @Rw{for} statement works over functions, |
1442 | called @def{iterators}. | 1418 | called @def{iterators}. |
@@ -1499,6 +1475,8 @@ then assign them to other variables before breaking or exiting the loop. | |||
1499 | 1475 | ||
1500 | } | 1476 | } |
1501 | 1477 | ||
1478 | } | ||
1479 | |||
1502 | @sect3{funcstat| @title{Function Calls as Statements} | 1480 | @sect3{funcstat| @title{Function Calls as Statements} |
1503 | To allow possible side-effects, | 1481 | To allow possible side-effects, |
1504 | function calls can be executed as statements: | 1482 | function calls can be executed as statements: |
@@ -1819,7 +1797,7 @@ A comparison @T{a > b} is translated to @T{b < a} | |||
1819 | and @T{a >= b} is translated to @T{b <= a}. | 1797 | and @T{a >= b} is translated to @T{b <= a}. |
1820 | 1798 | ||
1821 | Following the @x{IEEE 754} standard, | 1799 | Following the @x{IEEE 754} standard, |
1822 | @x{NaN} is considered neither smaller than, | 1800 | @x{NaN} is considered neither less than, |
1823 | nor equal to, nor greater than any value (including itself). | 1801 | nor equal to, nor greater than any value (including itself). |
1824 | 1802 | ||
1825 | } | 1803 | } |
@@ -2171,7 +2149,7 @@ then the function returns with no results. | |||
2171 | @index{multiple return} | 2149 | @index{multiple return} |
2172 | There is a system-dependent limit on the number of values | 2150 | There is a system-dependent limit on the number of values |
2173 | that a function may return. | 2151 | that a function may return. |
2174 | This limit is guaranteed to be larger than 1000. | 2152 | This limit is guaranteed to be greater than 1000. |
2175 | 2153 | ||
2176 | The @emphx{colon} syntax | 2154 | The @emphx{colon} syntax |
2177 | is used for defining @def{methods}, | 2155 | is used for defining @def{methods}, |
@@ -2367,7 +2345,7 @@ but it also can be any positive index after the stack top | |||
2367 | within the space allocated for the stack, | 2345 | within the space allocated for the stack, |
2368 | that is, indices up to the stack size. | 2346 | that is, indices up to the stack size. |
2369 | (Note that 0 is never an acceptable index.) | 2347 | (Note that 0 is never an acceptable index.) |
2370 | Indices to upvalues @see{c-closure} larger than the real number | 2348 | Indices to upvalues @see{c-closure} greater than the real number |
2371 | of upvalues in the current @N{C function} are also acceptable (but invalid). | 2349 | of upvalues in the current @N{C function} are also acceptable (but invalid). |
2372 | Except when noted otherwise, | 2350 | Except when noted otherwise, |
2373 | functions in the API work with acceptable indices. | 2351 | functions in the API work with acceptable indices. |
@@ -2879,7 +2857,7 @@ Ensures that the stack has space for at least @id{n} extra slots | |||
2879 | (that is, that you can safely push up to @id{n} values into it). | 2857 | (that is, that you can safely push up to @id{n} values into it). |
2880 | It returns false if it cannot fulfill the request, | 2858 | It returns false if it cannot fulfill the request, |
2881 | either because it would cause the stack | 2859 | either because it would cause the stack |
2882 | to be larger than a fixed maximum size | 2860 | to be greater than a fixed maximum size |
2883 | (typically at least several thousand elements) or | 2861 | (typically at least several thousand elements) or |
2884 | because it cannot allocate memory for the extra space. | 2862 | because it cannot allocate memory for the extra space. |
2885 | This function never shrinks the stack; | 2863 | This function never shrinks the stack; |
@@ -4053,7 +4031,7 @@ for the @Q{newindex} event @see{metatable}. | |||
4053 | 4031 | ||
4054 | Accepts any index, @N{or 0}, | 4032 | Accepts any index, @N{or 0}, |
4055 | and sets the stack top to this index. | 4033 | and sets the stack top to this index. |
4056 | If the new top is larger than the old one, | 4034 | If the new top is greater than the old one, |
4057 | then the new elements are filled with @nil. | 4035 | then the new elements are filled with @nil. |
4058 | If @id{index} @N{is 0}, then all stack elements are removed. | 4036 | If @id{index} @N{is 0}, then all stack elements are removed. |
4059 | 4037 | ||
@@ -5056,7 +5034,7 @@ size @id{sz} with a call @T{luaL_buffinitsize(L, &b, sz)}.} | |||
5056 | @item{ | 5034 | @item{ |
5057 | Finish by calling @T{luaL_pushresultsize(&b, sz)}, | 5035 | Finish by calling @T{luaL_pushresultsize(&b, sz)}, |
5058 | where @id{sz} is the total size of the resulting string | 5036 | where @id{sz} is the total size of the resulting string |
5059 | copied into that space (which may be smaller than or | 5037 | copied into that space (which may be less than or |
5060 | equal to the preallocated size). | 5038 | equal to the preallocated size). |
5061 | } | 5039 | } |
5062 | 5040 | ||
@@ -7336,7 +7314,7 @@ Functions that interpret byte sequences only accept | |||
7336 | valid sequences (well formed and not overlong). | 7314 | valid sequences (well formed and not overlong). |
7337 | By default, they only accept byte sequences | 7315 | By default, they only accept byte sequences |
7338 | that result in valid Unicode code points, | 7316 | that result in valid Unicode code points, |
7339 | rejecting values larger than @T{10FFFF} and surrogates. | 7317 | rejecting values greater than @T{10FFFF} and surrogates. |
7340 | A boolean argument @id{nonstrict}, when available, | 7318 | A boolean argument @id{nonstrict}, when available, |
7341 | lifts these checks, | 7319 | lifts these checks, |
7342 | so that all values up to @T{0x7FFFFFFF} are accepted. | 7320 | so that all values up to @T{0x7FFFFFFF} are accepted. |
@@ -7572,7 +7550,7 @@ returns the arc tangent of @id{y}. | |||
7572 | 7550 | ||
7573 | @LibEntry{math.ceil (x)| | 7551 | @LibEntry{math.ceil (x)| |
7574 | 7552 | ||
7575 | Returns the smallest integral value larger than or equal to @id{x}. | 7553 | Returns the smallest integral value greater than or equal to @id{x}. |
7576 | 7554 | ||
7577 | } | 7555 | } |
7578 | 7556 | ||
@@ -7597,7 +7575,7 @@ Returns the value @M{e@sp{x}} | |||
7597 | 7575 | ||
7598 | @LibEntry{math.floor (x)| | 7576 | @LibEntry{math.floor (x)| |
7599 | 7577 | ||
7600 | Returns the largest integral value smaller than or equal to @id{x}. | 7578 | Returns the largest integral value less than or equal to @id{x}. |
7601 | 7579 | ||
7602 | } | 7580 | } |
7603 | 7581 | ||
@@ -7611,7 +7589,7 @@ that rounds the quotient towards zero. (integer/float) | |||
7611 | @LibEntry{math.huge| | 7589 | @LibEntry{math.huge| |
7612 | 7590 | ||
7613 | The float value @idx{HUGE_VAL}, | 7591 | The float value @idx{HUGE_VAL}, |
7614 | a value larger than any other numeric value. | 7592 | a value greater than any other numeric value. |
7615 | 7593 | ||
7616 | } | 7594 | } |
7617 | 7595 | ||
@@ -8352,7 +8330,7 @@ of the given thread: | |||
8352 | @N{level 1} is the function that called @id{getinfo} | 8330 | @N{level 1} is the function that called @id{getinfo} |
8353 | (except for tail calls, which do not count on the stack); | 8331 | (except for tail calls, which do not count on the stack); |
8354 | and so on. | 8332 | and so on. |
8355 | If @id{f} is a number larger than the number of active functions, | 8333 | If @id{f} is a number greater than the number of active functions, |
8356 | then @id{getinfo} returns @nil. | 8334 | then @id{getinfo} returns @nil. |
8357 | 8335 | ||
8358 | The returned table can contain all the fields returned by @Lid{lua_getinfo}, | 8336 | The returned table can contain all the fields returned by @Lid{lua_getinfo}, |
@@ -8746,6 +8724,12 @@ When needed, this metamethod must be explicitly defined. | |||
8746 | } | 8724 | } |
8747 | 8725 | ||
8748 | @item{ | 8726 | @item{ |
8727 | The semantics of the numerical @Rw{for} loop | ||
8728 | over integers changed in some details. | ||
8729 | In particular, the control variable never wraps around. | ||
8730 | } | ||
8731 | |||
8732 | @item{ | ||
8749 | When a coroutine finishes with an error, | 8733 | When a coroutine finishes with an error, |
8750 | its stack is unwound (to run any pending closing methods). | 8734 | its stack is unwound (to run any pending closing methods). |
8751 | } | 8735 | } |
diff --git a/testes/code.lua b/testes/code.lua index 834ff5e2..128ca2cb 100644 --- a/testes/code.lua +++ b/testes/code.lua | |||
@@ -303,9 +303,9 @@ check(function (x) return x & 2.0 end, 'LOADF', 'BAND', 'RETURN1') | |||
303 | 303 | ||
304 | -- basic 'for' loops | 304 | -- basic 'for' loops |
305 | check(function () for i = -10, 10.5 do end end, | 305 | check(function () for i = -10, 10.5 do end end, |
306 | 'LOADI', 'LOADK', 'LOADI', 'FORPREP1', 'FORLOOP1', 'RETURN0') | 306 | 'LOADI', 'LOADK', 'LOADI', 'FORPREP', 'FORLOOP', 'RETURN0') |
307 | check(function () for i = 0xfffffff, 10.0, 1 do end end, | 307 | check(function () for i = 0xfffffff, 10.0, 1 do end end, |
308 | 'LOADK', 'LOADF', 'LOADI', 'FORPREP1', 'FORLOOP1', 'RETURN0') | 308 | 'LOADK', 'LOADF', 'LOADI', 'FORPREP', 'FORLOOP', 'RETURN0') |
309 | 309 | ||
310 | -- bug in constant folding for 5.1 | 310 | -- bug in constant folding for 5.1 |
311 | check(function () return -nil end, 'LOADNIL', 'UNM', 'RETURN1') | 311 | check(function () return -nil end, 'LOADNIL', 'UNM', 'RETURN1') |
diff --git a/testes/db.lua b/testes/db.lua index 976962b0..0858dd20 100644 --- a/testes/db.lua +++ b/testes/db.lua | |||
@@ -162,7 +162,7 @@ test([[for i,v in pairs{'a','b'} do | |||
162 | end | 162 | end |
163 | ]], {1,2,1,2,1,3}) | 163 | ]], {1,2,1,2,1,3}) |
164 | 164 | ||
165 | test([[for i=1,4 do a=1 end]], {1,1,1,1,1}) | 165 | test([[for i=1,4 do a=1 end]], {1,1,1,1}, true) |
166 | 166 | ||
167 | 167 | ||
168 | do -- testing line info/trace with large gaps in source | 168 | do -- testing line info/trace with large gaps in source |
diff --git a/testes/nextvar.lua b/testes/nextvar.lua index d2306ed1..e769ccdd 100644 --- a/testes/nextvar.lua +++ b/testes/nextvar.lua | |||
@@ -76,7 +76,7 @@ while a < lim do | |||
76 | a = math.ceil(a*1.3) | 76 | a = math.ceil(a*1.3) |
77 | end | 77 | end |
78 | 78 | ||
79 | 79 | ||
80 | local function check (t, na, nh) | 80 | local function check (t, na, nh) |
81 | local a, h = T.querytab(t) | 81 | local a, h = T.querytab(t) |
82 | if a ~= na or h ~= nh then | 82 | if a ~= na or h ~= nh then |
@@ -100,7 +100,7 @@ local s = 'return {' | |||
100 | for i=1,lim do | 100 | for i=1,lim do |
101 | s = s..i..',' | 101 | s = s..i..',' |
102 | local s = s | 102 | local s = s |
103 | for k=0,lim do | 103 | for k=0,lim do |
104 | local t = load(s..'}', '')() | 104 | local t = load(s..'}', '')() |
105 | assert(#t == i) | 105 | assert(#t == i) |
106 | check(t, fb(i), mp2(k)) | 106 | check(t, fb(i), mp2(k)) |
@@ -279,7 +279,7 @@ do -- clear global table | |||
279 | end | 279 | end |
280 | 280 | ||
281 | 281 | ||
282 | -- | 282 | -- |
283 | 283 | ||
284 | local function checknext (a) | 284 | local function checknext (a) |
285 | local b = {} | 285 | local b = {} |
@@ -500,7 +500,7 @@ else --[ | |||
500 | mt.__newindex = nil | 500 | mt.__newindex = nil |
501 | mt.__len = nil | 501 | mt.__len = nil |
502 | local tab2 = {} | 502 | local tab2 = {} |
503 | local u2 = T.newuserdata(0) | 503 | local u2 = T.newuserdata(0) |
504 | debug.setmetatable(u2, {__newindex = function (_, k, v) tab2[k] = v end}) | 504 | debug.setmetatable(u2, {__newindex = function (_, k, v) tab2[k] = v end}) |
505 | table.move(u, 1, 4, 1, u2) | 505 | table.move(u, 1, 4, 1, u2) |
506 | assert(#tab2 == 4 and tab2[1] == tab[1] and tab2[4] == tab[4]) | 506 | assert(#tab2 == 4 and tab2[1] == tab[1] and tab2[4] == tab[4]) |
@@ -601,6 +601,69 @@ do -- checking types | |||
601 | 601 | ||
602 | end | 602 | end |
603 | 603 | ||
604 | |||
605 | do -- testing other strange cases for numeric 'for' | ||
606 | |||
607 | local function checkfor (from, to, step, t) | ||
608 | local c = 0 | ||
609 | for i = from, to, step do | ||
610 | c = c + 1 | ||
611 | assert(i == t[c]) | ||
612 | end | ||
613 | assert(c == #t) | ||
614 | end | ||
615 | |||
616 | local maxi = math.maxinteger | ||
617 | local mini = math.mininteger | ||
618 | |||
619 | checkfor(mini, maxi, maxi, {mini, -1, maxi - 1}) | ||
620 | |||
621 | checkfor(mini, math.huge, maxi, {mini, -1, maxi - 1}) | ||
622 | |||
623 | checkfor(maxi, mini, mini, {maxi, -1}) | ||
624 | |||
625 | checkfor(maxi, mini, -maxi, {maxi, 0, -maxi}) | ||
626 | |||
627 | checkfor(maxi, -math.huge, mini, {maxi, -1}) | ||
628 | |||
629 | checkfor(maxi, mini, 1, {}) | ||
630 | checkfor(mini, maxi, -1, {}) | ||
631 | |||
632 | checkfor(maxi - 6, maxi, 3, {maxi - 6, maxi - 3, maxi}) | ||
633 | checkfor(mini + 4, mini, -2, {mini + 4, mini + 2, mini}) | ||
634 | |||
635 | local step = maxi // 10 | ||
636 | local c = mini | ||
637 | for i = mini, maxi, step do | ||
638 | assert(i == c) | ||
639 | c = c + step | ||
640 | end | ||
641 | |||
642 | c = maxi | ||
643 | for i = maxi, mini, -step do | ||
644 | assert(i == c) | ||
645 | c = c - step | ||
646 | end | ||
647 | |||
648 | checkfor(maxi, maxi, maxi, {maxi}) | ||
649 | checkfor(maxi, maxi, mini, {maxi}) | ||
650 | checkfor(mini, mini, maxi, {mini}) | ||
651 | checkfor(mini, mini, mini, {mini}) | ||
652 | end | ||
653 | |||
654 | |||
655 | checkerror("'for' step is zero", function () | ||
656 | for i = 1, 10, 0 do end | ||
657 | end) | ||
658 | |||
659 | checkerror("'for' step is zero", function () | ||
660 | for i = 1, -10, 0 do end | ||
661 | end) | ||
662 | |||
663 | checkerror("'for' step is zero", function () | ||
664 | for i = 1.0, -10, 0.0 do end | ||
665 | end) | ||
666 | |||
604 | collectgarbage() | 667 | collectgarbage() |
605 | 668 | ||
606 | 669 | ||
@@ -657,7 +720,7 @@ a[3] = 30 | |||
657 | -- testing ipairs with metamethods | 720 | -- testing ipairs with metamethods |
658 | a = {n=10} | 721 | a = {n=10} |
659 | setmetatable(a, { __index = function (t,k) | 722 | setmetatable(a, { __index = function (t,k) |
660 | if k <= t.n then return k * 10 end | 723 | if k <= t.n then return k * 10 end |
661 | end}) | 724 | end}) |
662 | i = 0 | 725 | i = 0 |
663 | for k,v in ipairs(a) do | 726 | for k,v in ipairs(a) do |