new interface for 'tonumber'

This commit is contained in:
Roberto Ierusalimschy
2013-04-26 13:03:50 -03:00
parent d4e6b75098
commit 4abe99dc34
4 changed files with 34 additions and 39 deletions

18
lapi.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lapi.c,v 2.174 2013/04/25 13:52:49 roberto Exp roberto $ ** $Id: lapi.c,v 2.175 2013/04/26 15:39:25 roberto Exp roberto $
** Lua API ** Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -271,7 +271,7 @@ LUA_API int lua_isinteger (lua_State *L, int idx) {
LUA_API int lua_isnumber (lua_State *L, int idx) { LUA_API int lua_isnumber (lua_State *L, int idx) {
TValue n; lua_Number n;
const TValue *o = index2addr(L, idx); const TValue *o = index2addr(L, idx);
return tonumber(o, &n); return tonumber(o, &n);
} }
@@ -339,11 +339,11 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) { LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
TValue n; lua_Number n;
const TValue *o = index2addr(L, idx); const TValue *o = index2addr(L, idx);
if (tonumber(o, &n)) { if (tonumber(o, &n)) {
if (isnum) *isnum = 1; if (isnum) *isnum = 1;
return nvalue(o); return n;
} }
else { else {
if (isnum) *isnum = 0; if (isnum) *isnum = 0;
@@ -353,7 +353,7 @@ LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) { LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
TValue n; lua_Number n;
const TValue *o = index2addr(L, idx); const TValue *o = index2addr(L, idx);
if (ttisinteger(o)) { if (ttisinteger(o)) {
if (isnum) *isnum = 1; if (isnum) *isnum = 1;
@@ -361,8 +361,7 @@ LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
} }
else if (tonumber(o, &n)) { else if (tonumber(o, &n)) {
lua_Integer res; lua_Integer res;
lua_Number num = nvalue(o); lua_number2integer(res, n);
lua_number2integer(res, num);
if (isnum) *isnum = 1; if (isnum) *isnum = 1;
return res; return res;
} }
@@ -374,12 +373,11 @@ LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) { LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) {
TValue n; lua_Number n;
const TValue *o = index2addr(L, idx); const TValue *o = index2addr(L, idx);
if (tonumber(o, &n)) { if (tonumber(o, &n)) {
lua_Unsigned res; lua_Unsigned res;
lua_Number num = nvalue(o); lua_number2unsigned(res, n);
lua_number2unsigned(res, num);
if (isnum) *isnum = 1; if (isnum) *isnum = 1;
return res; return res;
} }

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: ldebug.c,v 2.91 2013/04/25 15:59:42 roberto Exp roberto $ ** $Id: ldebug.c,v 2.92 2013/04/26 13:07:53 roberto Exp roberto $
** Debug Interface ** Debug Interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -525,8 +525,8 @@ l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
TValue temp; lua_Number temp;
if (luaV_tonumber(p1, &temp) == NULL) if (!tonumber(p1, &temp))
p2 = p1; /* first operand is wrong */ p2 = p1; /* first operand is wrong */
luaG_typeerror(L, p2, "perform arithmetic on"); luaG_typeerror(L, p2, "perform arithmetic on");
} }

42
lvm.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 2.162 2013/04/25 19:50:02 roberto Exp roberto $ ** $Id: lvm.c,v 2.163 2013/04/26 13:07:53 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -32,19 +32,14 @@
#define MAXTAGLOOP 100 #define MAXTAGLOOP 100
const TValue *luaV_tonumber (const TValue *obj, TValue *n) { int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
lua_Number num; lua_assert(!ttisfloat(obj));
if (ttisfloat(obj)) return obj;
if (ttisinteger(obj)) { if (ttisinteger(obj)) {
setnvalue(n, cast_num(ivalue(obj))); *n = cast_num(ivalue(obj));
return n; return 1;
}
if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) {
setnvalue(n, num);
return n;
} }
else else
return NULL; return (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, n));
} }
@@ -337,11 +332,9 @@ lua_Integer luaV_pow (lua_Integer x, lua_Integer y) {
void luaV_arith (lua_State *L, StkId ra, const TValue *rb, void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
const TValue *rc, TMS op) { const TValue *rc, TMS op) {
TValue tempb, tempc; lua_Number b, c;
const TValue *b, *c; if (tonumber(rb, &b) && tonumber(rc, &c)) {
if ((b = luaV_tonumber(rb, &tempb)) != NULL && lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, b, c);
(c = luaV_tonumber(rc, &tempc)) != NULL) {
lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c));
setnvalue(ra, res); setnvalue(ra, res);
} }
else if (!luaT_callbinTM(L, rb, rc, ra, op)) else if (!luaT_callbinTM(L, rb, rc, ra, op))
@@ -841,20 +834,23 @@ void luaV_execute (lua_State *L) {
} }
) )
vmcase(OP_FORPREP, vmcase(OP_FORPREP,
const TValue *init = ra; TValue *init = ra;
const TValue *plimit = ra+1; TValue *plimit = ra + 1;
const TValue *pstep = ra+2; TValue *pstep = ra + 2;
if (ttisinteger(ra) && ttisinteger(ra + 1) && ttisinteger(ra + 2)) { if (ttisinteger(ra) && ttisinteger(ra + 1) && ttisinteger(ra + 2)) {
setivalue(ra, ivalue(ra) - ivalue(pstep)); setivalue(ra, ivalue(ra) - ivalue(pstep));
} }
else { /* try with floats */ else { /* try with floats */
if (!tonumber(init, ra)) lua_Number ninit; lua_Number nlimit; lua_Number nstep;
if (!tonumber(init, &ninit))
luaG_runerror(L, LUA_QL("for") " initial value must be a number"); luaG_runerror(L, LUA_QL("for") " initial value must be a number");
else if (!tonumber(plimit, ra+1)) if (!tonumber(plimit, &nlimit))
luaG_runerror(L, LUA_QL("for") " limit must be a number"); luaG_runerror(L, LUA_QL("for") " limit must be a number");
else if (!tonumber(pstep, ra+2)) setnvalue(plimit, nlimit);
if (!tonumber(pstep, &nstep))
luaG_runerror(L, LUA_QL("for") " step must be a number"); luaG_runerror(L, LUA_QL("for") " step must be a number");
setnvalue(ra, luai_numsub(L, fltvalue(ra), fltvalue(pstep))); setnvalue(pstep, nstep);
setnvalue(ra, luai_numsub(L, ninit, nstep));
} }
ci->u.l.savedpc += GETARG_sBx(i); ci->u.l.savedpc += GETARG_sBx(i);
) )

7
lvm.h
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lvm.h,v 2.19 2013/04/15 15:44:46 roberto Exp roberto $ ** $Id: lvm.h,v 2.20 2013/04/25 19:12:41 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -15,7 +15,8 @@
#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o))) #define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o)))
#define tonumber(o,n) (ttisfloat(o) || (((o) = luaV_tonumber(o,n)) != NULL)) #define tonumber(o,n) \
(ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
#define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2)
@@ -24,7 +25,7 @@
LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
StkId val); StkId val);