diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-12-05 14:14:29 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-12-05 14:14:29 -0300 |
commit | d30569c06407529cc6e99f4a35ae5f9bfe6fa940 (patch) | |
tree | 51e560713cb01203d94d792a1e80f38ba7f84c52 | |
parent | 2d92102dee88a81711dca8e8ea3ef0ea9d732283 (diff) | |
download | lua-d30569c06407529cc6e99f4a35ae5f9bfe6fa940.tar.gz lua-d30569c06407529cc6e99f4a35ae5f9bfe6fa940.tar.bz2 lua-d30569c06407529cc6e99f4a35ae5f9bfe6fa940.zip |
Using an enumeration for float->integer coercion modes
-rw-r--r-- | lcode.c | 4 | ||||
-rw-r--r-- | ltable.c | 4 | ||||
-rw-r--r-- | lvm.c | 25 | ||||
-rw-r--r-- | lvm.h | 19 |
4 files changed, 30 insertions, 22 deletions
@@ -653,7 +653,7 @@ void luaK_int (FuncState *fs, int reg, lua_Integer i) { | |||
653 | 653 | ||
654 | static void luaK_float (FuncState *fs, int reg, lua_Number f) { | 654 | static void luaK_float (FuncState *fs, int reg, lua_Number f) { |
655 | lua_Integer fi; | 655 | lua_Integer fi; |
656 | if (luaV_flttointeger(f, &fi, 0) && fitsBx(fi)) | 656 | if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi)) |
657 | luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); | 657 | luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); |
658 | else | 658 | else |
659 | luaK_codek(fs, reg, luaK_numberK(fs, f)); | 659 | luaK_codek(fs, reg, luaK_numberK(fs, f)); |
@@ -1220,7 +1220,7 @@ static int isSCnumber (expdesc *e, int *pi, int *isfloat) { | |||
1220 | lua_Integer i; | 1220 | lua_Integer i; |
1221 | if (e->k == VKINT) | 1221 | if (e->k == VKINT) |
1222 | i = e->u.ival; | 1222 | i = e->u.ival; |
1223 | else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, 0)) | 1223 | else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, F2Ieq)) |
1224 | *isfloat = 1; | 1224 | *isfloat = 1; |
1225 | else | 1225 | else |
1226 | return 0; /* not a number */ | 1226 | return 0; /* not a number */ |
@@ -626,7 +626,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | |||
626 | else if (ttisfloat(key)) { | 626 | else if (ttisfloat(key)) { |
627 | lua_Number f = fltvalue(key); | 627 | lua_Number f = fltvalue(key); |
628 | lua_Integer k; | 628 | lua_Integer k; |
629 | if (luaV_flttointeger(f, &k, 0)) { /* does key fit in an integer? */ | 629 | if (luaV_flttointeger(f, &k, F2Ieq)) { /* does key fit in an integer? */ |
630 | setivalue(&aux, k); | 630 | setivalue(&aux, k); |
631 | key = &aux; /* insert it as an integer */ | 631 | key = &aux; /* insert it as an integer */ |
632 | } | 632 | } |
@@ -745,7 +745,7 @@ const TValue *luaH_get (Table *t, const TValue *key) { | |||
745 | case LUA_TNIL: return &absentkey; | 745 | case LUA_TNIL: return &absentkey; |
746 | case LUA_TNUMFLT: { | 746 | case LUA_TNUMFLT: { |
747 | lua_Integer k; | 747 | lua_Integer k; |
748 | if (luaV_flttointeger(fltvalue(key), &k, 0)) /* index is an integral? */ | 748 | if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ |
749 | return luaH_getint(t, k); /* use specialized version */ | 749 | return luaH_getint(t, k); /* use specialized version */ |
750 | /* else... */ | 750 | /* else... */ |
751 | } /* FALLTHROUGH */ | 751 | } /* FALLTHROUGH */ |
@@ -116,16 +116,13 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) { | |||
116 | 116 | ||
117 | 117 | ||
118 | /* | 118 | /* |
119 | ** try to convert a float to an integer, rounding according to 'mode': | 119 | ** try to convert a float to an integer, rounding according to 'mode'. |
120 | ** mode == 0: accepts only integral values | ||
121 | ** mode == 1: takes the floor of the number | ||
122 | ** mode == 2: takes the ceil of the number | ||
123 | */ | 120 | */ |
124 | int luaV_flttointeger (lua_Number n, lua_Integer *p, int mode) { | 121 | int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode) { |
125 | lua_Number f = l_floor(n); | 122 | lua_Number f = l_floor(n); |
126 | if (n != f) { /* not an integral value? */ | 123 | if (n != f) { /* not an integral value? */ |
127 | if (mode == 0) return 0; /* fails if mode demands integral value */ | 124 | if (mode == F2Ieq) return 0; /* fails if mode demands integral value */ |
128 | else if (mode == 2) /* needs ceil? */ | 125 | else if (mode == F2Iceil) /* needs ceil? */ |
129 | f += 1; /* convert floor to ceil (remember: n != f) */ | 126 | f += 1; /* convert floor to ceil (remember: n != f) */ |
130 | } | 127 | } |
131 | return lua_numbertointeger(f, p); | 128 | return lua_numbertointeger(f, p); |
@@ -137,7 +134,7 @@ int luaV_flttointeger (lua_Number n, lua_Integer *p, int mode) { | |||
137 | ** without string coercion. | 134 | ** without string coercion. |
138 | ** ("Fast track" handled by macro 'tointegerns'.) | 135 | ** ("Fast track" handled by macro 'tointegerns'.) |
139 | */ | 136 | */ |
140 | int luaV_tointegerns (const TValue *obj, lua_Integer *p, int mode) { | 137 | int luaV_tointegerns (const TValue *obj, lua_Integer *p, F2Imod mode) { |
141 | if (ttisfloat(obj)) | 138 | if (ttisfloat(obj)) |
142 | return luaV_flttointeger(fltvalue(obj), p, mode); | 139 | return luaV_flttointeger(fltvalue(obj), p, mode); |
143 | else if (ttisinteger(obj)) { | 140 | else if (ttisinteger(obj)) { |
@@ -152,7 +149,7 @@ int luaV_tointegerns (const TValue *obj, lua_Integer *p, int mode) { | |||
152 | /* | 149 | /* |
153 | ** try to convert a value to an integer. | 150 | ** try to convert a value to an integer. |
154 | */ | 151 | */ |
155 | int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | 152 | int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode) { |
156 | TValue v; | 153 | TValue v; |
157 | if (l_strton(obj, &v)) /* does 'obj' point to a numerical string? */ | 154 | if (l_strton(obj, &v)) /* does 'obj' point to a numerical string? */ |
158 | obj = &v; /* change it to point to its corresponding number */ | 155 | obj = &v; /* change it to point to its corresponding number */ |
@@ -178,7 +175,7 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | |||
178 | */ | 175 | */ |
179 | static int forlimit (lua_State *L, lua_Integer init, const TValue *lim, | 176 | static int forlimit (lua_State *L, lua_Integer init, const TValue *lim, |
180 | lua_Integer *p, lua_Integer step) { | 177 | lua_Integer *p, lua_Integer step) { |
181 | if (!luaV_tointeger(lim, p, (step < 0 ? 2 : 1))) { | 178 | if (!luaV_tointeger(lim, p, (step < 0 ? F2Iceil : F2Ifloor))) { |
182 | /* not coercible to in integer */ | 179 | /* not coercible to in integer */ |
183 | lua_Number flim; /* try to convert to float */ | 180 | lua_Number flim; /* try to convert to float */ |
184 | if (!tonumber(lim, &flim)) /* cannot convert to float? */ | 181 | if (!tonumber(lim, &flim)) /* cannot convert to float? */ |
@@ -417,7 +414,7 @@ static int LTintfloat (lua_Integer i, lua_Number f) { | |||
417 | return luai_numlt(cast_num(i), f); /* compare them as floats */ | 414 | return luai_numlt(cast_num(i), f); /* compare them as floats */ |
418 | else { /* i < f <=> i < ceil(f) */ | 415 | else { /* i < f <=> i < ceil(f) */ |
419 | lua_Integer fi; | 416 | lua_Integer fi; |
420 | if (luaV_flttointeger(f, &fi, 2)) /* fi = ceil(f) */ | 417 | if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ |
421 | return i < fi; /* compare them as integers */ | 418 | return i < fi; /* compare them as integers */ |
422 | else /* 'f' is either greater or less than all integers */ | 419 | else /* 'f' is either greater or less than all integers */ |
423 | return f > 0; /* greater? */ | 420 | return f > 0; /* greater? */ |
@@ -434,7 +431,7 @@ static int LEintfloat (lua_Integer i, lua_Number f) { | |||
434 | return luai_numle(cast_num(i), f); /* compare them as floats */ | 431 | return luai_numle(cast_num(i), f); /* compare them as floats */ |
435 | else { /* i <= f <=> i <= floor(f) */ | 432 | else { /* i <= f <=> i <= floor(f) */ |
436 | lua_Integer fi; | 433 | lua_Integer fi; |
437 | if (luaV_flttointeger(f, &fi, 1)) /* fi = floor(f) */ | 434 | if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ |
438 | return i <= fi; /* compare them as integers */ | 435 | return i <= fi; /* compare them as integers */ |
439 | else /* 'f' is either greater or less than all integers */ | 436 | else /* 'f' is either greater or less than all integers */ |
440 | return f > 0; /* greater? */ | 437 | return f > 0; /* greater? */ |
@@ -451,7 +448,7 @@ static int LTfloatint (lua_Number f, lua_Integer i) { | |||
451 | return luai_numlt(f, cast_num(i)); /* compare them as floats */ | 448 | return luai_numlt(f, cast_num(i)); /* compare them as floats */ |
452 | else { /* f < i <=> floor(f) < i */ | 449 | else { /* f < i <=> floor(f) < i */ |
453 | lua_Integer fi; | 450 | lua_Integer fi; |
454 | if (luaV_flttointeger(f, &fi, 1)) /* fi = floor(f) */ | 451 | if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ |
455 | return fi < i; /* compare them as integers */ | 452 | return fi < i; /* compare them as integers */ |
456 | else /* 'f' is either greater or less than all integers */ | 453 | else /* 'f' is either greater or less than all integers */ |
457 | return f < 0; /* less? */ | 454 | return f < 0; /* less? */ |
@@ -468,7 +465,7 @@ static int LEfloatint (lua_Number f, lua_Integer i) { | |||
468 | return luai_numle(f, cast_num(i)); /* compare them as floats */ | 465 | return luai_numle(f, cast_num(i)); /* compare them as floats */ |
469 | else { /* f <= i <=> ceil(f) <= i */ | 466 | else { /* f <= i <=> ceil(f) <= i */ |
470 | lua_Integer fi; | 467 | lua_Integer fi; |
471 | if (luaV_flttointeger(f, &fi, 2)) /* fi = ceil(f) */ | 468 | if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ |
472 | return fi <= i; /* compare them as integers */ | 469 | return fi <= i; /* compare them as integers */ |
473 | else /* 'f' is either greater or less than all integers */ | 470 | else /* 'f' is either greater or less than all integers */ |
474 | return f < 0; /* less? */ | 471 | return f < 0; /* less? */ |
@@ -33,10 +33,20 @@ | |||
33 | ** integral values) | 33 | ** integral values) |
34 | */ | 34 | */ |
35 | #if !defined(LUA_FLOORN2I) | 35 | #if !defined(LUA_FLOORN2I) |
36 | #define LUA_FLOORN2I 0 | 36 | #define LUA_FLOORN2I F2Ieq |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | 39 | ||
40 | /* | ||
41 | ** Rounding modes for float->integer coercion | ||
42 | */ | ||
43 | typedef enum { | ||
44 | F2Ieq, /* no rounding; accepts only integral values */ | ||
45 | F2Ifloor, /* takes the floor of the number */ | ||
46 | F2Iceil, /* takes the ceil of the number */ | ||
47 | } F2Imod; | ||
48 | |||
49 | |||
40 | /* convert an object to a float (including string coercion) */ | 50 | /* convert an object to a float (including string coercion) */ |
41 | #define tonumber(o,n) \ | 51 | #define tonumber(o,n) \ |
42 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) | 52 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) |
@@ -104,9 +114,10 @@ LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); | |||
104 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); | 114 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); |
105 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); | 115 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); |
106 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); | 116 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); |
107 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); | 117 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); |
108 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, int mode); | 118 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, |
109 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, int mode); | 119 | F2Imod mode); |
120 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); | ||
110 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, | 121 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, |
111 | StkId val, const TValue *slot); | 122 | StkId val, const TValue *slot); |
112 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | 123 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, |