/* ** Try to convert a 'for' limit to an integer, preserving the ** semantics of the loop. ** (The following explanation assumes a non-negative step; it is valid ** for negative steps mutatis mutandis.) ** If the limit can be converted to an integer, rounding down, that is ** it. ** Otherwise, check whether the limit can be converted to a number. If ** the number is too large, it is OK to set the limit as LUA_MAXINTEGER, ** which means no limit. If the number is too negative, the loop ** should not run, because any initial integer value is larger than the ** limit. So, it sets the limit to LUA_MININTEGER. 'stopnow' corrects ** the extreme case when the initial value is LUA_MININTEGER, in which ** case the LUA_MININTEGER limit would still run the loop once. */ static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, int *stopnow) { *stopnow = 0; /* usually, let loops run */ if (!tointeger_aux(obj, p, (step < 0 ? 1 : -1))) { /* not fit in integer? */ lua_Number n; /* try to convert to float */ if (!tonumber(obj, &n)) /* cannot convert to float? */ return 0; /* not a number */ if (n > 0) { /* if true, float is larger than max integer */ *p = LUA_MAXINTEGER; if (step < 0) *stopnow = 1; } else { /* float is smaller than min integer */ *p = LUA_MININTEGER; if (step >= 0) *stopnow = 1; } } return 1; }
/* ** try to convert a value to an integer, rounding according to 'mode': ** mode == 0: accepts only integral values ** mode == 1: takes the floor of the number ** mode == 2: takes the ceil of the number */ static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) { TValue v; again: #ifndef _KERNEL if (ttisfloat(obj)) { lua_Number n = fltvalue(obj); lua_Number f = l_floor(n); if (n != f) { /* not an integral value? */ if (mode == 0) return 0; /* fails if mode demands integral value */ else if (mode > 1) /* needs ceil? */ f += 1; /* convert floor to ceil (remember: n != f) */ } return lua_numbertointeger(f, p); } else if (ttisinteger(obj)) { #else /* _KERNEL */ if (ttisinteger(obj)) { UNUSED(mode); #endif *p = ivalue(obj); return 1; } else if (cvt2num(obj) && luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) { obj = &v; goto again; /* convert result from 'luaO_str2num' to an integer */ } return 0; /* conversion failed */ } /* ** try to convert a value to an integer */ int luaV_tointeger_ (const TValue *obj, lua_Integer *p) { return tointeger_aux(obj, p, LUA_FLOORN2I); } #ifndef _KERNEL /* ** Try to convert a 'for' limit to an integer, preserving the ** semantics of the loop. ** (The following explanation assumes a non-negative step; it is valid ** for negative steps mutatis mutandis.) ** If the limit can be converted to an integer, rounding down, that is ** it. ** Otherwise, check whether the limit can be converted to a number. If ** the number is too large, it is OK to set the limit as LUA_MAXINTEGER, ** which means no limit. If the number is too negative, the loop ** should not run, because any initial integer value is larger than the ** limit. So, it sets the limit to LUA_MININTEGER. 'stopnow' corrects ** the extreme case when the initial value is LUA_MININTEGER, in which ** case the LUA_MININTEGER limit would still run the loop once. */ static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, int *stopnow) { *stopnow = 0; /* usually, let loops run */ if (!tointeger_aux(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */ lua_Number n; /* try to convert to float */ if (!tonumber(obj, &n)) /* cannot convert to float? */ return 0; /* not a number */ if (n > 0) { /* if true, float is larger than max integer */ *p = LUA_MAXINTEGER; if (step < 0) *stopnow = 1; } else { /* float is smaller than min integer */ *p = LUA_MININTEGER; if (step >= 0) *stopnow = 1; } } return 1; }
/* ** try to convert a value to an integer */ int luaV_tointeger_ (const TValue *obj, lua_Integer *p) { return tointeger_aux(obj, p, 0); }
/* ** try to convert a value to an integer */ int luaV_tointeger_ (const TValue *obj, lua_Integer *p) { return tointeger_aux(obj, p, LUA_FLOORN2I); }