diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-05-20 13:22:55 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-05-20 13:22:55 -0300 |
commit | 0ec12c1bd1ff5f42450703bdbd48f29a2d5e78f8 (patch) | |
tree | 2f0d26c5bb3729a67e06bc86c03d30ed4ffba08f | |
parent | a71c0ab8613bb8f14c91f9c3fc05e68c9a982206 (diff) | |
download | lua-0ec12c1bd1ff5f42450703bdbd48f29a2d5e78f8.tar.gz lua-0ec12c1bd1ff5f42450703bdbd48f29a2d5e78f8.tar.bz2 lua-0ec12c1bd1ff5f42450703bdbd48f29a2d5e78f8.zip |
new semantics for numerical order (following math regardless
representation)
-rw-r--r-- | lvm.c | 118 |
1 files changed, 90 insertions, 28 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.239 2015/04/10 17:56:25 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.240 2015/04/29 18:27:16 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -35,22 +35,6 @@ | |||
35 | #define MAXTAGLOOP 2000 | 35 | #define MAXTAGLOOP 2000 |
36 | 36 | ||
37 | 37 | ||
38 | /* | ||
39 | ** Similar to 'tonumber', but does not attempt to convert strings and | ||
40 | ** ensure correct precision (no extra bits). Used in comparisons. | ||
41 | */ | ||
42 | static int tofloat (const TValue *obj, lua_Number *n) { | ||
43 | if (ttisfloat(obj)) *n = fltvalue(obj); | ||
44 | else if (ttisinteger(obj)) { | ||
45 | volatile lua_Number x = cast_num(ivalue(obj)); /* avoid extra precision */ | ||
46 | *n = x; | ||
47 | } | ||
48 | else { | ||
49 | *n = 0; /* to avoid warnings */ | ||
50 | return 0; | ||
51 | } | ||
52 | return 1; | ||
53 | } | ||
54 | 38 | ||
55 | 39 | ||
56 | /* | 40 | /* |
@@ -244,15 +228,96 @@ static int l_strcmp (const TString *ls, const TString *rs) { | |||
244 | 228 | ||
245 | 229 | ||
246 | /* | 230 | /* |
231 | ** Check whether integer 'i' is less than float 'f'. 'neg' true means | ||
232 | ** result will be later negated: NaN still must result in false after | ||
233 | ** inversion. The comparison is based on the equivalence: | ||
234 | ** i < f <--> i < ceil(f) | ||
235 | ** When 'f' is non-positive, 'ceil' is not necessary, because the | ||
236 | ** standard C truncation (when converting a float to an integer) does | ||
237 | ** the job. | ||
238 | ** | ||
239 | */ | ||
240 | static int LTintfloat (lua_Integer i, lua_Number f, int neg) { | ||
241 | if (f > 0) { | ||
242 | f = l_mathop(ceil)(f); | ||
243 | if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */ | ||
244 | return 1; /* f >= maxint + 1; larger than all integers */ | ||
245 | else { /* 0 < f < (maxint + 1) */ | ||
246 | /* as f now has integral value, f <= maxint; cast is safe */ | ||
247 | return (i < cast(lua_Integer, f)); | ||
248 | } | ||
249 | } | ||
250 | else if (f > cast_num(LUA_MININTEGER)) { /* minint < f <= 0? */ | ||
251 | return (i < cast(lua_Integer, f)); /* cast computes 'ceil' */ | ||
252 | } | ||
253 | else if (luai_numisnan(f)) | ||
254 | return neg; /* i < NaN: final result must be false */ | ||
255 | else /* f <= minint */ | ||
256 | return 0; /* 'f' cannot be larger than any int */ | ||
257 | } | ||
258 | |||
259 | |||
260 | /* | ||
261 | ** Check whether integer 'i' is less than or equal to float 'f'. | ||
262 | ** 'neg' is like in previous function. The comparison is based on the | ||
263 | ** equivalence: | ||
264 | ** i <= f <--> i <= floor(f) | ||
265 | ** When f is non-negative, 'floor' is not necessary (C truncation does | ||
266 | ** the job). | ||
267 | */ | ||
268 | static int LEintfloat (lua_Integer i, lua_Number f, int neg) { | ||
269 | if (f >= 0) { | ||
270 | if (f >= -cast_num(LUA_MININTEGER)) /* f >= (maxint + 1)? */ | ||
271 | return 1; /* 'f' larger than all integers */ | ||
272 | else { /* 0 <= f < (maxint + 1) */ | ||
273 | /* truncation ensures that resulting value is <= maxint */ | ||
274 | return (i <= cast(lua_Integer, f)); | ||
275 | } | ||
276 | } | ||
277 | else if (f >= cast_num(LUA_MININTEGER)) { /* minint <= f < 0? */ | ||
278 | /* f >= minint --> floor(f) >= minint */ | ||
279 | return (i <= cast(lua_Integer, l_floor(f))); | ||
280 | } | ||
281 | else if (luai_numisnan(f)) | ||
282 | return neg; /* i <= NaN: final result must be false */ | ||
283 | else /* f < minint */ | ||
284 | return 0; /* 'f' is smaller than any int */ | ||
285 | } | ||
286 | |||
287 | |||
288 | /* | ||
289 | ** Return 'l < r', for numbers. 'neg' means result will be negated | ||
290 | ** (that is, comparison is based on r <= l <--> not (l < r)). | ||
291 | ** In that case, comparisons with NaN must result in false after | ||
292 | ** being negated (so negate again the comparison). | ||
293 | */ | ||
294 | static int LTnum (const TValue *l, const TValue *r, int neg) { | ||
295 | if (ttisinteger(l)) { | ||
296 | lua_Integer li = ivalue(l); | ||
297 | if (ttisinteger(r)) | ||
298 | return li < ivalue(r); /* both are integers */ | ||
299 | else /* 'l' is int and 'r' is float */ | ||
300 | return LTintfloat(li, fltvalue(r), neg); /* l < r ? */ | ||
301 | } | ||
302 | else { | ||
303 | lua_Number lf = fltvalue(l); /* 'l' must be float */ | ||
304 | if (ttisfloat(r)) { /* both are float */ | ||
305 | lua_Number rf = fltvalue(r); | ||
306 | return (neg ? !luai_numle(rf, lf) : luai_numlt(lf, rf)); | ||
307 | } | ||
308 | else /* 'r' is int and 'l' is float */ | ||
309 | return !LEintfloat(ivalue(r), lf, !neg); /* not (r <= l) ? */ | ||
310 | } | ||
311 | } | ||
312 | |||
313 | |||
314 | /* | ||
247 | ** Main operation less than; return 'l < r'. | 315 | ** Main operation less than; return 'l < r'. |
248 | */ | 316 | */ |
249 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | 317 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { |
250 | int res; | 318 | int res; |
251 | lua_Number nl, nr; | 319 | if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ |
252 | if (ttisinteger(l) && ttisinteger(r)) /* both operands are integers? */ | 320 | return LTnum(l, r, 0); |
253 | return (ivalue(l) < ivalue(r)); | ||
254 | else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */ | ||
255 | return luai_numlt(nl, nr); | ||
256 | else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | 321 | else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ |
257 | return l_strcmp(tsvalue(l), tsvalue(r)) < 0; | 322 | return l_strcmp(tsvalue(l), tsvalue(r)) < 0; |
258 | else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */ | 323 | else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */ |
@@ -271,11 +336,8 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | |||
271 | */ | 336 | */ |
272 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | 337 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { |
273 | int res; | 338 | int res; |
274 | lua_Number nl, nr; | 339 | if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ |
275 | if (ttisinteger(l) && ttisinteger(r)) /* both operands are integers? */ | 340 | return !LTnum(r, l, 1); |
276 | return (ivalue(l) <= ivalue(r)); | ||
277 | else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */ | ||
278 | return luai_numle(nl, nr); | ||
279 | else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | 341 | else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ |
280 | return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; | 342 | return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; |
281 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */ | 343 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */ |
@@ -604,7 +666,7 @@ void luaV_finishOp (lua_State *L) { | |||
604 | ** some macros for common tasks in 'luaV_execute' | 666 | ** some macros for common tasks in 'luaV_execute' |
605 | */ | 667 | */ |
606 | 668 | ||
607 | #if !defined luai_runtimecheck | 669 | #if !defined(luai_runtimecheck) |
608 | #define luai_runtimecheck(L, c) /* void */ | 670 | #define luai_runtimecheck(L, c) /* void */ |
609 | #endif | 671 | #endif |
610 | 672 | ||