diff --git a/ldebug.c b/ldebug.c index 3590010c..ee1b87d9 100644 --- a/ldebug.c +++ b/ldebug.c @@ -696,6 +696,12 @@ l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { } +l_noret luaG_forerror (lua_State *L, const TValue *o, const char *what) { + luaG_runerror(L, "bad 'for' %s (number expected, got %s)", + what, luaT_objtypename(L, o)); +} + + l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { if (ttisstring(p1) || cvt2str(p1)) p1 = p2; luaG_typeerror(L, p1, "concatenate"); diff --git a/ldebug.h b/ldebug.h index 31ecc2f6..f080711d 100644 --- a/ldebug.h +++ b/ldebug.h @@ -24,6 +24,8 @@ LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *opname); +LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, + const char *what); LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2); LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, diff --git a/lvm.c b/lvm.c index 35a58089..aad965d6 100644 --- a/lvm.c +++ b/lvm.c @@ -1681,7 +1681,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { int stopnow; if (unlikely(!forlimit(plimit, &ilimit, 1, &stopnow))) { savestate(L, ci); /* for the error message */ - luaG_runerror(L, "'for' limit must be a number"); + luaG_forerror(L, plimit, "limit"); } initv = (stopnow ? 0 : ivalue(init)); setivalue(plimit, ilimit); @@ -1732,13 +1732,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { lua_Number ninit; lua_Number nlimit; lua_Number nstep; savestate(L, ci); /* in case of errors */ if (unlikely(!tonumber(plimit, &nlimit))) - luaG_runerror(L, "'for' limit must be a number"); + luaG_forerror(L, plimit, "limit"); setfltvalue(plimit, nlimit); if (unlikely(!tonumber(pstep, &nstep))) - luaG_runerror(L, "'for' step must be a number"); + luaG_forerror(L, pstep, "step"); setfltvalue(pstep, nstep); if (unlikely(!tonumber(init, &ninit))) - luaG_runerror(L, "'for' initial value must be a number"); + luaG_forerror(L, init, "initial value"); setfltvalue(init, luai_numsub(L, ninit, nstep)); } pc += GETARG_Bx(i); diff --git a/testes/errors.lua b/testes/errors.lua index 142e8b33..74975e31 100644 --- a/testes/errors.lua +++ b/testes/errors.lua @@ -154,6 +154,16 @@ checkmessage("a = 24 // 0", "divide by zero") checkmessage("a = 1 % 0", "'n%0'") +-- numeric for loops +checkmessage("for i = {}, 10 do end", "table") +checkmessage("for i = io.stdin, 10 do end", "FILE") +checkmessage("for i = {}, 10 do end", "initial value") +checkmessage("for i = 1, 'x', 10 do end", "string") +checkmessage("for i = 1, {}, 10 do end", "limit") +checkmessage("for i = 1, {} do end", "limit") +checkmessage("for i = 1, 10, print do end", "step") +checkmessage("for i = 1, 10, print do end", "function") + -- passing light userdata instead of full userdata _G.D = debug checkmessage([[