Better error messages for invalid operands in numeric 'for'
"Better" and similar to error messages for invalid function arguments.
*old message: 'for' limit must be a number
*new message: bad 'for' limit (number expected, got table)
diff --git a/ldebug.c b/ldebug.c
index 3590010..ee1b87d 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -696,6 +696,12 @@
}
+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 31ecc2f..f080711 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 35a5808..aad965d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1681,7 +1681,7 @@
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 @@
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 142e8b3..74975e3 100644
--- a/testes/errors.lua
+++ b/testes/errors.lua
@@ -154,6 +154,16 @@
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([[