OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --- a/src/Makefile |
2 | +++ b/src/Makefile |
||
3 | @@ -25,7 +25,7 @@ PLATS= aix ansi bsd freebsd generic linu |
||
4 | LUA_A= liblua.a |
||
5 | CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ |
||
6 | lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ |
||
7 | - lundump.o lvm.o lzio.o |
||
8 | + lundump.o lvm.o lzio.o lnum.o |
||
9 | LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ |
||
10 | lstrlib.o loadlib.o linit.o |
||
11 | |||
12 | @@ -148,6 +148,7 @@ llex.o: llex.c lua.h luaconf.h ldo.h lob |
||
13 | lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h |
||
14 | lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ |
||
15 | ltm.h lzio.h lmem.h ldo.h |
||
16 | +lnum.o: lnum.c lua.h llex.h lnum.h |
||
17 | loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h |
||
18 | lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ |
||
19 | ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h |
||
20 | @@ -179,4 +180,18 @@ lzio.o: lzio.c lua.h luaconf.h llimits.h |
||
21 | print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ |
||
22 | ltm.h lzio.h lmem.h lopcodes.h lundump.h |
||
23 | |||
24 | +luaconf.h: lnum_config.h |
||
25 | +lapi.c: lnum.h |
||
26 | +lauxlib.c: llimits.h |
||
27 | +lbaselib.c: llimits.h lobject.h lapi.h |
||
28 | +lcode.c: lnum.h |
||
29 | +liolib.c: lnum.h llex.h |
||
30 | +llex.c: lnum.h |
||
31 | +lnum.h: lobject.h |
||
32 | +lobject.c: llex.h lnum.h |
||
33 | +ltable.c: lnum.h |
||
34 | +lua.c: llimits.h |
||
35 | +lvm.c: llex.h lnum.h |
||
36 | +print.c: lnum.h |
||
37 | + |
||
38 | # (end of Makefile) |
||
39 | --- a/src/lapi.c |
||
40 | +++ b/src/lapi.c |
||
41 | @@ -28,7 +28,7 @@ |
||
42 | #include "ltm.h" |
||
43 | #include "lundump.h" |
||
44 | #include "lvm.h" |
||
45 | - |
||
46 | +#include "lnum.h" |
||
47 | |||
48 | |||
49 | const char lua_ident[] = |
||
50 | @@ -241,12 +241,13 @@ LUA_API void lua_pushvalue (lua_State *L |
||
51 | |||
52 | LUA_API int lua_type (lua_State *L, int idx) { |
||
53 | StkId o = index2adr(L, idx); |
||
54 | - return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); |
||
55 | + return (o == luaO_nilobject) ? LUA_TNONE : ttype_ext(o); |
||
56 | } |
||
57 | |||
58 | |||
59 | LUA_API const char *lua_typename (lua_State *L, int t) { |
||
60 | UNUSED(L); |
||
61 | + lua_assert( t!= LUA_TINT ); |
||
62 | return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; |
||
63 | } |
||
64 | |||
65 | @@ -264,6 +265,14 @@ LUA_API int lua_isnumber (lua_State *L, |
||
66 | } |
||
67 | |||
68 | |||
69 | +LUA_API int lua_isinteger (lua_State *L, int idx) { |
||
70 | + TValue tmp; |
||
71 | + lua_Integer dum; |
||
72 | + const TValue *o = index2adr(L, idx); |
||
73 | + return tonumber(o,&tmp) && (ttisint(o) || tt_integer_valued(o,&dum)); |
||
74 | +} |
||
75 | + |
||
76 | + |
||
77 | LUA_API int lua_isstring (lua_State *L, int idx) { |
||
78 | int t = lua_type(L, idx); |
||
79 | return (t == LUA_TSTRING || t == LUA_TNUMBER); |
||
80 | @@ -309,31 +318,66 @@ LUA_API int lua_lessthan (lua_State *L, |
||
81 | } |
||
82 | |||
83 | |||
84 | - |
||
85 | LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { |
||
86 | TValue n; |
||
87 | const TValue *o = index2adr(L, idx); |
||
88 | - if (tonumber(o, &n)) |
||
89 | + if (tonumber(o, &n)) { |
||
90 | +#ifdef LNUM_COMPLEX |
||
91 | + if (nvalue_img(o) != 0) |
||
92 | + luaG_runerror(L, "expecting a real number"); |
||
93 | +#endif |
||
94 | return nvalue(o); |
||
95 | - else |
||
96 | - return 0; |
||
97 | + } |
||
98 | + return 0; |
||
99 | } |
||
100 | |||
101 | |||
102 | LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { |
||
103 | TValue n; |
||
104 | + /* Lua 5.1 documented behaviour is to return nonzero for non-integer: |
||
105 | + * "If the number is not an integer, it is truncated in some non-specified way." |
||
106 | + * I would suggest to change this, to return 0 for anything that would |
||
107 | + * not fit in 'lua_Integer'. |
||
108 | + */ |
||
109 | +#ifdef LUA_COMPAT_TOINTEGER |
||
110 | + /* Lua 5.1 compatible */ |
||
111 | const TValue *o = index2adr(L, idx); |
||
112 | if (tonumber(o, &n)) { |
||
113 | - lua_Integer res; |
||
114 | - lua_Number num = nvalue(o); |
||
115 | - lua_number2integer(res, num); |
||
116 | - return res; |
||
117 | + lua_Integer i; |
||
118 | + lua_Number d; |
||
119 | + if (ttisint(o)) return ivalue(o); |
||
120 | + d= nvalue_fast(o); |
||
121 | +# ifdef LNUM_COMPLEX |
||
122 | + if (nvalue_img_fast(o) != 0) |
||
123 | + luaG_runerror(L, "expecting a real number"); |
||
124 | +# endif |
||
125 | + lua_number2integer(i, d); |
||
126 | + return i; |
||
127 | } |
||
128 | - else |
||
129 | - return 0; |
||
130 | +#else |
||
131 | + /* New suggestion */ |
||
132 | + const TValue *o = index2adr(L, idx); |
||
133 | + if (tonumber(o, &n)) { |
||
134 | + lua_Integer i; |
||
135 | + if (ttisint(o)) return ivalue(o); |
||
136 | + if (tt_integer_valued(o,&i)) return i; |
||
137 | + } |
||
138 | +#endif |
||
139 | + return 0; |
||
140 | } |
||
141 | |||
142 | |||
143 | +#ifdef LNUM_COMPLEX |
||
144 | +LUA_API lua_Complex lua_tocomplex (lua_State *L, int idx) { |
||
145 | + TValue tmp; |
||
146 | + const TValue *o = index2adr(L, idx); |
||
147 | + if (tonumber(o, &tmp)) |
||
148 | + return nvalue_complex(o); |
||
149 | + return 0; |
||
150 | +} |
||
151 | +#endif |
||
152 | + |
||
153 | + |
||
154 | LUA_API int lua_toboolean (lua_State *L, int idx) { |
||
155 | const TValue *o = index2adr(L, idx); |
||
156 | return !l_isfalse(o); |
||
157 | @@ -364,6 +408,7 @@ LUA_API size_t lua_objlen (lua_State *L, |
||
158 | case LUA_TSTRING: return tsvalue(o)->len; |
||
159 | case LUA_TUSERDATA: return uvalue(o)->len; |
||
160 | case LUA_TTABLE: return luaH_getn(hvalue(o)); |
||
161 | + case LUA_TINT: |
||
162 | case LUA_TNUMBER: { |
||
163 | size_t l; |
||
164 | lua_lock(L); /* `luaV_tostring' may create a new string */ |
||
165 | @@ -426,6 +471,8 @@ LUA_API void lua_pushnil (lua_State *L) |
||
166 | } |
||
167 | |||
168 | |||
169 | +/* 'lua_pushnumber()' may lose accuracy on integers, 'lua_pushinteger' will not. |
||
170 | + */ |
||
171 | LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { |
||
172 | lua_lock(L); |
||
173 | setnvalue(L->top, n); |
||
174 | @@ -434,12 +481,22 @@ LUA_API void lua_pushnumber (lua_State * |
||
175 | } |
||
176 | |||
177 | |||
178 | -LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { |
||
179 | +LUA_API void lua_pushinteger (lua_State *L, lua_Integer i) { |
||
180 | + lua_lock(L); |
||
181 | + setivalue(L->top, i); |
||
182 | + api_incr_top(L); |
||
183 | + lua_unlock(L); |
||
184 | +} |
||
185 | + |
||
186 | + |
||
187 | +#ifdef LNUM_COMPLEX |
||
188 | +LUA_API void lua_pushcomplex (lua_State *L, lua_Complex v) { |
||
189 | lua_lock(L); |
||
190 | - setnvalue(L->top, cast_num(n)); |
||
191 | + setnvalue_complex( L->top, v ); |
||
192 | api_incr_top(L); |
||
193 | lua_unlock(L); |
||
194 | } |
||
195 | +#endif |
||
196 | |||
197 | |||
198 | LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { |
||
199 | @@ -569,7 +626,7 @@ LUA_API void lua_rawgeti (lua_State *L, |
||
200 | lua_lock(L); |
||
201 | o = index2adr(L, idx); |
||
202 | api_check(L, ttistable(o)); |
||
203 | - setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); |
||
204 | + setobj2s(L, L->top, luaH_getint(hvalue(o), n)); |
||
205 | api_incr_top(L); |
||
206 | lua_unlock(L); |
||
207 | } |
||
208 | @@ -597,6 +654,9 @@ LUA_API int lua_getmetatable (lua_State |
||
209 | case LUA_TUSERDATA: |
||
210 | mt = uvalue(obj)->metatable; |
||
211 | break; |
||
212 | + case LUA_TINT: |
||
213 | + mt = G(L)->mt[LUA_TNUMBER]; |
||
214 | + break; |
||
215 | default: |
||
216 | mt = G(L)->mt[ttype(obj)]; |
||
217 | break; |
||
218 | @@ -687,7 +747,7 @@ LUA_API void lua_rawseti (lua_State *L, |
||
219 | api_checknelems(L, 1); |
||
220 | o = index2adr(L, idx); |
||
221 | api_check(L, ttistable(o)); |
||
222 | - setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); |
||
223 | + setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1); |
||
224 | luaC_barriert(L, hvalue(o), L->top-1); |
||
225 | L->top--; |
||
226 | lua_unlock(L); |
||
227 | @@ -721,7 +781,7 @@ LUA_API int lua_setmetatable (lua_State |
||
228 | break; |
||
229 | } |
||
230 | default: { |
||
231 | - G(L)->mt[ttype(obj)] = mt; |
||
232 | + G(L)->mt[ttype_ext(obj)] = mt; |
||
233 | break; |
||
234 | } |
||
235 | } |
||
236 | @@ -1085,3 +1145,32 @@ LUA_API const char *lua_setupvalue (lua_ |
||
237 | return name; |
||
238 | } |
||
239 | |||
240 | + |
||
241 | +/* Help function for 'luaB_tonumber()', avoids multiple str->number |
||
242 | + * conversions for Lua "tonumber()". |
||
243 | + * |
||
244 | + * Also pushes floating point numbers with integer value as integer, which |
||
245 | + * can be used by 'tonumber()' in scripts to bring values back to integer |
||
246 | + * realm. |
||
247 | + * |
||
248 | + * Note: The 'back to integer realm' is _not_ to affect string conversions: |
||
249 | + * 'tonumber("4294967295.1")' should give a floating point value, although |
||
250 | + * the value would be 4294967296 (and storable in int64 realm). |
||
251 | + */ |
||
252 | +int lua_pushvalue_as_number (lua_State *L, int idx) |
||
253 | +{ |
||
254 | + const TValue *o = index2adr(L, idx); |
||
255 | + TValue tmp; |
||
256 | + lua_Integer i; |
||
257 | + if (ttisnumber(o)) { |
||
258 | + if ( (!ttisint(o)) && tt_integer_valued(o,&i)) { |
||
259 | + lua_pushinteger( L, i ); |
||
260 | + return 1; |
||
261 | + } |
||
262 | + } else if (!tonumber(o, &tmp)) { |
||
263 | + return 0; |
||
264 | + } |
||
265 | + if (ttisint(o)) lua_pushinteger( L, ivalue(o) ); |
||
266 | + else lua_pushnumber( L, nvalue_fast(o) ); |
||
267 | + return 1; |
||
268 | +} |
||
269 | --- a/src/lapi.h |
||
270 | +++ b/src/lapi.h |
||
271 | @@ -13,4 +13,6 @@ |
||
272 | |||
273 | LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); |
||
274 | |||
275 | +int lua_pushvalue_as_number (lua_State *L, int idx); |
||
276 | + |
||
277 | #endif |
||
278 | --- a/src/lauxlib.c |
||
279 | +++ b/src/lauxlib.c |
||
280 | @@ -23,7 +23,7 @@ |
||
281 | #include "lua.h" |
||
282 | |||
283 | #include "lauxlib.h" |
||
284 | - |
||
285 | +#include "llimits.h" |
||
286 | |||
287 | #define FREELIST_REF 0 /* free list of references */ |
||
288 | |||
289 | @@ -66,7 +66,7 @@ LUALIB_API int luaL_typerror (lua_State |
||
290 | |||
291 | |||
292 | static void tag_error (lua_State *L, int narg, int tag) { |
||
293 | - luaL_typerror(L, narg, lua_typename(L, tag)); |
||
294 | + luaL_typerror(L, narg, tag==LUA_TINT ? "integer" : lua_typename(L, tag)); |
||
295 | } |
||
296 | |||
297 | |||
298 | @@ -188,8 +188,8 @@ LUALIB_API lua_Number luaL_optnumber (lu |
||
299 | |||
300 | LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { |
||
301 | lua_Integer d = lua_tointeger(L, narg); |
||
302 | - if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ |
||
303 | - tag_error(L, narg, LUA_TNUMBER); |
||
304 | + if (d == 0 && !lua_isinteger(L, narg)) /* avoid extra test when d is not 0 */ |
||
305 | + tag_error(L, narg, LUA_TINT); |
||
306 | return d; |
||
307 | } |
||
308 | |||
309 | @@ -200,6 +200,16 @@ LUALIB_API lua_Integer luaL_optinteger ( |
||
310 | } |
||
311 | |||
312 | |||
313 | +#ifdef LNUM_COMPLEX |
||
314 | +LUALIB_API lua_Complex luaL_checkcomplex (lua_State *L, int narg) { |
||
315 | + lua_Complex c = lua_tocomplex(L, narg); |
||
316 | + if (c == 0 && !lua_isnumber(L, narg)) /* avoid extra test when c is not 0 */ |
||
317 | + tag_error(L, narg, LUA_TNUMBER); |
||
318 | + return c; |
||
319 | +} |
||
320 | +#endif |
||
321 | + |
||
322 | + |
||
323 | LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { |
||
324 | if (!lua_getmetatable(L, obj)) /* no metatable? */ |
||
325 | return 0; |
||
326 | --- a/src/lauxlib.h |
||
327 | +++ b/src/lauxlib.h |
||
328 | @@ -57,6 +57,12 @@ LUALIB_API lua_Number (luaL_optnumber) ( |
||
329 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); |
||
330 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, |
||
331 | lua_Integer def); |
||
332 | +#define luaL_checkint32(L,narg) ((int)luaL_checkinteger(L,narg)) |
||
333 | +#define luaL_optint32(L,narg,def) ((int)luaL_optinteger(L,narg,def)) |
||
334 | + |
||
335 | +#ifdef LNUM_COMPLEX |
||
336 | + LUALIB_API lua_Complex (luaL_checkcomplex) (lua_State *L, int narg); |
||
337 | +#endif |
||
338 | |||
339 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); |
||
340 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); |
||
341 | --- a/src/lbaselib.c |
||
342 | +++ b/src/lbaselib.c |
||
343 | @@ -18,7 +18,9 @@ |
||
344 | |||
345 | #include "lauxlib.h" |
||
346 | #include "lualib.h" |
||
347 | - |
||
348 | +#include "llimits.h" |
||
349 | +#include "lobject.h" |
||
350 | +#include "lapi.h" |
||
351 | |||
352 | |||
353 | |||
354 | @@ -54,20 +56,25 @@ static int luaB_tonumber (lua_State *L) |
||
355 | int base = luaL_optint(L, 2, 10); |
||
356 | if (base == 10) { /* standard conversion */ |
||
357 | luaL_checkany(L, 1); |
||
358 | - if (lua_isnumber(L, 1)) { |
||
359 | - lua_pushnumber(L, lua_tonumber(L, 1)); |
||
360 | + if (lua_isnumber(L, 1)) { /* numeric string, or a number */ |
||
361 | + lua_pushvalue_as_number(L,1); /* API extension (not to lose accuracy here) */ |
||
362 | return 1; |
||
363 | - } |
||
364 | + } |
||
365 | } |
||
366 | else { |
||
367 | const char *s1 = luaL_checkstring(L, 1); |
||
368 | char *s2; |
||
369 | - unsigned long n; |
||
370 | + unsigned LUA_INTEGER n; |
||
371 | luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); |
||
372 | - n = strtoul(s1, &s2, base); |
||
373 | + n = lua_str2ul(s1, &s2, base); |
||
374 | if (s1 != s2) { /* at least one valid digit? */ |
||
375 | while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ |
||
376 | if (*s2 == '\0') { /* no invalid trailing characters? */ |
||
377 | + |
||
378 | + /* Push as number, there needs to be separate 'luaB_tointeger' for |
||
379 | + * when the caller wants to preserve the bits (matters if unsigned |
||
380 | + * values are used). |
||
381 | + */ |
||
382 | lua_pushnumber(L, (lua_Number)n); |
||
383 | return 1; |
||
384 | } |
||
385 | @@ -144,7 +151,7 @@ static int luaB_setfenv (lua_State *L) { |
||
386 | luaL_checktype(L, 2, LUA_TTABLE); |
||
387 | getfunc(L, 0); |
||
388 | lua_pushvalue(L, 2); |
||
389 | - if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { |
||
390 | + if (lua_isnumber(L, 1) && lua_tointeger(L, 1) == 0) { |
||
391 | /* change environment of current thread */ |
||
392 | lua_pushthread(L); |
||
393 | lua_insert(L, -2); |
||
394 | @@ -209,7 +216,7 @@ static int luaB_collectgarbage (lua_Stat |
||
395 | return 1; |
||
396 | } |
||
397 | default: { |
||
398 | - lua_pushnumber(L, res); |
||
399 | + lua_pushinteger(L, res); |
||
400 | return 1; |
||
401 | } |
||
402 | } |
||
403 | @@ -631,6 +638,8 @@ static void base_open (lua_State *L) { |
||
404 | luaL_register(L, "_G", base_funcs); |
||
405 | lua_pushliteral(L, LUA_VERSION); |
||
406 | lua_setglobal(L, "_VERSION"); /* set global _VERSION */ |
||
407 | + lua_pushliteral(L, LUA_LNUM); |
||
408 | + lua_setglobal(L, "_LNUM"); /* "[complex] double|float|ldouble int32|int64" */ |
||
409 | /* `ipairs' and `pairs' need auxiliary functions as upvalues */ |
||
410 | auxopen(L, "ipairs", luaB_ipairs, ipairsaux); |
||
411 | auxopen(L, "pairs", luaB_pairs, luaB_next); |
||
412 | --- a/src/lcode.c |
||
413 | +++ b/src/lcode.c |
||
414 | @@ -22,13 +22,18 @@ |
||
415 | #include "lopcodes.h" |
||
416 | #include "lparser.h" |
||
417 | #include "ltable.h" |
||
418 | +#include "lnum.h" |
||
419 | |||
420 | |||
421 | #define hasjumps(e) ((e)->t != (e)->f) |
||
422 | |||
423 | - |
||
424 | static int isnumeral(expdesc *e) { |
||
425 | - return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); |
||
426 | + int ek= |
||
427 | +#ifdef LNUM_COMPLEX |
||
428 | + (e->k == VKNUM2) || |
||
429 | +#endif |
||
430 | + (e->k == VKINT) || (e->k == VKNUM); |
||
431 | + return (ek && e->t == NO_JUMP && e->f == NO_JUMP); |
||
432 | } |
||
433 | |||
434 | |||
435 | @@ -231,12 +236,16 @@ static int addk (FuncState *fs, TValue * |
||
436 | TValue *idx = luaH_set(L, fs->h, k); |
||
437 | Proto *f = fs->f; |
||
438 | int oldsize = f->sizek; |
||
439 | - if (ttisnumber(idx)) { |
||
440 | - lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); |
||
441 | - return cast_int(nvalue(idx)); |
||
442 | + if (ttype(idx)==LUA_TNUMBER) { |
||
443 | + luai_normalize(idx); |
||
444 | + lua_assert( ttype(idx)==LUA_TINT ); /* had no fraction */ |
||
445 | + } |
||
446 | + if (ttisint(idx)) { |
||
447 | + lua_assert(luaO_rawequalObj(&fs->f->k[ivalue(idx)], v)); |
||
448 | + return cast_int(ivalue(idx)); |
||
449 | } |
||
450 | else { /* constant not found; create a new entry */ |
||
451 | - setnvalue(idx, cast_num(fs->nk)); |
||
452 | + setivalue(idx, fs->nk); |
||
453 | luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, |
||
454 | MAXARG_Bx, "constant table overflow"); |
||
455 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); |
||
456 | @@ -261,6 +270,21 @@ int luaK_numberK (FuncState *fs, lua_Num |
||
457 | } |
||
458 | |||
459 | |||
460 | +int luaK_integerK (FuncState *fs, lua_Integer r) { |
||
461 | + TValue o; |
||
462 | + setivalue(&o, r); |
||
463 | + return addk(fs, &o, &o); |
||
464 | +} |
||
465 | + |
||
466 | + |
||
467 | +#ifdef LNUM_COMPLEX |
||
468 | +static int luaK_imagK (FuncState *fs, lua_Number r) { |
||
469 | + TValue o; |
||
470 | + setnvalue_complex(&o, r*I); |
||
471 | + return addk(fs, &o, &o); |
||
472 | +} |
||
473 | +#endif |
||
474 | + |
||
475 | static int boolK (FuncState *fs, int b) { |
||
476 | TValue o; |
||
477 | setbvalue(&o, b); |
||
478 | @@ -359,6 +383,16 @@ static void discharge2reg (FuncState *fs |
||
479 | luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); |
||
480 | break; |
||
481 | } |
||
482 | + case VKINT: { |
||
483 | + luaK_codeABx(fs, OP_LOADK, reg, luaK_integerK(fs, e->u.ival)); |
||
484 | + break; |
||
485 | + } |
||
486 | +#ifdef LNUM_COMPLEX |
||
487 | + case VKNUM2: { |
||
488 | + luaK_codeABx(fs, OP_LOADK, reg, luaK_imagK(fs, e->u.nval)); |
||
489 | + break; |
||
490 | + } |
||
491 | +#endif |
||
492 | case VRELOCABLE: { |
||
493 | Instruction *pc = &getcode(fs, e); |
||
494 | SETARG_A(*pc, reg); |
||
495 | @@ -444,6 +478,10 @@ void luaK_exp2val (FuncState *fs, expdes |
||
496 | int luaK_exp2RK (FuncState *fs, expdesc *e) { |
||
497 | luaK_exp2val(fs, e); |
||
498 | switch (e->k) { |
||
499 | +#ifdef LNUM_COMPLEX |
||
500 | + case VKNUM2: |
||
501 | +#endif |
||
502 | + case VKINT: |
||
503 | case VKNUM: |
||
504 | case VTRUE: |
||
505 | case VFALSE: |
||
506 | @@ -451,6 +489,10 @@ int luaK_exp2RK (FuncState *fs, expdesc |
||
507 | if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ |
||
508 | e->u.s.info = (e->k == VNIL) ? nilK(fs) : |
||
509 | (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : |
||
510 | + (e->k == VKINT) ? luaK_integerK(fs, e->u.ival) : |
||
511 | +#ifdef LNUM_COMPLEX |
||
512 | + (e->k == VKNUM2) ? luaK_imagK(fs, e->u.nval) : |
||
513 | +#endif |
||
514 | boolK(fs, (e->k == VTRUE)); |
||
515 | e->k = VK; |
||
516 | return RKASK(e->u.s.info); |
||
517 | @@ -540,7 +582,10 @@ void luaK_goiftrue (FuncState *fs, expde |
||
518 | int pc; /* pc of last jump */ |
||
519 | luaK_dischargevars(fs, e); |
||
520 | switch (e->k) { |
||
521 | - case VK: case VKNUM: case VTRUE: { |
||
522 | +#ifdef LNUM_COMPLEX |
||
523 | + case VKNUM2: |
||
524 | +#endif |
||
525 | + case VKINT: case VK: case VKNUM: case VTRUE: { |
||
526 | pc = NO_JUMP; /* always true; do nothing */ |
||
527 | break; |
||
528 | } |
||
529 | @@ -590,7 +635,10 @@ static void codenot (FuncState *fs, expd |
||
530 | e->k = VTRUE; |
||
531 | break; |
||
532 | } |
||
533 | - case VK: case VKNUM: case VTRUE: { |
||
534 | +#ifdef LNUM_COMPLEX |
||
535 | + case VKNUM2: |
||
536 | +#endif |
||
537 | + case VKINT: case VK: case VKNUM: case VTRUE: { |
||
538 | e->k = VFALSE; |
||
539 | break; |
||
540 | } |
||
541 | @@ -626,25 +674,70 @@ void luaK_indexed (FuncState *fs, expdes |
||
542 | |||
543 | static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { |
||
544 | lua_Number v1, v2, r; |
||
545 | + int vkres= VKNUM; |
||
546 | if (!isnumeral(e1) || !isnumeral(e2)) return 0; |
||
547 | - v1 = e1->u.nval; |
||
548 | - v2 = e2->u.nval; |
||
549 | + |
||
550 | + /* real and imaginary parts don't mix. */ |
||
551 | +#ifdef LNUM_COMPLEX |
||
552 | + if (e1->k == VKNUM2) { |
||
553 | + if ((op != OP_UNM) && (e2->k != VKNUM2)) return 0; |
||
554 | + vkres= VKNUM2; } |
||
555 | + else if (e2->k == VKNUM2) { return 0; } |
||
556 | +#endif |
||
557 | + if ((e1->k == VKINT) && (e2->k == VKINT)) { |
||
558 | + lua_Integer i1= e1->u.ival, i2= e2->u.ival; |
||
559 | + lua_Integer rr; |
||
560 | + int done= 0; |
||
561 | + /* Integer/integer calculations (may end up producing floating point) */ |
||
562 | + switch (op) { |
||
563 | + case OP_ADD: done= try_addint( &rr, i1, i2 ); break; |
||
564 | + case OP_SUB: done= try_subint( &rr, i1, i2 ); break; |
||
565 | + case OP_MUL: done= try_mulint( &rr, i1, i2 ); break; |
||
566 | + case OP_DIV: done= try_divint( &rr, i1, i2 ); break; |
||
567 | + case OP_MOD: done= try_modint( &rr, i1, i2 ); break; |
||
568 | + case OP_POW: done= try_powint( &rr, i1, i2 ); break; |
||
569 | + case OP_UNM: done= try_unmint( &rr, i1 ); break; |
||
570 | + default: done= 0; break; |
||
571 | + } |
||
572 | + if (done) { |
||
573 | + e1->u.ival = rr; /* remained within integer range */ |
||
574 | + return 1; |
||
575 | + } |
||
576 | + } |
||
577 | + v1 = (e1->k == VKINT) ? ((lua_Number)e1->u.ival) : e1->u.nval; |
||
578 | + v2 = (e2->k == VKINT) ? ((lua_Number)e2->u.ival) : e2->u.nval; |
||
579 | + |
||
580 | switch (op) { |
||
581 | case OP_ADD: r = luai_numadd(v1, v2); break; |
||
582 | case OP_SUB: r = luai_numsub(v1, v2); break; |
||
583 | - case OP_MUL: r = luai_nummul(v1, v2); break; |
||
584 | + case OP_MUL: |
||
585 | +#ifdef LNUM_COMPLEX |
||
586 | + if (vkres==VKNUM2) return 0; /* leave to runtime (could do here, but not worth it?) */ |
||
587 | +#endif |
||
588 | + r = luai_nummul(v1, v2); break; |
||
589 | case OP_DIV: |
||
590 | if (v2 == 0) return 0; /* do not attempt to divide by 0 */ |
||
591 | - r = luai_numdiv(v1, v2); break; |
||
592 | +#ifdef LNUM_COMPLEX |
||
593 | + if (vkres==VKNUM2) return 0; /* leave to runtime */ |
||
594 | +#endif |
||
595 | + r = luai_numdiv(v1, v2); break; |
||
596 | case OP_MOD: |
||
597 | if (v2 == 0) return 0; /* do not attempt to divide by 0 */ |
||
598 | +#ifdef LNUM_COMPLEX |
||
599 | + if (vkres==VKNUM2) return 0; /* leave to runtime */ |
||
600 | +#endif |
||
601 | r = luai_nummod(v1, v2); break; |
||
602 | - case OP_POW: r = luai_numpow(v1, v2); break; |
||
603 | + case OP_POW: |
||
604 | +#ifdef LNUM_COMPLEX |
||
605 | + if (vkres==VKNUM2) return 0; /* leave to runtime */ |
||
606 | +#endif |
||
607 | + r = luai_numpow(v1, v2); break; |
||
608 | case OP_UNM: r = luai_numunm(v1); break; |
||
609 | case OP_LEN: return 0; /* no constant folding for 'len' */ |
||
610 | default: lua_assert(0); r = 0; break; |
||
611 | } |
||
612 | if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ |
||
613 | + e1->k = cast(expkind,vkres); |
||
614 | e1->u.nval = r; |
||
615 | return 1; |
||
616 | } |
||
617 | @@ -688,7 +781,8 @@ static void codecomp (FuncState *fs, OpC |
||
618 | |||
619 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { |
||
620 | expdesc e2; |
||
621 | - e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; |
||
622 | + e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0; |
||
623 | + |
||
624 | switch (op) { |
||
625 | case OPR_MINUS: { |
||
626 | if (!isnumeral(e)) |
||
627 | --- a/src/lcode.h |
||
628 | +++ b/src/lcode.h |
||
629 | @@ -71,6 +71,6 @@ LUAI_FUNC void luaK_prefix (FuncState *f |
||
630 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); |
||
631 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); |
||
632 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); |
||
633 | - |
||
634 | +LUAI_FUNC int luaK_integerK (FuncState *fs, lua_Integer r); |
||
635 | |||
636 | #endif |
||
637 | --- a/src/ldebug.c |
||
638 | +++ b/src/ldebug.c |
||
639 | @@ -183,7 +183,7 @@ static void collectvalidlines (lua_State |
||
640 | int *lineinfo = f->l.p->lineinfo; |
||
641 | int i; |
||
642 | for (i=0; i<f->l.p->sizelineinfo; i++) |
||
643 | - setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); |
||
644 | + setbvalue(luaH_setint(L, t, lineinfo[i]), 1); |
||
645 | sethvalue(L, L->top, t); |
||
646 | } |
||
647 | incr_top(L); |
||
648 | @@ -566,7 +566,7 @@ static int isinstack (CallInfo *ci, cons |
||
649 | |||
650 | void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { |
||
651 | const char *name = NULL; |
||
652 | - const char *t = luaT_typenames[ttype(o)]; |
||
653 | + const char *t = luaT_typenames[ttype_ext(o)]; |
||
654 | const char *kind = (isinstack(L->ci, o)) ? |
||
655 | getobjname(L, L->ci, cast_int(o - L->base), &name) : |
||
656 | NULL; |
||
657 | @@ -594,8 +594,8 @@ void luaG_aritherror (lua_State *L, cons |
||
658 | |||
659 | |||
660 | int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { |
||
661 | - const char *t1 = luaT_typenames[ttype(p1)]; |
||
662 | - const char *t2 = luaT_typenames[ttype(p2)]; |
||
663 | + const char *t1 = luaT_typenames[ttype_ext(p1)]; |
||
664 | + const char *t2 = luaT_typenames[ttype_ext(p2)]; |
||
665 | if (t1[2] == t2[2]) |
||
666 | luaG_runerror(L, "attempt to compare two %s values", t1); |
||
667 | else |
||
668 | --- a/src/ldo.c |
||
669 | +++ b/src/ldo.c |
||
670 | @@ -220,9 +220,9 @@ static StkId adjust_varargs (lua_State * |
||
671 | luaD_checkstack(L, p->maxstacksize); |
||
672 | htab = luaH_new(L, nvar, 1); /* create `arg' table */ |
||
673 | for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */ |
||
674 | - setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i); |
||
675 | + setobj2n(L, luaH_setint(L, htab, i+1), L->top - nvar + i); |
||
676 | /* store counter in field `n' */ |
||
677 | - setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); |
||
678 | + setivalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), nvar); |
||
679 | } |
||
680 | #endif |
||
681 | /* move fixed parameters to final position */ |
||
682 | --- a/src/ldump.c |
||
683 | +++ b/src/ldump.c |
||
684 | @@ -52,6 +52,11 @@ static void DumpNumber(lua_Number x, Dum |
||
685 | DumpVar(x,D); |
||
686 | } |
||
687 | |||
688 | +static void DumpInteger(lua_Integer x, DumpState* D) |
||
689 | +{ |
||
690 | + DumpVar(x,D); |
||
691 | +} |
||
692 | + |
||
693 | static void DumpVector(const void* b, int n, size_t size, DumpState* D) |
||
694 | { |
||
695 | DumpInt(n,D); |
||
696 | @@ -93,8 +98,11 @@ static void DumpConstants(const Proto* f |
||
697 | DumpChar(bvalue(o),D); |
||
698 | break; |
||
699 | case LUA_TNUMBER: |
||
700 | - DumpNumber(nvalue(o),D); |
||
701 | + DumpNumber(nvalue_fast(o),D); |
||
702 | break; |
||
703 | + case LUA_TINT: |
||
704 | + DumpInteger(ivalue(o),D); |
||
705 | + break; |
||
706 | case LUA_TSTRING: |
||
707 | DumpString(rawtsvalue(o),D); |
||
708 | break; |
||
709 | --- a/src/liolib.c |
||
710 | +++ b/src/liolib.c |
||
711 | @@ -9,6 +9,7 @@ |
||
712 | #include <stdio.h> |
||
713 | #include <stdlib.h> |
||
714 | #include <string.h> |
||
715 | +#include <ctype.h> |
||
716 | |||
717 | #define liolib_c |
||
718 | #define LUA_LIB |
||
719 | @@ -18,7 +19,8 @@ |
||
720 | #include "lauxlib.h" |
||
721 | #include "lualib.h" |
||
722 | |||
723 | - |
||
724 | +#include "lnum.h" |
||
725 | +#include "llex.h" |
||
726 | |||
727 | #define IO_INPUT 1 |
||
728 | #define IO_OUTPUT 2 |
||
729 | @@ -269,6 +271,13 @@ static int io_lines (lua_State *L) { |
||
730 | ** ======================================================= |
||
731 | */ |
||
732 | |||
733 | +/* |
||
734 | +* Many problems if we intend the same 'n' format specifier (see 'file:read()') |
||
735 | +* to work for both FP and integer numbers, without losing their accuracy. So |
||
736 | +* we don't. 'n' reads numbers as floating points, 'i' as integers. Old code |
||
737 | +* remains valid, but won't provide full integer accuracy (this only matters |
||
738 | +* with float FP and/or 64-bit integers). |
||
739 | +*/ |
||
740 | |||
741 | static int read_number (lua_State *L, FILE *f) { |
||
742 | lua_Number d; |
||
743 | @@ -282,6 +291,43 @@ static int read_number (lua_State *L, FI |
||
744 | } |
||
745 | } |
||
746 | |||
747 | +static int read_integer (lua_State *L, FILE *f) { |
||
748 | + lua_Integer i; |
||
749 | + if (fscanf(f, LUA_INTEGER_SCAN, &i) == 1) { |
||
750 | + lua_pushinteger(L, i); |
||
751 | + return 1; |
||
752 | + } |
||
753 | + else return 0; /* read fails */ |
||
754 | +} |
||
755 | + |
||
756 | +#ifdef LNUM_COMPLEX |
||
757 | +static int read_complex (lua_State *L, FILE *f) { |
||
758 | + /* NNN / NNNi / NNN+MMMi / NNN-MMMi */ |
||
759 | + lua_Number a,b; |
||
760 | + if (fscanf(f, LUA_NUMBER_SCAN, &a) == 1) { |
||
761 | + int c=fgetc(f); |
||
762 | + switch(c) { |
||
763 | + case 'i': |
||
764 | + lua_pushcomplex(L, a*I); |
||
765 | + return 1; |
||
766 | + case '+': |
||
767 | + case '-': |
||
768 | + /* "i" is consumed if at the end; just 'NNN+MMM' will most likely |
||
769 | + * behave as if "i" was there? (TBD: test) |
||
770 | + */ |
||
771 | + if (fscanf(f, LUA_NUMBER_SCAN "i", &b) == 1) { |
||
772 | + lua_pushcomplex(L, a+ (c=='+' ? b:-b)*I); |
||
773 | + return 1; |
||
774 | + } |
||
775 | + } |
||
776 | + ungetc( c,f ); |
||
777 | + lua_pushnumber(L,a); /*real part only*/ |
||
778 | + return 1; |
||
779 | + } |
||
780 | + return 0; /* read fails */ |
||
781 | +} |
||
782 | +#endif |
||
783 | + |
||
784 | |||
785 | static int test_eof (lua_State *L, FILE *f) { |
||
786 | int c = getc(f); |
||
787 | @@ -355,6 +401,14 @@ static int g_read (lua_State *L, FILE *f |
||
788 | case 'n': /* number */ |
||
789 | success = read_number(L, f); |
||
790 | break; |
||
791 | + case 'i': /* integer (full accuracy) */ |
||
792 | + success = read_integer(L, f); |
||
793 | + break; |
||
794 | +#ifdef LNUM_COMPLEX |
||
795 | + case 'c': /* complex */ |
||
796 | + success = read_complex(L, f); |
||
797 | + break; |
||
798 | +#endif |
||
799 | case 'l': /* line */ |
||
800 | success = read_line(L, f); |
||
801 | break; |
||
802 | @@ -415,9 +469,10 @@ static int g_write (lua_State *L, FILE * |
||
803 | int status = 1; |
||
804 | for (; nargs--; arg++) { |
||
805 | if (lua_type(L, arg) == LUA_TNUMBER) { |
||
806 | - /* optimization: could be done exactly as for strings */ |
||
807 | - status = status && |
||
808 | - fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; |
||
809 | + if (lua_isinteger(L,arg)) |
||
810 | + status = status && fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg)) > 0; |
||
811 | + else |
||
812 | + status = status && fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; |
||
813 | } |
||
814 | else { |
||
815 | size_t l; |
||
816 | @@ -460,7 +515,7 @@ static int f_setvbuf (lua_State *L) { |
||
817 | static const char *const modenames[] = {"no", "full", "line", NULL}; |
||
818 | FILE *f = tofile(L); |
||
819 | int op = luaL_checkoption(L, 2, NULL, modenames); |
||
820 | - lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); |
||
821 | + size_t sz = luaL_optint32(L, 3, LUAL_BUFFERSIZE); |
||
822 | int res = setvbuf(f, NULL, mode[op], sz); |
||
823 | return pushresult(L, res == 0, NULL); |
||
824 | } |
||
825 | --- a/src/llex.c |
||
826 | +++ b/src/llex.c |
||
827 | @@ -22,6 +22,7 @@ |
||
828 | #include "lstring.h" |
||
829 | #include "ltable.h" |
||
830 | #include "lzio.h" |
||
831 | +#include "lnum.h" |
||
832 | |||
833 | |||
834 | |||
835 | @@ -34,13 +35,17 @@ |
||
836 | |||
837 | |||
838 | /* ORDER RESERVED */ |
||
839 | -const char *const luaX_tokens [] = { |
||
840 | +static const char *const luaX_tokens [] = { |
||
841 | "and", "break", "do", "else", "elseif", |
||
842 | "end", "false", "for", "function", "if", |
||
843 | "in", "local", "nil", "not", "or", "repeat", |
||
844 | "return", "then", "true", "until", "while", |
||
845 | "..", "...", "==", ">=", "<=", "~=", |
||
846 | "<number>", "<name>", "<string>", "<eof>", |
||
847 | + "<integer>", |
||
848 | +#ifdef LNUM_COMPLEX |
||
849 | + "<number2>", |
||
850 | +#endif |
||
851 | NULL |
||
852 | }; |
||
853 | |||
854 | @@ -90,7 +95,11 @@ static const char *txtToken (LexState *l |
||
855 | switch (token) { |
||
856 | case TK_NAME: |
||
857 | case TK_STRING: |
||
858 | + case TK_INT: |
||
859 | case TK_NUMBER: |
||
860 | +#ifdef LNUM_COMPLEX |
||
861 | + case TK_NUMBER2: |
||
862 | +#endif |
||
863 | save(ls, '\0'); |
||
864 | return luaZ_buffer(ls->buff); |
||
865 | default: |
||
866 | @@ -175,23 +184,27 @@ static void buffreplace (LexState *ls, c |
||
867 | if (p[n] == from) p[n] = to; |
||
868 | } |
||
869 | |||
870 | - |
||
871 | -static void trydecpoint (LexState *ls, SemInfo *seminfo) { |
||
872 | +/* TK_NUMBER (/ TK_NUMBER2) */ |
||
873 | +static int trydecpoint (LexState *ls, SemInfo *seminfo) { |
||
874 | /* format error: try to update decimal point separator */ |
||
875 | struct lconv *cv = localeconv(); |
||
876 | char old = ls->decpoint; |
||
877 | + int ret; |
||
878 | ls->decpoint = (cv ? cv->decimal_point[0] : '.'); |
||
879 | buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ |
||
880 | - if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { |
||
881 | + ret= luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r, NULL); |
||
882 | + if (!ret) { |
||
883 | /* format error with correct decimal point: no more options */ |
||
884 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ |
||
885 | luaX_lexerror(ls, "malformed number", TK_NUMBER); |
||
886 | } |
||
887 | + return ret; |
||
888 | } |
||
889 | |||
890 | |||
891 | -/* LUA_NUMBER */ |
||
892 | -static void read_numeral (LexState *ls, SemInfo *seminfo) { |
||
893 | +/* TK_NUMBER / TK_INT (/TK_NUMBER2) */ |
||
894 | +static int read_numeral (LexState *ls, SemInfo *seminfo) { |
||
895 | + int ret; |
||
896 | lua_assert(isdigit(ls->current)); |
||
897 | do { |
||
898 | save_and_next(ls); |
||
899 | @@ -202,8 +215,9 @@ static void read_numeral (LexState *ls, |
||
900 | save_and_next(ls); |
||
901 | save(ls, '\0'); |
||
902 | buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ |
||
903 | - if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ |
||
904 | - trydecpoint(ls, seminfo); /* try to update decimal point separator */ |
||
905 | + ret= luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r, &seminfo->i ); |
||
906 | + if (!ret) return trydecpoint(ls, seminfo); /* try to update decimal point separator */ |
||
907 | + return ret; |
||
908 | } |
||
909 | |||
910 | |||
911 | @@ -331,6 +345,7 @@ static void read_string (LexState *ls, i |
||
912 | } |
||
913 | |||
914 | |||
915 | +/* char / TK_* */ |
||
916 | static int llex (LexState *ls, SemInfo *seminfo) { |
||
917 | luaZ_resetbuffer(ls->buff); |
||
918 | for (;;) { |
||
919 | @@ -402,8 +417,7 @@ static int llex (LexState *ls, SemInfo * |
||
920 | } |
||
921 | else if (!isdigit(ls->current)) return '.'; |
||
922 | else { |
||
923 | - read_numeral(ls, seminfo); |
||
924 | - return TK_NUMBER; |
||
925 | + return read_numeral(ls, seminfo); |
||
926 | } |
||
927 | } |
||
928 | case EOZ: { |
||
929 | @@ -416,8 +430,7 @@ static int llex (LexState *ls, SemInfo * |
||
930 | continue; |
||
931 | } |
||
932 | else if (isdigit(ls->current)) { |
||
933 | - read_numeral(ls, seminfo); |
||
934 | - return TK_NUMBER; |
||
935 | + return read_numeral(ls, seminfo); |
||
936 | } |
||
937 | else if (isalpha(ls->current) || ls->current == '_') { |
||
938 | /* identifier or reserved word */ |
||
939 | --- a/src/llex.h |
||
940 | +++ b/src/llex.h |
||
941 | @@ -29,19 +29,22 @@ enum RESERVED { |
||
942 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, |
||
943 | /* other terminal symbols */ |
||
944 | TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, |
||
945 | - TK_NAME, TK_STRING, TK_EOS |
||
946 | + TK_NAME, TK_STRING, TK_EOS, TK_INT |
||
947 | +#ifdef LNUM_COMPLEX |
||
948 | + , TK_NUMBER2 /* imaginary constants: Ni */ |
||
949 | +#endif |
||
950 | }; |
||
951 | |||
952 | /* number of reserved words */ |
||
953 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) |
||
954 | |||
955 | |||
956 | -/* array with token `names' */ |
||
957 | -LUAI_DATA const char *const luaX_tokens []; |
||
958 | - |
||
959 | - |
||
960 | +/* SemInfo is a local data structure of 'llex.c', used for carrying a string |
||
961 | + * or a number. A separate token (TK_*) will tell, how to interpret the data. |
||
962 | + */ |
||
963 | typedef union { |
||
964 | lua_Number r; |
||
965 | + lua_Integer i; |
||
966 | TString *ts; |
||
967 | } SemInfo; /* semantics information */ |
||
968 | |||
969 | --- a/src/llimits.h |
||
970 | +++ b/src/llimits.h |
||
971 | @@ -49,6 +49,7 @@ typedef LUAI_USER_ALIGNMENT_T L_Umaxalig |
||
972 | |||
973 | /* result of a `usual argument conversion' over lua_Number */ |
||
974 | typedef LUAI_UACNUMBER l_uacNumber; |
||
975 | +typedef LUAI_UACINTEGER l_uacInteger; |
||
976 | |||
977 | |||
978 | /* internal assertions for in-house debugging */ |
||
979 | @@ -80,7 +81,6 @@ typedef LUAI_UACNUMBER l_uacNumber; |
||
980 | #define cast_int(i) cast(int, (i)) |
||
981 | |||
982 | |||
983 | - |
||
984 | /* |
||
985 | ** type for virtual-machine instructions |
||
986 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) |
||
987 | --- a/src/lmathlib.c |
||
988 | +++ b/src/lmathlib.c |
||
989 | @@ -4,7 +4,6 @@ |
||
990 | ** See Copyright Notice in lua.h |
||
991 | */ |
||
992 | |||
993 | - |
||
994 | #include <stdlib.h> |
||
995 | #include <math.h> |
||
996 | |||
997 | @@ -16,113 +15,210 @@ |
||
998 | #include "lauxlib.h" |
||
999 | #include "lualib.h" |
||
1000 | |||
1001 | +/* 'luai_vectpow()' as a replacement for 'cpow()'. Defined in the header; we |
||
1002 | + * don't intrude the code libs internal functions. |
||
1003 | + */ |
||
1004 | +#ifdef LNUM_COMPLEX |
||
1005 | +# include "lnum.h" |
||
1006 | +#endif |
||
1007 | |||
1008 | #undef PI |
||
1009 | -#define PI (3.14159265358979323846) |
||
1010 | -#define RADIANS_PER_DEGREE (PI/180.0) |
||
1011 | - |
||
1012 | - |
||
1013 | +#ifdef LNUM_FLOAT |
||
1014 | +# define PI (3.14159265358979323846F) |
||
1015 | +#elif defined(M_PI) |
||
1016 | +# define PI M_PI |
||
1017 | +#else |
||
1018 | +# define PI (3.14159265358979323846264338327950288) |
||
1019 | +#endif |
||
1020 | +#define RADIANS_PER_DEGREE (PI/180) |
||
1021 | + |
||
1022 | +#undef HUGE |
||
1023 | +#ifdef LNUM_FLOAT |
||
1024 | +# define HUGE HUGE_VALF |
||
1025 | +#elif defined(LNUM_LDOUBLE) |
||
1026 | +# define HUGE HUGE_VALL |
||
1027 | +#else |
||
1028 | +# define HUGE HUGE_VAL |
||
1029 | +#endif |
||
1030 | |||
1031 | static int math_abs (lua_State *L) { |
||
1032 | - lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); |
||
1033 | +#ifdef LNUM_COMPLEX |
||
1034 | + lua_pushnumber(L, _LF(cabs) (luaL_checkcomplex(L,1))); |
||
1035 | +#else |
||
1036 | + lua_pushnumber(L, _LF(fabs) (luaL_checknumber(L, 1))); |
||
1037 | +#endif |
||
1038 | return 1; |
||
1039 | } |
||
1040 | |||
1041 | static int math_sin (lua_State *L) { |
||
1042 | - lua_pushnumber(L, sin(luaL_checknumber(L, 1))); |
||
1043 | +#ifdef LNUM_COMPLEX |
||
1044 | + lua_pushcomplex(L, _LF(csin) (luaL_checkcomplex(L,1))); |
||
1045 | +#else |
||
1046 | + lua_pushnumber(L, _LF(sin) (luaL_checknumber(L, 1))); |
||
1047 | +#endif |
||
1048 | return 1; |
||
1049 | } |
||
1050 | |||
1051 | static int math_sinh (lua_State *L) { |
||
1052 | - lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); |
||
1053 | +#ifdef LNUM_COMPLEX |
||
1054 | + lua_pushcomplex(L, _LF(csinh) (luaL_checkcomplex(L,1))); |
||
1055 | +#else |
||
1056 | + lua_pushnumber(L, _LF(sinh) (luaL_checknumber(L, 1))); |
||
1057 | +#endif |
||
1058 | return 1; |
||
1059 | } |
||
1060 | |||
1061 | static int math_cos (lua_State *L) { |
||
1062 | - lua_pushnumber(L, cos(luaL_checknumber(L, 1))); |
||
1063 | +#ifdef LNUM_COMPLEX |
||
1064 | + lua_pushcomplex(L, _LF(ccos) (luaL_checkcomplex(L,1))); |
||
1065 | +#else |
||
1066 | + lua_pushnumber(L, _LF(cos) (luaL_checknumber(L, 1))); |
||
1067 | +#endif |
||
1068 | return 1; |
||
1069 | } |
||
1070 | |||
1071 | static int math_cosh (lua_State *L) { |
||
1072 | - lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); |
||
1073 | +#ifdef LNUM_COMPLEX |
||
1074 | + lua_pushcomplex(L, _LF(ccosh) (luaL_checkcomplex(L,1))); |
||
1075 | +#else |
||
1076 | + lua_pushnumber(L, _LF(cosh) (luaL_checknumber(L, 1))); |
||
1077 | +#endif |
||
1078 | return 1; |
||
1079 | } |
||
1080 | |||
1081 | static int math_tan (lua_State *L) { |
||
1082 | - lua_pushnumber(L, tan(luaL_checknumber(L, 1))); |
||
1083 | +#ifdef LNUM_COMPLEX |
||
1084 | + lua_pushcomplex(L, _LF(ctan) (luaL_checkcomplex(L,1))); |
||
1085 | +#else |
||
1086 | + lua_pushnumber(L, _LF(tan) (luaL_checknumber(L, 1))); |
||
1087 | +#endif |
||
1088 | return 1; |
||
1089 | } |
||
1090 | |||
1091 | static int math_tanh (lua_State *L) { |
||
1092 | - lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); |
||
1093 | +#ifdef LNUM_COMPLEX |
||
1094 | + lua_pushcomplex(L, _LF(ctanh) (luaL_checkcomplex(L,1))); |
||
1095 | +#else |
||
1096 | + lua_pushnumber(L, _LF(tanh) (luaL_checknumber(L, 1))); |
||
1097 | +#endif |
||
1098 | return 1; |
||
1099 | } |
||
1100 | |||
1101 | static int math_asin (lua_State *L) { |
||
1102 | - lua_pushnumber(L, asin(luaL_checknumber(L, 1))); |
||
1103 | +#ifdef LNUM_COMPLEX |
||
1104 | + lua_pushcomplex(L, _LF(casin) (luaL_checkcomplex(L,1))); |
||
1105 | +#else |
||
1106 | + lua_pushnumber(L, _LF(asin) (luaL_checknumber(L, 1))); |
||
1107 | +#endif |
||
1108 | return 1; |
||
1109 | } |
||
1110 | |||
1111 | static int math_acos (lua_State *L) { |
||
1112 | - lua_pushnumber(L, acos(luaL_checknumber(L, 1))); |
||
1113 | +#ifdef LNUM_COMPLEX |
||
1114 | + lua_pushcomplex(L, _LF(cacos) (luaL_checkcomplex(L,1))); |
||
1115 | +#else |
||
1116 | + lua_pushnumber(L, _LF(acos) (luaL_checknumber(L, 1))); |
||
1117 | +#endif |
||
1118 | return 1; |
||
1119 | } |
||
1120 | |||
1121 | static int math_atan (lua_State *L) { |
||
1122 | - lua_pushnumber(L, atan(luaL_checknumber(L, 1))); |
||
1123 | +#ifdef LNUM_COMPLEX |
||
1124 | + lua_pushcomplex(L, _LF(catan) (luaL_checkcomplex(L,1))); |
||
1125 | +#else |
||
1126 | + lua_pushnumber(L, _LF(atan) (luaL_checknumber(L, 1))); |
||
1127 | +#endif |
||
1128 | return 1; |
||
1129 | } |
||
1130 | |||
1131 | static int math_atan2 (lua_State *L) { |
||
1132 | - lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); |
||
1133 | + /* scalars only */ |
||
1134 | + lua_pushnumber(L, _LF(atan2) (luaL_checknumber(L, 1), luaL_checknumber(L, 2))); |
||
1135 | return 1; |
||
1136 | } |
||
1137 | |||
1138 | static int math_ceil (lua_State *L) { |
||
1139 | - lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); |
||
1140 | +#ifdef LNUM_COMPLEX |
||
1141 | + lua_Complex v= luaL_checkcomplex(L, 1); |
||
1142 | + lua_pushcomplex(L, _LF(ceil) (_LF(creal)(v)) + _LF(ceil) (_LF(cimag)(v))*I); |
||
1143 | +#else |
||
1144 | + lua_pushnumber(L, _LF(ceil) (luaL_checknumber(L, 1))); |
||
1145 | +#endif |
||
1146 | return 1; |
||
1147 | } |
||
1148 | |||
1149 | static int math_floor (lua_State *L) { |
||
1150 | - lua_pushnumber(L, floor(luaL_checknumber(L, 1))); |
||
1151 | +#ifdef LNUM_COMPLEX |
||
1152 | + lua_Complex v= luaL_checkcomplex(L, 1); |
||
1153 | + lua_pushcomplex(L, _LF(floor) (_LF(creal)(v)) + _LF(floor) (_LF(cimag)(v))*I); |
||
1154 | +#else |
||
1155 | + lua_pushnumber(L, _LF(floor) (luaL_checknumber(L, 1))); |
||
1156 | +#endif |
||
1157 | return 1; |
||
1158 | } |
||
1159 | |||
1160 | -static int math_fmod (lua_State *L) { |
||
1161 | - lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); |
||
1162 | +static int math_fmod (lua_State *L) { |
||
1163 | + /* scalars only */ |
||
1164 | + lua_pushnumber(L, _LF(fmod) (luaL_checknumber(L, 1), luaL_checknumber(L, 2))); |
||
1165 | return 1; |
||
1166 | } |
||
1167 | |||
1168 | static int math_modf (lua_State *L) { |
||
1169 | - double ip; |
||
1170 | - double fp = modf(luaL_checknumber(L, 1), &ip); |
||
1171 | + /* scalars only */ |
||
1172 | + lua_Number ip; |
||
1173 | + lua_Number fp = _LF(modf) (luaL_checknumber(L, 1), &ip); |
||
1174 | lua_pushnumber(L, ip); |
||
1175 | lua_pushnumber(L, fp); |
||
1176 | return 2; |
||
1177 | } |
||
1178 | |||
1179 | static int math_sqrt (lua_State *L) { |
||
1180 | - lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); |
||
1181 | +#ifdef LNUM_COMPLEX |
||
1182 | + lua_pushcomplex(L, _LF(csqrt) (luaL_checkcomplex(L,1))); |
||
1183 | +#else |
||
1184 | + lua_pushnumber(L, _LF(sqrt) (luaL_checknumber(L, 1))); |
||
1185 | +#endif |
||
1186 | return 1; |
||
1187 | } |
||
1188 | |||
1189 | static int math_pow (lua_State *L) { |
||
1190 | - lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); |
||
1191 | +#ifdef LNUM_COMPLEX |
||
1192 | + /* C99 'cpow' gives somewhat inaccurate results (i.e. (-1)^2 = -1+1.2246467991474e-16i). |
||
1193 | + * 'luai_vectpow' smoothens such, reusing it is the reason we need to #include "lnum.h". |
||
1194 | + */ |
||
1195 | + lua_pushcomplex(L, luai_vectpow(luaL_checkcomplex(L,1), luaL_checkcomplex(L,2))); |
||
1196 | +#else |
||
1197 | + lua_pushnumber(L, _LF(pow) (luaL_checknumber(L, 1), luaL_checknumber(L, 2))); |
||
1198 | +#endif |
||
1199 | return 1; |
||
1200 | } |
||
1201 | |||
1202 | static int math_log (lua_State *L) { |
||
1203 | - lua_pushnumber(L, log(luaL_checknumber(L, 1))); |
||
1204 | +#ifdef LNUM_COMPLEX |
||
1205 | + lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1))); |
||
1206 | +#else |
||
1207 | + lua_pushnumber(L, _LF(log) (luaL_checknumber(L, 1))); |
||
1208 | +#endif |
||
1209 | return 1; |
||
1210 | } |
||
1211 | |||
1212 | static int math_log10 (lua_State *L) { |
||
1213 | - lua_pushnumber(L, log10(luaL_checknumber(L, 1))); |
||
1214 | +#ifdef LNUM_COMPLEX |
||
1215 | + /* Not in standard <complex.h> , but easy to calculate: log_a(x) = log_b(x) / log_b(a) |
||
1216 | + */ |
||
1217 | + lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)) / _LF(log) (10)); |
||
1218 | +#else |
||
1219 | + lua_pushnumber(L, _LF(log10) (luaL_checknumber(L, 1))); |
||
1220 | +#endif |
||
1221 | return 1; |
||
1222 | } |
||
1223 | |||
1224 | static int math_exp (lua_State *L) { |
||
1225 | - lua_pushnumber(L, exp(luaL_checknumber(L, 1))); |
||
1226 | +#ifdef LNUM_COMPLEX |
||
1227 | + lua_pushcomplex(L, _LF(cexp) (luaL_checkcomplex(L,1))); |
||
1228 | +#else |
||
1229 | + lua_pushnumber(L, _LF(exp) (luaL_checknumber(L, 1))); |
||
1230 | +#endif |
||
1231 | return 1; |
||
1232 | } |
||
1233 | |||
1234 | @@ -138,19 +234,20 @@ static int math_rad (lua_State *L) { |
||
1235 | |||
1236 | static int math_frexp (lua_State *L) { |
||
1237 | int e; |
||
1238 | - lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); |
||
1239 | + lua_pushnumber(L, _LF(frexp) (luaL_checknumber(L, 1), &e)); |
||
1240 | lua_pushinteger(L, e); |
||
1241 | return 2; |
||
1242 | } |
||
1243 | |||
1244 | static int math_ldexp (lua_State *L) { |
||
1245 | - lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); |
||
1246 | + lua_pushnumber(L, _LF(ldexp) (luaL_checknumber(L, 1), luaL_checkint(L, 2))); |
||
1247 | return 1; |
||
1248 | } |
||
1249 | |||
1250 | |||
1251 | |||
1252 | static int math_min (lua_State *L) { |
||
1253 | + /* scalars only */ |
||
1254 | int n = lua_gettop(L); /* number of arguments */ |
||
1255 | lua_Number dmin = luaL_checknumber(L, 1); |
||
1256 | int i; |
||
1257 | @@ -165,6 +262,7 @@ static int math_min (lua_State *L) { |
||
1258 | |||
1259 | |||
1260 | static int math_max (lua_State *L) { |
||
1261 | + /* scalars only */ |
||
1262 | int n = lua_gettop(L); /* number of arguments */ |
||
1263 | lua_Number dmax = luaL_checknumber(L, 1); |
||
1264 | int i; |
||
1265 | @@ -182,25 +280,20 @@ static int math_random (lua_State *L) { |
||
1266 | /* the `%' avoids the (rare) case of r==1, and is needed also because on |
||
1267 | some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ |
||
1268 | lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; |
||
1269 | - switch (lua_gettop(L)) { /* check number of arguments */ |
||
1270 | - case 0: { /* no arguments */ |
||
1271 | - lua_pushnumber(L, r); /* Number between 0 and 1 */ |
||
1272 | - break; |
||
1273 | - } |
||
1274 | - case 1: { /* only upper limit */ |
||
1275 | - int u = luaL_checkint(L, 1); |
||
1276 | - luaL_argcheck(L, 1<=u, 1, "interval is empty"); |
||
1277 | - lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ |
||
1278 | - break; |
||
1279 | - } |
||
1280 | - case 2: { /* lower and upper limits */ |
||
1281 | - int l = luaL_checkint(L, 1); |
||
1282 | - int u = luaL_checkint(L, 2); |
||
1283 | - luaL_argcheck(L, l<=u, 2, "interval is empty"); |
||
1284 | - lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ |
||
1285 | - break; |
||
1286 | - } |
||
1287 | - default: return luaL_error(L, "wrong number of arguments"); |
||
1288 | + int n= lua_gettop(L); /* number of arguments */ |
||
1289 | + if (n==0) { /* no arguments: range [0,1) */ |
||
1290 | + lua_pushnumber(L, r); |
||
1291 | + } else if (n<=2) { /* int range [1,u] or [l,u] */ |
||
1292 | + int l= n==1 ? 1 : luaL_checkint(L, 1); |
||
1293 | + int u = luaL_checkint(L, n); |
||
1294 | + int tmp; |
||
1295 | + lua_Number d; |
||
1296 | + luaL_argcheck(L, l<=u, n, "interval is empty"); |
||
1297 | + d= _LF(floor)(r*(u-l+1)); |
||
1298 | + lua_number2int(tmp,d); |
||
1299 | + lua_pushinteger(L, l+tmp); |
||
1300 | + } else { |
||
1301 | + return luaL_error(L, "wrong number of arguments"); |
||
1302 | } |
||
1303 | return 1; |
||
1304 | } |
||
1305 | @@ -211,6 +304,66 @@ static int math_randomseed (lua_State *L |
||
1306 | return 0; |
||
1307 | } |
||
1308 | |||
1309 | +/* |
||
1310 | +* Lua 5.1 does not have acosh, asinh, atanh for scalars (not ANSI C) |
||
1311 | +*/ |
||
1312 | +#if __STDC_VERSION__ >= 199901L |
||
1313 | +static int math_acosh (lua_State *L) { |
||
1314 | +# ifdef LNUM_COMPLEX |
||
1315 | + lua_pushcomplex(L, _LF(cacosh) (luaL_checkcomplex(L,1))); |
||
1316 | +# else |
||
1317 | + lua_pushnumber(L, _LF(acosh) (luaL_checknumber(L,1))); |
||
1318 | +# endif |
||
1319 | + return 1; |
||
1320 | +} |
||
1321 | +static int math_asinh (lua_State *L) { |
||
1322 | +# ifdef LNUM_COMPLEX |
||
1323 | + lua_pushcomplex(L, _LF(casinh) (luaL_checkcomplex(L,1))); |
||
1324 | +# else |
||
1325 | + lua_pushnumber(L, _LF(asinh) (luaL_checknumber(L,1))); |
||
1326 | +# endif |
||
1327 | + return 1; |
||
1328 | +} |
||
1329 | +static int math_atanh (lua_State *L) { |
||
1330 | +# ifdef LNUM_COMPLEX |
||
1331 | + lua_pushcomplex(L, _LF(catanh) (luaL_checkcomplex(L,1))); |
||
1332 | +# else |
||
1333 | + lua_pushnumber(L, _LF(atanh) (luaL_checknumber(L,1))); |
||
1334 | +# endif |
||
1335 | + return 1; |
||
1336 | +} |
||
1337 | +#endif |
||
1338 | + |
||
1339 | +/* |
||
1340 | + * C99 complex functions, not covered above. |
||
1341 | +*/ |
||
1342 | +#ifdef LNUM_COMPLEX |
||
1343 | +static int math_arg (lua_State *L) { |
||
1344 | + lua_pushnumber(L, _LF(carg) (luaL_checkcomplex(L,1))); |
||
1345 | + return 1; |
||
1346 | +} |
||
1347 | + |
||
1348 | +static int math_imag (lua_State *L) { |
||
1349 | + lua_pushnumber(L, _LF(cimag) (luaL_checkcomplex(L,1))); |
||
1350 | + return 1; |
||
1351 | +} |
||
1352 | + |
||
1353 | +static int math_real (lua_State *L) { |
||
1354 | + lua_pushnumber(L, _LF(creal) (luaL_checkcomplex(L,1))); |
||
1355 | + return 1; |
||
1356 | +} |
||
1357 | + |
||
1358 | +static int math_conj (lua_State *L) { |
||
1359 | + lua_pushcomplex(L, _LF(conj) (luaL_checkcomplex(L,1))); |
||
1360 | + return 1; |
||
1361 | +} |
||
1362 | + |
||
1363 | +static int math_proj (lua_State *L) { |
||
1364 | + lua_pushcomplex(L, _LF(cproj) (luaL_checkcomplex(L,1))); |
||
1365 | + return 1; |
||
1366 | +} |
||
1367 | +#endif |
||
1368 | + |
||
1369 | |||
1370 | static const luaL_Reg mathlib[] = { |
||
1371 | {"abs", math_abs}, |
||
1372 | @@ -241,6 +394,18 @@ static const luaL_Reg mathlib[] = { |
||
1373 | {"sqrt", math_sqrt}, |
||
1374 | {"tanh", math_tanh}, |
||
1375 | {"tan", math_tan}, |
||
1376 | +#if __STDC_VERSION__ >= 199901L |
||
1377 | + {"acosh", math_acosh}, |
||
1378 | + {"asinh", math_asinh}, |
||
1379 | + {"atanh", math_atanh}, |
||
1380 | +#endif |
||
1381 | +#ifdef LNUM_COMPLEX |
||
1382 | + {"arg", math_arg}, |
||
1383 | + {"imag", math_imag}, |
||
1384 | + {"real", math_real}, |
||
1385 | + {"conj", math_conj}, |
||
1386 | + {"proj", math_proj}, |
||
1387 | +#endif |
||
1388 | {NULL, NULL} |
||
1389 | }; |
||
1390 | |||
1391 | @@ -252,8 +417,10 @@ LUALIB_API int luaopen_math (lua_State * |
||
1392 | luaL_register(L, LUA_MATHLIBNAME, mathlib); |
||
1393 | lua_pushnumber(L, PI); |
||
1394 | lua_setfield(L, -2, "pi"); |
||
1395 | - lua_pushnumber(L, HUGE_VAL); |
||
1396 | + lua_pushnumber(L, HUGE); |
||
1397 | lua_setfield(L, -2, "huge"); |
||
1398 | + lua_pushinteger(L, LUA_INTEGER_MAX ); |
||
1399 | + lua_setfield(L, -2, "hugeint"); |
||
1400 | #if defined(LUA_COMPAT_MOD) |
||
1401 | lua_getfield(L, -1, "fmod"); |
||
1402 | lua_setfield(L, -2, "mod"); |
||
1403 | --- /dev/null |
||
1404 | +++ b/src/lnum.c |
||
1405 | @@ -0,0 +1,312 @@ |
||
1406 | +/* |
||
1407 | +** $Id: lnum.c,v ... $ |
||
1408 | +** Internal number model |
||
1409 | +** See Copyright Notice in lua.h |
||
1410 | +*/ |
||
1411 | + |
||
1412 | +#include <stdlib.h> |
||
1413 | +#include <math.h> |
||
1414 | +#include <ctype.h> |
||
1415 | +#include <string.h> |
||
1416 | +#include <stdio.h> |
||
1417 | +#include <errno.h> |
||
1418 | + |
||
1419 | +#define lnum_c |
||
1420 | +#define LUA_CORE |
||
1421 | + |
||
1422 | +#include "lua.h" |
||
1423 | +#include "llex.h" |
||
1424 | +#include "lnum.h" |
||
1425 | + |
||
1426 | +/* |
||
1427 | +** lua_real2str converts a (non-complex) number to a string. |
||
1428 | +** lua_str2real converts a string to a (non-complex) number. |
||
1429 | +*/ |
||
1430 | +#define lua_real2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) |
||
1431 | + |
||
1432 | +/* |
||
1433 | +* Note: Only 'strtod()' is part of ANSI C; others are C99 and |
||
1434 | +* may need '--std=c99' compiler setting (at least on Ubuntu 7.10). |
||
1435 | +* |
||
1436 | +* Visual C++ 2008 Express does not have 'strtof()', nor 'strtold()'. |
||
1437 | +* References to '_strtold()' exist but don't compile. It seems best |
||
1438 | +* to leave Windows users with DOUBLE only (or compile with MinGW). |
||
1439 | +* |
||
1440 | +* In practise, using '(long double)strtod' is a risky thing, since |
||
1441 | +* it will cause accuracy loss in reading in numbers, and such losses |
||
1442 | +* will pile up in later processing. Get a real 'strtold()' or don't |
||
1443 | +* use that mode at all. |
||
1444 | +*/ |
||
1445 | +#ifdef LNUM_DOUBLE |
||
1446 | +# define lua_str2real strtod |
||
1447 | +#elif defined(LNUM_FLOAT) |
||
1448 | +# define lua_str2real strtof |
||
1449 | +#elif defined(LNUM_LDOUBLE) |
||
1450 | +# define lua_str2real strtold |
||
1451 | +#endif |
||
1452 | + |
||
1453 | +#define lua_integer2str(s,v) sprintf((s), LUA_INTEGER_FMT, (v)) |
||
1454 | + |
||
1455 | +/* 's' is expected to be LUAI_MAXNUMBER2STR long (enough for any number) |
||
1456 | +*/ |
||
1457 | +void luaO_num2buf( char *s, const TValue *o ) |
||
1458 | +{ |
||
1459 | + lua_Number n; |
||
1460 | + lua_assert( ttisnumber(o) ); |
||
1461 | + |
||
1462 | + /* Reason to handle integers differently is not only speed, but accuracy as |
||
1463 | + * well. We want to make any integer tostring() without roundings, at all. |
||
1464 | + */ |
||
1465 | + if (ttisint(o)) { |
||
1466 | + lua_integer2str( s, ivalue(o) ); |
||
1467 | + return; |
||
1468 | + } |
||
1469 | + n= nvalue_fast(o); |
||
1470 | + lua_real2str(s, n); |
||
1471 | + |
||
1472 | +#ifdef LNUM_COMPLEX |
||
1473 | + lua_Number n2= nvalue_img_fast(o); |
||
1474 | + if (n2!=0) { /* Postfix with +-Ni */ |
||
1475 | + int re0= (n == 0); |
||
1476 | + char *s2= re0 ? s : strchr(s,'\0'); |
||
1477 | + if ((!re0) && (n2>0)) *s2++= '+'; |
||
1478 | + lua_real2str( s2, n2 ); |
||
1479 | + strcat(s2,"i"); |
||
1480 | + } |
||
1481 | +#endif |
||
1482 | +} |
||
1483 | + |
||
1484 | +/* |
||
1485 | +* If a LUA_TNUMBER has integer value, give it. |
||
1486 | +*/ |
||
1487 | +int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref ) { |
||
1488 | + lua_Number d; |
||
1489 | + lua_Integer i; |
||
1490 | + |
||
1491 | + lua_assert( ttype(o)==LUA_TNUMBER ); |
||
1492 | + lua_assert( ref ); |
||
1493 | +#ifdef LNUM_COMPLEX |
||
1494 | + if (nvalue_img_fast(o)!=0) return 0; |
||
1495 | +#endif |
||
1496 | + d= nvalue_fast(o); |
||
1497 | + lua_number2integer(i, d); |
||
1498 | + if (cast_num(i) == d) { |
||
1499 | + *ref= i; return 1; |
||
1500 | + } |
||
1501 | + return 0; |
||
1502 | +} |
||
1503 | + |
||
1504 | +/* |
||
1505 | + * Lua 5.1.3 (using 'strtod()') allows 0x+hex but not 0+octal. This is good, |
||
1506 | + * and we should NOT use 'autobase' 0 with 'strtoul[l]()' for this reason. |
||
1507 | + * |
||
1508 | + * Lua 5.1.3 allows '0x...' numbers to overflow and lose precision; this is not |
||
1509 | + * good. On Visual C++ 2008, 'strtod()' does not even take them in. Better to |
||
1510 | + * require hex values to fit 'lua_Integer' or give an error that they don't? |
||
1511 | + * |
||
1512 | + * Full hex range (0 .. 0xff..ff) is stored as integers, not to lose any bits. |
||
1513 | + * Numerical value of 0xff..ff will be -1, if used in calculations. |
||
1514 | + * |
||
1515 | + * Returns: TK_INT for a valid integer, '*endptr_ref' updated |
||
1516 | + * TK_NUMBER for seemingly numeric, to be parsed as floating point |
||
1517 | + * 0 for bad characters, not a number (or '0x' out of range) |
||
1518 | + */ |
||
1519 | +static int luaO_str2i (const char *s, lua_Integer *res, char **endptr_ref) { |
||
1520 | + char *endptr; |
||
1521 | + /* 'v' gets ULONG_MAX on possible overflow (which is > LUA_INTEGER_MAX); |
||
1522 | + * we don't have to check 'errno' here. |
||
1523 | + */ |
||
1524 | + unsigned LUA_INTEGER v= lua_str2ul(s, &endptr, 10); |
||
1525 | + if (endptr == s) return 0; /* nothing numeric */ |
||
1526 | + if (v==0 && *endptr=='x') { |
||
1527 | + errno= 0; /* needs to be set, 'strtoul[l]' does not clear it */ |
||
1528 | + v= lua_str2ul(endptr+1, &endptr, 16); /* retry as hex, unsigned range */ |
||
1529 | + if (errno==ERANGE) { /* clamped to 0xff..ff */ |
||
1530 | +#if (defined(LNUM_INT32) && !defined(LNUM_FLOAT)) || defined(LNUM_LDOUBLE) |
||
1531 | + return TK_NUMBER; /* Allow to be read as floating point (has more integer range) */ |
||
1532 | +#else |
||
1533 | + return 0; /* Reject the number */ |
||
1534 | +#endif |
||
1535 | + } |
||
1536 | + } else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) { |
||
1537 | + return TK_NUMBER; /* not in signed range, or has '.', 'e' etc. trailing */ |
||
1538 | + } |
||
1539 | + *res= (lua_Integer)v; |
||
1540 | + *endptr_ref= endptr; |
||
1541 | + return TK_INT; |
||
1542 | +} |
||
1543 | + |
||
1544 | +/* 0 / TK_NUMBER / TK_INT (/ TK_NUMBER2) */ |
||
1545 | +int luaO_str2d (const char *s, lua_Number *res_n, lua_Integer *res_i) { |
||
1546 | + char *endptr; |
||
1547 | + int ret= TK_NUMBER; |
||
1548 | + /* Check integers first, if caller is allowing. |
||
1549 | + * If 'res2'==NULL, they're only looking for floating point. |
||
1550 | + */ |
||
1551 | + if (res_i) { |
||
1552 | + ret= luaO_str2i(s,res_i,&endptr); |
||
1553 | + if (ret==0) return 0; |
||
1554 | + } |
||
1555 | + if (ret==TK_NUMBER) { |
||
1556 | + lua_assert(res_n); |
||
1557 | + /* Note: Visual C++ 2008 Express 'strtod()' does not read in "0x..." |
||
1558 | + * numbers; it will read '0' and spit 'x' as endptr. |
||
1559 | + * This means hex constants not fitting in 'lua_Integer' won't |
||
1560 | + * be read in at all. What to do? |
||
1561 | + */ |
||
1562 | + *res_n = lua_str2real(s, &endptr); |
||
1563 | + if (endptr == s) return 0; /* conversion failed */ |
||
1564 | + /* Visual C++ 2008 'strtod()' does not allow "0x..." input. */ |
||
1565 | +#if defined(_MSC_VER) && !defined(LNUM_FLOAT) && !defined(LNUM_INT64) |
||
1566 | + if (*res_n==0 && *endptr=='x') { |
||
1567 | + /* Hex constant too big for 'lua_Integer' but that could fit in 'lua_Number' |
||
1568 | + * integer bits |
||
1569 | + */ |
||
1570 | + unsigned __int64 v= _strtoui64( s, &endptr, 16 ); |
||
1571 | + /* We just let > 64 bit values be clamped to _UI64_MAX (MSDN does not say 'errno'==ERANGE would be set) */ |
||
1572 | + *res_n= cast_num(v); |
||
1573 | + if (*res_n != v) return 0; /* Would have lost accuracy */ |
||
1574 | + } |
||
1575 | +#endif |
||
1576 | +#ifdef LNUM_COMPLEX |
||
1577 | + if (*endptr == 'i') { endptr++; ret= TK_NUMBER2; } |
||
1578 | +#endif |
||
1579 | + } |
||
1580 | + if (*endptr) { |
||
1581 | + while (isspace(cast(unsigned char, *endptr))) endptr++; |
||
1582 | + if (*endptr) return 0; /* invalid trail */ |
||
1583 | + } |
||
1584 | + return ret; |
||
1585 | +} |
||
1586 | + |
||
1587 | + |
||
1588 | +/* Functions for finding out, when integer operations remain in range |
||
1589 | + * (and doing them). |
||
1590 | + */ |
||
1591 | +int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { |
||
1592 | + lua_Integer v= ib+ic; /* may overflow */ |
||
1593 | + if (ib>0 && ic>0) { if (v < 0) return 0; /*overflow, use floats*/ } |
||
1594 | + else if (ib<0 && ic<0) { if (v >= 0) return 0; } |
||
1595 | + *r= v; |
||
1596 | + return 1; |
||
1597 | +} |
||
1598 | + |
||
1599 | +int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { |
||
1600 | + lua_Integer v= ib-ic; /* may overflow */ |
||
1601 | + if (ib>=0 && ic<0) { if (v < 0) return 0; /*overflow, use floats*/ } |
||
1602 | + else if (ib<0 && ic>0) { if (v >= 0) return 0; } |
||
1603 | + *r= v; |
||
1604 | + return 1; |
||
1605 | +} |
||
1606 | + |
||
1607 | +int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { |
||
1608 | + if (ib!=LUA_INTEGER_MIN && ic!=LUA_INTEGER_MIN) { |
||
1609 | + lua_Integer b= luai_abs(ib), c= luai_abs(ic); |
||
1610 | + if ( (ib==0) || (LUA_INTEGER_MAX/b >= c) ) { |
||
1611 | + *r= ib*ic; /* no overflow */ |
||
1612 | + return 1; |
||
1613 | + } |
||
1614 | + } else if (ib==0 || ic==0) { |
||
1615 | + *r= 0; return 1; |
||
1616 | + } |
||
1617 | + |
||
1618 | + /* Result can be LUA_INTEGER_MIN; if it is, calculating it using floating |
||
1619 | + * point will not cause accuracy loss. |
||
1620 | + */ |
||
1621 | + if ( luai_nummul( cast_num(ib), cast_num(ic) ) == LUA_INTEGER_MIN ) { |
||
1622 | + *r= LUA_INTEGER_MIN; |
||
1623 | + return 1; |
||
1624 | + } |
||
1625 | + return 0; |
||
1626 | +} |
||
1627 | + |
||
1628 | +int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { |
||
1629 | + /* N/0: leave to float side, to give an error |
||
1630 | + */ |
||
1631 | + if (ic==0) return 0; |
||
1632 | + |
||
1633 | + /* N/LUA_INTEGER_MIN: always non-integer results, or 0 or +1 |
||
1634 | + */ |
||
1635 | + if (ic==LUA_INTEGER_MIN) { |
||
1636 | + if (ib==LUA_INTEGER_MIN) { *r=1; return 1; } |
||
1637 | + if (ib==0) { *r=0; return 1; } |
||
1638 | + |
||
1639 | + /* LUA_INTEGER_MIN (-2^31|63)/N: calculate using float side (either the division |
||
1640 | + * causes non-integer results, or there is no accuracy loss in int->fp->int |
||
1641 | + * conversions (N=2,4,8,..,256 and N=2^30,2^29,..2^23). |
||
1642 | + */ |
||
1643 | + } else if (ib==LUA_INTEGER_MIN) { |
||
1644 | + lua_Number d= luai_numdiv( cast_num(LUA_INTEGER_MIN), cast_num(ic) ); |
||
1645 | + lua_Integer i; lua_number2integer(i,d); |
||
1646 | + if (cast_num(i)==d) { *r= i; return 1; } |
||
1647 | + |
||
1648 | + } else { |
||
1649 | + /* Note: We _can_ use ANSI C mod here, even on negative values, since |
||
1650 | + * we only test for == 0 (the sign would be implementation dependent). |
||
1651 | + */ |
||
1652 | + if (ib%ic == 0) { *r= ib/ic; return 1; } |
||
1653 | + } |
||
1654 | + |
||
1655 | + return 0; |
||
1656 | +} |
||
1657 | + |
||
1658 | +int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { |
||
1659 | + if (ic!=0) { |
||
1660 | + /* ANSI C can be trusted when b%c==0, or when values are non-negative. |
||
1661 | + * b - (floor(b/c) * c) |
||
1662 | + * --> |
||
1663 | + * + +: b - (b/c) * c (b % c can be used) |
||
1664 | + * - -: b - (b/c) * c (b % c could work, but not defined by ANSI C) |
||
1665 | + * 0 -: b - (b/c) * c (=0, b % c could work, but not defined by ANSI C) |
||
1666 | + * - +: b - (b/c-1) * c (when b!=-c) |
||
1667 | + * + -: b - (b/c-1) * c (when b!=-c) |
||
1668 | + * |
||
1669 | + * o MIN%MIN ends up 0, via overflow in calcs but that does not matter. |
||
1670 | + * o MIN%MAX ends up MAX-1 (and other such numbers), also after overflow, |
||
1671 | + * but that does not matter, results do. |
||
1672 | + */ |
||
1673 | + lua_Integer v= ib % ic; |
||
1674 | + if ( v!=0 && (ib<0 || ic<0) ) { |
||
1675 | + v= ib - ((ib/ic) - ((ib<=0 && ic<0) ? 0:1)) * ic; |
||
1676 | + } |
||
1677 | + /* Result should always have same sign as 2nd argument. (PIL2) */ |
||
1678 | + lua_assert( (v<0) ? (ic<0) : (v>0) ? (ic>0) : 1 ); |
||
1679 | + *r= v; |
||
1680 | + return 1; |
||
1681 | + } |
||
1682 | + return 0; /* let float side return NaN */ |
||
1683 | +} |
||
1684 | + |
||
1685 | +int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { |
||
1686 | + |
||
1687 | + /* In FLOAT/INT32 or FLOAT|DOUBLE/INT64 modes, calculating integer powers |
||
1688 | + * via FP realm may lose accuracy (i.e. 7^11 = 1977326743, which fits int32 |
||
1689 | + * but not 23-bit float mantissa). |
||
1690 | + * |
||
1691 | + * The current solution is dumb, but it works and uses little code. Use of |
||
1692 | + * integer powers is not anticipated to be very frequent (apart from 2^x, |
||
1693 | + * which is separately optimized). |
||
1694 | + */ |
||
1695 | + if (ib==0) *r=0; |
||
1696 | + else if (ic<0) return 0; /* FP realm */ |
||
1697 | + else if (ib==2 && ic < (int)sizeof(lua_Integer)*8-1) *r= ((lua_Integer)1)<<ic; /* 1,2,4,...2^30 | 2^62 optimization */ |
||
1698 | + else if (ic==0) *r=1; |
||
1699 | + else if (luai_abs(ib)==1) *r= (ic%2) ? ib:1; |
||
1700 | + else { |
||
1701 | + lua_Integer x= ib; |
||
1702 | + while( --ic ) { |
||
1703 | + if (!try_mulint( &x, x, ib )) |
||
1704 | + return 0; /* FP realm */ |
||
1705 | + } |
||
1706 | + *r= x; |
||
1707 | + } |
||
1708 | + return 1; |
||
1709 | +} |
||
1710 | + |
||
1711 | +int try_unmint( lua_Integer *r, lua_Integer ib ) { |
||
1712 | + /* Negating LUA_INTEGER_MIN leaves the range. */ |
||
1713 | + if ( ib != LUA_INTEGER_MIN ) |
||
1714 | + { *r= -ib; return 1; } |
||
1715 | + return 0; |
||
1716 | +} |
||
1717 | + |
||
1718 | --- /dev/null |
||
1719 | +++ b/src/lnum.h |
||
1720 | @@ -0,0 +1,116 @@ |
||
1721 | +/* |
||
1722 | +** $Id: lnum.h,v ... $ |
||
1723 | +** Internal Number model |
||
1724 | +** See Copyright Notice in lua.h |
||
1725 | +*/ |
||
1726 | + |
||
1727 | +#ifndef lnum_h |
||
1728 | +#define lnum_h |
||
1729 | + |
||
1730 | +#include <math.h> |
||
1731 | + |
||
1732 | +#include "lobject.h" |
||
1733 | + |
||
1734 | +/* |
||
1735 | +** The luai_num* macros define the primitive operations over 'lua_Number's |
||
1736 | +** (not 'lua_Integer's, not 'lua_Complex'). |
||
1737 | +*/ |
||
1738 | +#define luai_numadd(a,b) ((a)+(b)) |
||
1739 | +#define luai_numsub(a,b) ((a)-(b)) |
||
1740 | +#define luai_nummul(a,b) ((a)*(b)) |
||
1741 | +#define luai_numdiv(a,b) ((a)/(b)) |
||
1742 | +#define luai_nummod(a,b) ((a) - _LF(floor)((a)/(b))*(b)) |
||
1743 | +#define luai_numpow(a,b) (_LF(pow)(a,b)) |
||
1744 | +#define luai_numunm(a) (-(a)) |
||
1745 | +#define luai_numeq(a,b) ((a)==(b)) |
||
1746 | +#define luai_numlt(a,b) ((a)<(b)) |
||
1747 | +#define luai_numle(a,b) ((a)<=(b)) |
||
1748 | +#define luai_numisnan(a) (!luai_numeq((a), (a))) |
||
1749 | + |
||
1750 | +int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); |
||
1751 | +int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); |
||
1752 | +int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); |
||
1753 | +int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); |
||
1754 | +int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); |
||
1755 | +int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); |
||
1756 | +int try_unmint( lua_Integer *r, lua_Integer ib ); |
||
1757 | + |
||
1758 | +#ifdef LNUM_COMPLEX |
||
1759 | + static inline lua_Complex luai_vectunm( lua_Complex a ) { return -a; } |
||
1760 | + static inline lua_Complex luai_vectadd( lua_Complex a, lua_Complex b ) { return a+b; } |
||
1761 | + static inline lua_Complex luai_vectsub( lua_Complex a, lua_Complex b ) { return a-b; } |
||
1762 | + static inline lua_Complex luai_vectmul( lua_Complex a, lua_Complex b ) { return a*b; } |
||
1763 | + static inline lua_Complex luai_vectdiv( lua_Complex a, lua_Complex b ) { return a/b; } |
||
1764 | + |
||
1765 | +/* |
||
1766 | + * C99 does not provide modulus for complex numbers. It most likely is not |
||
1767 | + * meaningful at all. |
||
1768 | + */ |
||
1769 | + |
||
1770 | +/* |
||
1771 | + * Complex power |
||
1772 | + * |
||
1773 | + * C99 'cpow' gives inaccurate results for many common cases s.a. (1i)^2 -> |
||
1774 | + * -1+1.2246467991474e-16i (OS X 10.4, gcc 4.0.1 build 5367) |
||
1775 | + * |
||
1776 | + * [(a+bi)^(c+di)] = (r^c) * exp(-d*t) * cos(c*t + d*ln(r)) + |
||
1777 | + * = (r^c) * exp(-d*t) * sin(c*t + d*ln(r)) *i |
||
1778 | + * r = sqrt(a^2+b^2), t = arctan( b/a ) |
||
1779 | + * |
||
1780 | + * Reference: <http://home.att.net/~srschmitt/complexnumbers.html> |
||
1781 | + * Could also be calculated using: x^y = exp(ln(x)*y) |
||
1782 | + * |
||
1783 | + * Note: Defined here (and not in .c) so 'lmathlib.c' can share the |
||
1784 | + * implementation. |
||
1785 | + */ |
||
1786 | + static inline |
||
1787 | + lua_Complex luai_vectpow( lua_Complex a, lua_Complex b ) |
||
1788 | + { |
||
1789 | +# if 1 |
||
1790 | + lua_Number ar= _LF(creal)(a), ai= _LF(cimag)(a); |
||
1791 | + lua_Number br= _LF(creal)(b), bi= _LF(cimag)(b); |
||
1792 | + |
||
1793 | + if (ai==0 && bi==0) { /* a^c (real) */ |
||
1794 | + return luai_numpow( ar, br ); |
||
1795 | + } |
||
1796 | + |
||
1797 | + int br_int= (int)br; |
||
1798 | + |
||
1799 | + if ( ai!=0 && bi==0 && br_int==br && br_int!=0 && br_int!=INT_MIN ) { |
||
1800 | + /* (a+bi)^N, N = { +-1,+-2, ... +-INT_MAX } |
||
1801 | + */ |
||
1802 | + lua_Number k= luai_numpow( _LF(sqrt) (ar*ar + ai*ai), br ); |
||
1803 | + lua_Number cos_z, sin_z; |
||
1804 | + |
||
1805 | + /* Situation depends upon c (N) in the following manner: |
||
1806 | + * |
||
1807 | + * N%4==0 => cos(c*t)=1, sin(c*t)=0 |
||
1808 | + * (N*sign(b))%4==1 or (N*sign(b))%4==-3 => cos(c*t)=0, sin(c*t)=1 |
||
1809 | + * N%4==2 or N%4==-2 => cos(c*t)=-1, sin(c*t)=0 |
||
1810 | + * (N*sign(b))%4==-1 or (N*sign(b))%4==3 => cos(c*t)=0, sin(c*t)=-1 |
||
1811 | + */ |
||
1812 | + int br_int_abs = br_int<0 ? -br_int:br_int; |
||
1813 | + |
||
1814 | + switch( (br_int_abs%4) * (br_int<0 ? -1:1) * (ai<0 ? -1:1) ) { |
||
1815 | + case 0: cos_z=1, sin_z=0; break; |
||
1816 | + case 2: case -2: cos_z=-1, sin_z=0; break; |
||
1817 | + case 1: case -3: cos_z=0, sin_z=1; break; |
||
1818 | + case 3: case -1: cos_z=0, sin_z=-1; break; |
||
1819 | + default: lua_assert(0); return 0; |
||
1820 | + } |
||
1821 | + return k*cos_z + (k*sin_z)*I; |
||
1822 | + } |
||
1823 | +# endif |
||
1824 | + return _LF(cpow) ( a, b ); |
||
1825 | + } |
||
1826 | +#endif |
||
1827 | + |
||
1828 | +LUAI_FUNC int luaO_str2d (const char *s, lua_Number *res1, lua_Integer *res2); |
||
1829 | +LUAI_FUNC void luaO_num2buf( char *s, const TValue *o ); |
||
1830 | + |
||
1831 | +LUAI_FUNC int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref ); |
||
1832 | + |
||
1833 | +#define luai_normalize(o) \ |
||
1834 | +{ lua_Integer _i; if (tt_integer_valued(o,&_i)) setivalue(o,_i); } |
||
1835 | + |
||
1836 | +#endif |
||
1837 | --- /dev/null |
||
1838 | +++ b/src/lnum_config.h |
||
1839 | @@ -0,0 +1,221 @@ |
||
1840 | +/* |
||
1841 | +** $Id: lnum_config.h,v ... $ |
||
1842 | +** Internal Number model |
||
1843 | +** See Copyright Notice in lua.h |
||
1844 | +*/ |
||
1845 | + |
||
1846 | +#ifndef lnum_config_h |
||
1847 | +#define lnum_config_h |
||
1848 | + |
||
1849 | +/* |
||
1850 | +** Default number modes |
||
1851 | +*/ |
||
1852 | +#if (!defined LNUM_DOUBLE) && (!defined LNUM_FLOAT) && (!defined LNUM_LDOUBLE) |
||
1853 | +# define LNUM_FLOAT |
||
1854 | +#endif |
||
1855 | +#if (!defined LNUM_INT16) && (!defined LNUM_INT32) && (!defined LNUM_INT64) |
||
1856 | +# define LNUM_INT32 |
||
1857 | +#endif |
||
1858 | + |
||
1859 | +/* |
||
1860 | +** Require C99 mode for COMPLEX, FLOAT and LDOUBLE (only DOUBLE is ANSI C). |
||
1861 | +*/ |
||
1862 | +#if defined(LNUM_COMPLEX) && (__STDC_VERSION__ < 199901L) |
||
1863 | +# error "Need C99 for complex (use '--std=c99' or similar)" |
||
1864 | +#elif defined(LNUM_LDOUBLE) && (__STDC_VERSION__ < 199901L) && !defined(_MSC_VER) |
||
1865 | +# error "Need C99 for 'long double' (use '--std=c99' or similar)" |
||
1866 | +#elif defined(LNUM_FLOAT) && (__STDC_VERSION__ < 199901L) |
||
1867 | +/* LNUM_FLOAT not supported on Windows */ |
||
1868 | +# error "Need C99 for 'float' (use '--std=c99' or similar)" |
||
1869 | +#endif |
||
1870 | + |
||
1871 | +/* |
||
1872 | +** Number mode identifier to accompany the version string. |
||
1873 | +*/ |
||
1874 | +#ifdef LNUM_COMPLEX |
||
1875 | +# define _LNUM1 "complex " |
||
1876 | +#else |
||
1877 | +# define _LNUM1 "" |
||
1878 | +#endif |
||
1879 | +#ifdef LNUM_DOUBLE |
||
1880 | +# define _LNUM2 "double" |
||
1881 | +#elif defined(LNUM_FLOAT) |
||
1882 | +# define _LNUM2 "float" |
||
1883 | +#elif defined(LNUM_LDOUBLE) |
||
1884 | +# define _LNUM2 "ldouble" |
||
1885 | +#endif |
||
1886 | +#ifdef LNUM_INT32 |
||
1887 | +# define _LNUM3 "int32" |
||
1888 | +#elif defined(LNUM_INT64) |
||
1889 | +# define _LNUM3 "int64" |
||
1890 | +#elif defined(LNUM_INT16) |
||
1891 | +# define _LNUM3 "int16" |
||
1892 | +#endif |
||
1893 | +#define LUA_LNUM _LNUM1 _LNUM2 " " _LNUM3 |
||
1894 | + |
||
1895 | +/* |
||
1896 | +** LUA_NUMBER is the type of floating point number in Lua |
||
1897 | +** LUA_NUMBER_SCAN is the format for reading numbers. |
||
1898 | +** LUA_NUMBER_FMT is the format for writing numbers. |
||
1899 | +*/ |
||
1900 | +#ifdef LNUM_FLOAT |
||
1901 | +# define LUA_NUMBER float |
||
1902 | +# define LUA_NUMBER_SCAN "%f" |
||
1903 | +# define LUA_NUMBER_FMT "%g" |
||
1904 | +#elif (defined LNUM_DOUBLE) |
||
1905 | +# define LUA_NUMBER double |
||
1906 | +# define LUA_NUMBER_SCAN "%lf" |
||
1907 | +# define LUA_NUMBER_FMT "%.14g" |
||
1908 | +#elif (defined LNUM_LDOUBLE) |
||
1909 | +# define LUA_NUMBER long double |
||
1910 | +# define LUA_NUMBER_SCAN "%Lg" |
||
1911 | +# define LUA_NUMBER_FMT "%.20Lg" |
||
1912 | +#endif |
||
1913 | + |
||
1914 | + |
||
1915 | +/* |
||
1916 | +** LUAI_MAXNUMBER2STR: size of a buffer fitting any number->string result. |
||
1917 | +** |
||
1918 | +** double: 24 (sign, x.xxxxxxxxxxxxxxe+nnnn, and \0) |
||
1919 | +** int64: 21 (19 digits, sign, and \0) |
||
1920 | +** long double: 43 for 128-bit (sign, x.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe+nnnn, and \0) |
||
1921 | +** 30 for 80-bit (sign, x.xxxxxxxxxxxxxxxxxxxxe+nnnn, and \0) |
||
1922 | +*/ |
||
1923 | +#ifdef LNUM_LDOUBLE |
||
1924 | +# define _LUAI_MN2S 44 |
||
1925 | +#else |
||
1926 | +# define _LUAI_MN2S 24 |
||
1927 | +#endif |
||
1928 | + |
||
1929 | +#ifdef LNUM_COMPLEX |
||
1930 | +# define LUAI_MAXNUMBER2STR (2*_LUAI_MN2S) |
||
1931 | +#else |
||
1932 | +# define LUAI_MAXNUMBER2STR _LUAI_MN2S |
||
1933 | +#endif |
||
1934 | + |
||
1935 | +/* |
||
1936 | +** LUA_INTEGER is the integer type used by lua_pushinteger/lua_tointeger/lua_isinteger. |
||
1937 | +** LUA_INTEGER_SCAN is the format for reading integers |
||
1938 | +** LUA_INTEGER_FMT is the format for writing integers |
||
1939 | +** |
||
1940 | +** Note: Visual C++ 2005 does not have 'strtoull()', use '_strtoui64()' instead. |
||
1941 | +*/ |
||
1942 | +#ifdef LNUM_INT32 |
||
1943 | +# if LUAI_BITSINT > 16 |
||
1944 | +# define LUA_INTEGER int |
||
1945 | +# define LUA_INTEGER_SCAN "%d" |
||
1946 | +# define LUA_INTEGER_FMT "%d" |
||
1947 | +# else |
||
1948 | +/* Note: 'LUA_INTEGER' being 'ptrdiff_t' (as in Lua 5.1) causes problems with |
||
1949 | + * 'printf()' operations. Also 'unsigned ptrdiff_t' is invalid. |
||
1950 | + */ |
||
1951 | +# define LUA_INTEGER long |
||
1952 | +# define LUA_INTEGER_SCAN "%ld" |
||
1953 | +# define LUA_INTEGER_FMT "%ld" |
||
1954 | +# endif |
||
1955 | +# define LUA_INTEGER_MAX 0x7FFFFFFF /* 2^31-1 */ |
||
1956 | +/* */ |
||
1957 | +#elif defined(LNUM_INT64) |
||
1958 | +# define LUA_INTEGER long long |
||
1959 | +# ifdef _MSC_VER |
||
1960 | +# define lua_str2ul _strtoui64 |
||
1961 | +# else |
||
1962 | +# define lua_str2ul strtoull |
||
1963 | +# endif |
||
1964 | +# define LUA_INTEGER_SCAN "%lld" |
||
1965 | +# define LUA_INTEGER_FMT "%lld" |
||
1966 | +# define LUA_INTEGER_MAX 0x7fffffffffffffffLL /* 2^63-1 */ |
||
1967 | +# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX - 1LL) /* -2^63 */ |
||
1968 | +/* */ |
||
1969 | +#elif defined(LNUM_INT16) |
||
1970 | +# if LUAI_BITSINT > 16 |
||
1971 | +# define LUA_INTEGER short |
||
1972 | +# define LUA_INTEGER_SCAN "%hd" |
||
1973 | +# define LUA_INTEGER_FMT "%hd" |
||
1974 | +# else |
||
1975 | +# define LUA_INTEGER int |
||
1976 | +# define LUA_INTEGER_SCAN "%d" |
||
1977 | +# define LUA_INTEGER_FMT "%d" |
||
1978 | +# endif |
||
1979 | +# define LUA_INTEGER_MAX 0x7FFF /* 2^16-1 */ |
||
1980 | +#endif |
||
1981 | + |
||
1982 | +#ifndef lua_str2ul |
||
1983 | +# define lua_str2ul (unsigned LUA_INTEGER)strtoul |
||
1984 | +#endif |
||
1985 | +#ifndef LUA_INTEGER_MIN |
||
1986 | +# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */ |
||
1987 | +#endif |
||
1988 | + |
||
1989 | +/* |
||
1990 | +@@ lua_number2int is a macro to convert lua_Number to int. |
||
1991 | +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. |
||
1992 | +** CHANGE them if you know a faster way to convert a lua_Number to |
||
1993 | +** int (with any rounding method and without throwing errors) in your |
||
1994 | +** system. In Pentium machines, a naive typecast from double to int |
||
1995 | +** in C is extremely slow, so any alternative is worth trying. |
||
1996 | +*/ |
||
1997 | + |
||
1998 | +/* On a Pentium, resort to a trick */ |
||
1999 | +#if defined(LNUM_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ |
||
2000 | + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) |
||
2001 | + |
||
2002 | +/* On a Microsoft compiler, use assembler */ |
||
2003 | +# if defined(_MSC_VER) |
||
2004 | +# define lua_number2int(i,d) __asm fld d __asm fistp i |
||
2005 | +# else |
||
2006 | + |
||
2007 | +/* the next trick should work on any Pentium, but sometimes clashes |
||
2008 | + with a DirectX idiosyncrasy */ |
||
2009 | +union luai_Cast { double l_d; long l_l; }; |
||
2010 | +# define lua_number2int(i,d) \ |
||
2011 | + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } |
||
2012 | +# endif |
||
2013 | + |
||
2014 | +# ifndef LNUM_INT64 |
||
2015 | +# define lua_number2integer lua_number2int |
||
2016 | +# endif |
||
2017 | + |
||
2018 | +/* this option always works, but may be slow */ |
||
2019 | +#else |
||
2020 | +# define lua_number2int(i,d) ((i)=(int)(d)) |
||
2021 | +#endif |
||
2022 | + |
||
2023 | +/* Note: Some compilers (OS X gcc 4.0?) may choke on double->long long conversion |
||
2024 | + * since it can lose precision. Others do require 'long long' there. |
||
2025 | + */ |
||
2026 | +#ifndef lua_number2integer |
||
2027 | +# define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) |
||
2028 | +#endif |
||
2029 | + |
||
2030 | +/* |
||
2031 | +** 'luai_abs()' to give absolute value of 'lua_Integer' |
||
2032 | +*/ |
||
2033 | +#ifdef LNUM_INT32 |
||
2034 | +# define luai_abs abs |
||
2035 | +#elif defined(LNUM_INT64) && (__STDC_VERSION__ >= 199901L) |
||
2036 | +# define luai_abs llabs |
||
2037 | +#else |
||
2038 | +# define luai_abs(v) ((v) >= 0 ? (v) : -(v)) |
||
2039 | +#endif |
||
2040 | + |
||
2041 | +/* |
||
2042 | +** LUAI_UACNUMBER is the result of an 'usual argument conversion' over a number. |
||
2043 | +** LUAI_UACINTEGER the same, over an integer. |
||
2044 | +*/ |
||
2045 | +#define LUAI_UACNUMBER double |
||
2046 | +#define LUAI_UACINTEGER long |
||
2047 | + |
||
2048 | +/* ANSI C only has math funcs for 'double. C99 required for float and long double |
||
2049 | + * variants. |
||
2050 | + */ |
||
2051 | +#ifdef LNUM_DOUBLE |
||
2052 | +# define _LF(name) name |
||
2053 | +#elif defined(LNUM_FLOAT) |
||
2054 | +# define _LF(name) name ## f |
||
2055 | +#elif defined(LNUM_LDOUBLE) |
||
2056 | +# define _LF(name) name ## l |
||
2057 | +#endif |
||
2058 | + |
||
2059 | +#endif |
||
2060 | + |
||
2061 | --- a/src/lobject.c |
||
2062 | +++ b/src/lobject.c |
||
2063 | @@ -21,7 +21,8 @@ |
||
2064 | #include "lstate.h" |
||
2065 | #include "lstring.h" |
||
2066 | #include "lvm.h" |
||
2067 | - |
||
2068 | +#include "llex.h" |
||
2069 | +#include "lnum.h" |
||
2070 | |||
2071 | |||
2072 | const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; |
||
2073 | @@ -70,12 +71,31 @@ int luaO_log2 (unsigned int x) { |
||
2074 | |||
2075 | |||
2076 | int luaO_rawequalObj (const TValue *t1, const TValue *t2) { |
||
2077 | - if (ttype(t1) != ttype(t2)) return 0; |
||
2078 | + if (!ttype_ext_same(t1,t2)) return 0; |
||
2079 | else switch (ttype(t1)) { |
||
2080 | case LUA_TNIL: |
||
2081 | return 1; |
||
2082 | + case LUA_TINT: |
||
2083 | + if (ttype(t2)==LUA_TINT) |
||
2084 | + return ivalue(t1) == ivalue(t2); |
||
2085 | + else { /* t1:int, t2:num */ |
||
2086 | +#ifdef LNUM_COMPLEX |
||
2087 | + if (nvalue_img_fast(t2) != 0) return 0; |
||
2088 | +#endif |
||
2089 | + /* Avoid doing accuracy losing cast, if possible. */ |
||
2090 | + lua_Integer tmp; |
||
2091 | + if (tt_integer_valued(t2,&tmp)) |
||
2092 | + return ivalue(t1) == tmp; |
||
2093 | + else |
||
2094 | + return luai_numeq( cast_num(ivalue(t1)), nvalue_fast(t2) ); |
||
2095 | + } |
||
2096 | case LUA_TNUMBER: |
||
2097 | - return luai_numeq(nvalue(t1), nvalue(t2)); |
||
2098 | + if (ttype(t2)==LUA_TINT) |
||
2099 | + return luaO_rawequalObj(t2, t1); /* swap LUA_TINT to left */ |
||
2100 | +#ifdef LNUM_COMPLEX |
||
2101 | + if (!luai_numeq(nvalue_img_fast(t1), nvalue_img_fast(t2))) return 0; |
||
2102 | +#endif |
||
2103 | + return luai_numeq(nvalue_fast(t1), nvalue_fast(t2)); |
||
2104 | case LUA_TBOOLEAN: |
||
2105 | return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ |
||
2106 | case LUA_TLIGHTUSERDATA: |
||
2107 | @@ -86,21 +106,6 @@ int luaO_rawequalObj (const TValue *t1, |
||
2108 | } |
||
2109 | } |
||
2110 | |||
2111 | - |
||
2112 | -int luaO_str2d (const char *s, lua_Number *result) { |
||
2113 | - char *endptr; |
||
2114 | - *result = lua_str2number(s, &endptr); |
||
2115 | - if (endptr == s) return 0; /* conversion failed */ |
||
2116 | - if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ |
||
2117 | - *result = cast_num(strtoul(s, &endptr, 16)); |
||
2118 | - if (*endptr == '\0') return 1; /* most common case */ |
||
2119 | - while (isspace(cast(unsigned char, *endptr))) endptr++; |
||
2120 | - if (*endptr != '\0') return 0; /* invalid trailing characters? */ |
||
2121 | - return 1; |
||
2122 | -} |
||
2123 | - |
||
2124 | - |
||
2125 | - |
||
2126 | static void pushstr (lua_State *L, const char *str) { |
||
2127 | setsvalue2s(L, L->top, luaS_new(L, str)); |
||
2128 | incr_top(L); |
||
2129 | @@ -131,7 +136,11 @@ const char *luaO_pushvfstring (lua_State |
||
2130 | break; |
||
2131 | } |
||
2132 | case 'd': { |
||
2133 | - setnvalue(L->top, cast_num(va_arg(argp, int))); |
||
2134 | + /* This is tricky for 64-bit integers; maybe they even cannot be |
||
2135 | + * supported on all compilers; depends on the conversions applied to |
||
2136 | + * variable argument lists. TBD: test! |
||
2137 | + */ |
||
2138 | + setivalue(L->top, (lua_Integer) va_arg(argp, l_uacInteger)); |
||
2139 | incr_top(L); |
||
2140 | break; |
||
2141 | } |
||
2142 | @@ -212,3 +221,4 @@ void luaO_chunkid (char *out, const char |
||
2143 | } |
||
2144 | } |
||
2145 | } |
||
2146 | + |
||
2147 | --- a/src/lobject.h |
||
2148 | +++ b/src/lobject.h |
||
2149 | @@ -17,7 +17,11 @@ |
||
2150 | |||
2151 | |||
2152 | /* tags for values visible from Lua */ |
||
2153 | -#define LAST_TAG LUA_TTHREAD |
||
2154 | +#if LUA_TINT > LUA_TTHREAD |
||
2155 | +# define LAST_TAG LUA_TINT |
||
2156 | +#else |
||
2157 | +# define LAST_TAG LUA_TTHREAD |
||
2158 | +#endif |
||
2159 | |||
2160 | #define NUM_TAGS (LAST_TAG+1) |
||
2161 | |||
2162 | @@ -59,7 +63,12 @@ typedef struct GCheader { |
||
2163 | typedef union { |
||
2164 | GCObject *gc; |
||
2165 | void *p; |
||
2166 | +#ifdef LNUM_COMPLEX |
||
2167 | + lua_Complex n; |
||
2168 | +#else |
||
2169 | lua_Number n; |
||
2170 | +#endif |
||
2171 | + lua_Integer i; |
||
2172 | int b; |
||
2173 | } Value; |
||
2174 | |||
2175 | @@ -77,7 +86,11 @@ typedef struct lua_TValue { |
||
2176 | |||
2177 | /* Macros to test type */ |
||
2178 | #define ttisnil(o) (ttype(o) == LUA_TNIL) |
||
2179 | -#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) |
||
2180 | +#define ttisint(o) (ttype(o) == LUA_TINT) |
||
2181 | +#define ttisnumber(o) ((ttype(o) == LUA_TINT) || (ttype(o) == LUA_TNUMBER)) |
||
2182 | +#ifdef LNUM_COMPLEX |
||
2183 | +# define ttiscomplex(o) ((ttype(o) == LUA_TNUMBER) && (nvalue_img_fast(o)!=0)) |
||
2184 | +#endif |
||
2185 | #define ttisstring(o) (ttype(o) == LUA_TSTRING) |
||
2186 | #define ttistable(o) (ttype(o) == LUA_TTABLE) |
||
2187 | #define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) |
||
2188 | @@ -90,7 +103,25 @@ typedef struct lua_TValue { |
||
2189 | #define ttype(o) ((o)->tt) |
||
2190 | #define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) |
||
2191 | #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) |
||
2192 | -#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) |
||
2193 | + |
||
2194 | +#define ttype_ext(o) ( ttype(o) == LUA_TINT ? LUA_TNUMBER : ttype(o) ) |
||
2195 | +#define ttype_ext_same(o1,o2) ( (ttype(o1)==ttype(o2)) || (ttisnumber(o1) && ttisnumber(o2)) ) |
||
2196 | + |
||
2197 | +/* '_fast' variants are for cases where 'ttype(o)' is known to be LUA_TNUMBER. |
||
2198 | + */ |
||
2199 | +#ifdef LNUM_COMPLEX |
||
2200 | +# define nvalue_complex_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n ) |
||
2201 | +# define nvalue_fast(o) ( _LF(creal) ( nvalue_complex_fast(o) ) ) |
||
2202 | +# define nvalue_img_fast(o) ( _LF(cimag) ( nvalue_complex_fast(o) ) ) |
||
2203 | +# define nvalue_complex(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? (o)->value.i : (o)->value.n ) |
||
2204 | +# define nvalue_img(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? 0 : _LF(cimag)( (o)->value.n ) ) |
||
2205 | +# define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : _LF(creal)((o)->value.n) ) |
||
2206 | +#else |
||
2207 | +# define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : (o)->value.n ) |
||
2208 | +# define nvalue_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n ) |
||
2209 | +#endif |
||
2210 | +#define ivalue(o) check_exp( ttype(o)==LUA_TINT, (o)->value.i ) |
||
2211 | + |
||
2212 | #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) |
||
2213 | #define tsvalue(o) (&rawtsvalue(o)->tsv) |
||
2214 | #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) |
||
2215 | @@ -116,8 +147,27 @@ typedef struct lua_TValue { |
||
2216 | /* Macros to set values */ |
||
2217 | #define setnilvalue(obj) ((obj)->tt=LUA_TNIL) |
||
2218 | |||
2219 | -#define setnvalue(obj,x) \ |
||
2220 | - { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } |
||
2221 | +/* Must not have side effects, 'x' may be expression. |
||
2222 | +*/ |
||
2223 | +#define setivalue(obj,x) \ |
||
2224 | + { TValue *i_o=(obj); i_o->value.i=(x); i_o->tt=LUA_TINT; } |
||
2225 | + |
||
2226 | +# define setnvalue(obj,x) \ |
||
2227 | + { TValue *i_o=(obj); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; } |
||
2228 | + |
||
2229 | +/* Note: Complex always has "inline", both are C99. |
||
2230 | +*/ |
||
2231 | +#ifdef LNUM_COMPLEX |
||
2232 | + static inline void setnvalue_complex_fast( TValue *obj, lua_Complex x ) { |
||
2233 | + lua_assert( _LF(cimag)(x) != 0 ); |
||
2234 | + obj->value.n= x; obj->tt= LUA_TNUMBER; |
||
2235 | + } |
||
2236 | + static inline void setnvalue_complex( TValue *obj, lua_Complex x ) { |
||
2237 | + if (_LF(cimag)(x) == 0) { setnvalue(obj, _LF(creal)(x)); } |
||
2238 | + else { obj->value.n= x; obj->tt= LUA_TNUMBER; } |
||
2239 | + } |
||
2240 | +#endif |
||
2241 | + |
||
2242 | |||
2243 | #define setpvalue(obj,x) \ |
||
2244 | { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } |
||
2245 | @@ -155,9 +205,6 @@ typedef struct lua_TValue { |
||
2246 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ |
||
2247 | checkliveness(G(L),i_o); } |
||
2248 | |||
2249 | - |
||
2250 | - |
||
2251 | - |
||
2252 | #define setobj(L,obj1,obj2) \ |
||
2253 | { const TValue *o2=(obj2); TValue *o1=(obj1); \ |
||
2254 | o1->value = o2->value; o1->tt=o2->tt; \ |
||
2255 | @@ -185,8 +232,11 @@ typedef struct lua_TValue { |
||
2256 | |||
2257 | #define setttype(obj, tt) (ttype(obj) = (tt)) |
||
2258 | |||
2259 | - |
||
2260 | -#define iscollectable(o) (ttype(o) >= LUA_TSTRING) |
||
2261 | +#if LUA_TINT >= LUA_TSTRING |
||
2262 | +# define iscollectable(o) ((ttype(o) >= LUA_TSTRING) && (ttype(o) != LUA_TINT)) |
||
2263 | +#else |
||
2264 | +# define iscollectable(o) (ttype(o) >= LUA_TSTRING) |
||
2265 | +#endif |
||
2266 | |||
2267 | |||
2268 | |||
2269 | @@ -370,12 +420,10 @@ LUAI_FUNC int luaO_log2 (unsigned int x) |
||
2270 | LUAI_FUNC int luaO_int2fb (unsigned int x); |
||
2271 | LUAI_FUNC int luaO_fb2int (int x); |
||
2272 | LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); |
||
2273 | -LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); |
||
2274 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, |
||
2275 | va_list argp); |
||
2276 | LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); |
||
2277 | LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); |
||
2278 | |||
2279 | - |
||
2280 | #endif |
||
2281 | |||
2282 | --- a/src/loslib.c |
||
2283 | +++ b/src/loslib.c |
||
2284 | @@ -186,15 +186,30 @@ static int os_time (lua_State *L) { |
||
2285 | } |
||
2286 | if (t == (time_t)(-1)) |
||
2287 | lua_pushnil(L); |
||
2288 | - else |
||
2289 | - lua_pushnumber(L, (lua_Number)t); |
||
2290 | + else { |
||
2291 | + /* On float systems the pushed value must be an integer, NOT a number. |
||
2292 | + * Otherwise, accuracy is lost in the time_t->float conversion. |
||
2293 | + */ |
||
2294 | +#ifdef LNUM_FLOAT |
||
2295 | + lua_pushinteger(L, (lua_Integer) t); |
||
2296 | +#else |
||
2297 | + lua_pushnumber(L, (lua_Number) t); |
||
2298 | +#endif |
||
2299 | + } |
||
2300 | return 1; |
||
2301 | } |
||
2302 | |||
2303 | |||
2304 | static int os_difftime (lua_State *L) { |
||
2305 | +#ifdef LNUM_FLOAT |
||
2306 | + lua_Integer i= (lua_Integer) |
||
2307 | + difftime( (time_t)(luaL_checkinteger(L, 1)), |
||
2308 | + (time_t)(luaL_optinteger(L, 2, 0))); |
||
2309 | + lua_pushinteger(L, i); |
||
2310 | +#else |
||
2311 | lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), |
||
2312 | (time_t)(luaL_optnumber(L, 2, 0)))); |
||
2313 | +#endif |
||
2314 | return 1; |
||
2315 | } |
||
2316 | |||
2317 | --- a/src/lparser.c |
||
2318 | +++ b/src/lparser.c |
||
2319 | @@ -33,7 +33,6 @@ |
||
2320 | |||
2321 | #define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) |
||
2322 | |||
2323 | - |
||
2324 | /* |
||
2325 | ** nodes for block list (list of active blocks) |
||
2326 | */ |
||
2327 | @@ -72,7 +71,7 @@ static void errorlimit (FuncState *fs, i |
||
2328 | const char *msg = (fs->f->linedefined == 0) ? |
||
2329 | luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : |
||
2330 | luaO_pushfstring(fs->L, "function at line %d has more than %d %s", |
||
2331 | - fs->f->linedefined, limit, what); |
||
2332 | + (fs->f->linedefined), limit, what); |
||
2333 | luaX_lexerror(fs->ls, msg, 0); |
||
2334 | } |
||
2335 | |||
2336 | @@ -733,6 +732,18 @@ static void simpleexp (LexState *ls, exp |
||
2337 | v->u.nval = ls->t.seminfo.r; |
||
2338 | break; |
||
2339 | } |
||
2340 | + case TK_INT: { |
||
2341 | + init_exp(v, VKINT, 0); |
||
2342 | + v->u.ival = ls->t.seminfo.i; |
||
2343 | + break; |
||
2344 | + } |
||
2345 | +#ifdef LNUM_COMPLEX |
||
2346 | + case TK_NUMBER2: { |
||
2347 | + init_exp(v, VKNUM2, 0); |
||
2348 | + v->u.nval = ls->t.seminfo.r; |
||
2349 | + break; |
||
2350 | + } |
||
2351 | +#endif |
||
2352 | case TK_STRING: { |
||
2353 | codestring(ls, v, ls->t.seminfo.ts); |
||
2354 | break; |
||
2355 | @@ -1079,7 +1090,7 @@ static void fornum (LexState *ls, TStrin |
||
2356 | if (testnext(ls, ',')) |
||
2357 | exp1(ls); /* optional step */ |
||
2358 | else { /* default step = 1 */ |
||
2359 | - luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); |
||
2360 | + luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_integerK(fs, 1)); |
||
2361 | luaK_reserveregs(fs, 1); |
||
2362 | } |
||
2363 | forbody(ls, base, line, 1, 1); |
||
2364 | --- a/src/lparser.h |
||
2365 | +++ b/src/lparser.h |
||
2366 | @@ -31,7 +31,11 @@ typedef enum { |
||
2367 | VRELOCABLE, /* info = instruction pc */ |
||
2368 | VNONRELOC, /* info = result register */ |
||
2369 | VCALL, /* info = instruction pc */ |
||
2370 | - VVARARG /* info = instruction pc */ |
||
2371 | + VVARARG, /* info = instruction pc */ |
||
2372 | + VKINT /* ival = integer value */ |
||
2373 | +#ifdef LNUM_COMPLEX |
||
2374 | + ,VKNUM2 /* nval = imaginary value */ |
||
2375 | +#endif |
||
2376 | } expkind; |
||
2377 | |||
2378 | typedef struct expdesc { |
||
2379 | @@ -39,6 +43,7 @@ typedef struct expdesc { |
||
2380 | union { |
||
2381 | struct { int info, aux; } s; |
||
2382 | lua_Number nval; |
||
2383 | + lua_Integer ival; |
||
2384 | } u; |
||
2385 | int t; /* patch list of `exit when true' */ |
||
2386 | int f; /* patch list of `exit when false' */ |
||
2387 | --- a/src/lstrlib.c |
||
2388 | +++ b/src/lstrlib.c |
||
2389 | @@ -43,8 +43,8 @@ static ptrdiff_t posrelat (ptrdiff_t pos |
||
2390 | static int str_sub (lua_State *L) { |
||
2391 | size_t l; |
||
2392 | const char *s = luaL_checklstring(L, 1, &l); |
||
2393 | - ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); |
||
2394 | - ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); |
||
2395 | + ptrdiff_t start = posrelat(luaL_checkint32(L, 2), l); |
||
2396 | + ptrdiff_t end = posrelat(luaL_optint32(L, 3, -1), l); |
||
2397 | if (start < 1) start = 1; |
||
2398 | if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; |
||
2399 | if (start <= end) |
||
2400 | @@ -106,8 +106,8 @@ static int str_rep (lua_State *L) { |
||
2401 | static int str_byte (lua_State *L) { |
||
2402 | size_t l; |
||
2403 | const char *s = luaL_checklstring(L, 1, &l); |
||
2404 | - ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); |
||
2405 | - ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); |
||
2406 | + ptrdiff_t posi = posrelat(luaL_optint32(L, 2, 1), l); |
||
2407 | + ptrdiff_t pose = posrelat(luaL_optint32(L, 3, posi), l); |
||
2408 | int n, i; |
||
2409 | if (posi <= 0) posi = 1; |
||
2410 | if ((size_t)pose > l) pose = l; |
||
2411 | @@ -496,7 +496,7 @@ static int str_find_aux (lua_State *L, i |
||
2412 | size_t l1, l2; |
||
2413 | const char *s = luaL_checklstring(L, 1, &l1); |
||
2414 | const char *p = luaL_checklstring(L, 2, &l2); |
||
2415 | - ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; |
||
2416 | + ptrdiff_t init = posrelat(luaL_optint32(L, 3, 1), l1) - 1; |
||
2417 | if (init < 0) init = 0; |
||
2418 | else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; |
||
2419 | if (find && (lua_toboolean(L, 4) || /* explicit request? */ |
||
2420 | @@ -690,7 +690,7 @@ static int str_gsub (lua_State *L) { |
||
2421 | ** maximum size of each format specification (such as '%-099.99d') |
||
2422 | ** (+10 accounts for %99.99x plus margin of error) |
||
2423 | */ |
||
2424 | -#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) |
||
2425 | +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTEGER_FMT)-2 + 10) |
||
2426 | |||
2427 | |||
2428 | static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { |
||
2429 | @@ -747,9 +747,9 @@ static const char *scanformat (lua_State |
||
2430 | static void addintlen (char *form) { |
||
2431 | size_t l = strlen(form); |
||
2432 | char spec = form[l - 1]; |
||
2433 | - strcpy(form + l - 1, LUA_INTFRMLEN); |
||
2434 | - form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; |
||
2435 | - form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; |
||
2436 | + const char *tmp= LUA_INTEGER_FMT; /* "%lld" or "%ld" */ |
||
2437 | + strcpy(form + l - 1, tmp+1); |
||
2438 | + form[l + sizeof(LUA_INTEGER_FMT)-4] = spec; |
||
2439 | } |
||
2440 | |||
2441 | |||
2442 | @@ -779,12 +779,12 @@ static int str_format (lua_State *L) { |
||
2443 | } |
||
2444 | case 'd': case 'i': { |
||
2445 | addintlen(form); |
||
2446 | - sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); |
||
2447 | + sprintf(buff, form, luaL_checkinteger(L, arg)); |
||
2448 | break; |
||
2449 | } |
||
2450 | case 'o': case 'u': case 'x': case 'X': { |
||
2451 | addintlen(form); |
||
2452 | - sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); |
||
2453 | + sprintf(buff, form, (unsigned LUA_INTEGER)luaL_checkinteger(L, arg)); |
||
2454 | break; |
||
2455 | } |
||
2456 | case 'e': case 'E': case 'f': |
||
2457 | --- a/src/ltable.c |
||
2458 | +++ b/src/ltable.c |
||
2459 | @@ -33,6 +33,7 @@ |
||
2460 | #include "lobject.h" |
||
2461 | #include "lstate.h" |
||
2462 | #include "ltable.h" |
||
2463 | +#include "lnum.h" |
||
2464 | |||
2465 | |||
2466 | /* |
||
2467 | @@ -51,25 +52,15 @@ |
||
2468 | |||
2469 | #define hashstr(t,str) hashpow2(t, (str)->tsv.hash) |
||
2470 | #define hashboolean(t,p) hashpow2(t, p) |
||
2471 | - |
||
2472 | +#define hashint(t,i) hashpow2(t,i) |
||
2473 | |||
2474 | /* |
||
2475 | ** for some types, it is better to avoid modulus by power of 2, as |
||
2476 | ** they tend to have many 2 factors. |
||
2477 | */ |
||
2478 | #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) |
||
2479 | - |
||
2480 | - |
||
2481 | #define hashpointer(t,p) hashmod(t, IntPoint(p)) |
||
2482 | |||
2483 | - |
||
2484 | -/* |
||
2485 | -** number of ints inside a lua_Number |
||
2486 | -*/ |
||
2487 | -#define numints cast_int(sizeof(lua_Number)/sizeof(int)) |
||
2488 | - |
||
2489 | - |
||
2490 | - |
||
2491 | #define dummynode (&dummynode_) |
||
2492 | |||
2493 | static const Node dummynode_ = { |
||
2494 | @@ -80,27 +71,46 @@ static const Node dummynode_ = { |
||
2495 | |||
2496 | /* |
||
2497 | ** hash for lua_Numbers |
||
2498 | +** |
||
2499 | +** for non-complex modes, never called with 'lua_Integer' value range (s.a. 0) |
||
2500 | */ |
||
2501 | static Node *hashnum (const Table *t, lua_Number n) { |
||
2502 | - unsigned int a[numints]; |
||
2503 | - int i; |
||
2504 | - if (luai_numeq(n, 0)) /* avoid problems with -0 */ |
||
2505 | - return gnode(t, 0); |
||
2506 | - memcpy(a, &n, sizeof(a)); |
||
2507 | - for (i = 1; i < numints; i++) a[0] += a[i]; |
||
2508 | - return hashmod(t, a[0]); |
||
2509 | + const unsigned int *p= cast(const unsigned int *,&n); |
||
2510 | + unsigned int sum= *p; |
||
2511 | + unsigned int m= sizeof(lua_Number)/sizeof(int); |
||
2512 | + unsigned int i; |
||
2513 | + /* OS X Intel has 'm'==4 and gives "Bus error" if the last integer of |
||
2514 | + * 'n' is read; the actual size of long double is only 80 bits = 10 bytes. |
||
2515 | + * Linux x86 has 'm'==3, and does not require reduction. |
||
2516 | + */ |
||
2517 | +#if defined(LNUM_LDOUBLE) && defined(__i386__) |
||
2518 | + if (m>3) m--; |
||
2519 | +#endif |
||
2520 | + for (i = 1; i < m; i++) sum += p[i]; |
||
2521 | + return hashmod(t, sum); |
||
2522 | } |
||
2523 | |||
2524 | |||
2525 | - |
||
2526 | /* |
||
2527 | ** returns the `main' position of an element in a table (that is, the index |
||
2528 | ** of its hash value) |
||
2529 | +** |
||
2530 | +** Floating point numbers with integer value give the hash position of the |
||
2531 | +** integer (so they use the same table position). |
||
2532 | */ |
||
2533 | static Node *mainposition (const Table *t, const TValue *key) { |
||
2534 | + lua_Integer i; |
||
2535 | switch (ttype(key)) { |
||
2536 | case LUA_TNUMBER: |
||
2537 | - return hashnum(t, nvalue(key)); |
||
2538 | + if (tt_integer_valued(key,&i)) |
||
2539 | + return hashint(t, i); |
||
2540 | +#ifdef LNUM_COMPLEX |
||
2541 | + if (nvalue_img_fast(key)!=0 && luai_numeq(nvalue_fast(key),0)) |
||
2542 | + return gnode(t, 0); /* 0 and -0 to give same hash */ |
||
2543 | +#endif |
||
2544 | + return hashnum(t, nvalue_fast(key)); |
||
2545 | + case LUA_TINT: |
||
2546 | + return hashint(t, ivalue(key)); |
||
2547 | case LUA_TSTRING: |
||
2548 | return hashstr(t, rawtsvalue(key)); |
||
2549 | case LUA_TBOOLEAN: |
||
2550 | @@ -116,16 +126,20 @@ static Node *mainposition (const Table * |
||
2551 | /* |
||
2552 | ** returns the index for `key' if `key' is an appropriate key to live in |
||
2553 | ** the array part of the table, -1 otherwise. |
||
2554 | +** |
||
2555 | +** Anything <=0 is taken as not being in the array part. |
||
2556 | */ |
||
2557 | -static int arrayindex (const TValue *key) { |
||
2558 | - if (ttisnumber(key)) { |
||
2559 | - lua_Number n = nvalue(key); |
||
2560 | - int k; |
||
2561 | - lua_number2int(k, n); |
||
2562 | - if (luai_numeq(cast_num(k), n)) |
||
2563 | - return k; |
||
2564 | +static int arrayindex (const TValue *key, int max) { |
||
2565 | + lua_Integer k; |
||
2566 | + switch( ttype(key) ) { |
||
2567 | + case LUA_TINT: |
||
2568 | + k= ivalue(key); break; |
||
2569 | + case LUA_TNUMBER: |
||
2570 | + if (tt_integer_valued(key,&k)) break; |
||
2571 | + default: |
||
2572 | + return -1; /* not to be used as array index */ |
||
2573 | } |
||
2574 | - return -1; /* `key' did not match some condition */ |
||
2575 | + return ((k>0) && (k <= max)) ? cast_int(k) : -1; |
||
2576 | } |
||
2577 | |||
2578 | |||
2579 | @@ -137,8 +151,8 @@ static int arrayindex (const TValue *key |
||
2580 | static int findindex (lua_State *L, Table *t, StkId key) { |
||
2581 | int i; |
||
2582 | if (ttisnil(key)) return -1; /* first iteration */ |
||
2583 | - i = arrayindex(key); |
||
2584 | - if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ |
||
2585 | + i = arrayindex(key, t->sizearray); |
||
2586 | + if (i>0) /* inside array part? */ |
||
2587 | return i-1; /* yes; that's the index (corrected to C) */ |
||
2588 | else { |
||
2589 | Node *n = mainposition(t, key); |
||
2590 | @@ -163,7 +177,7 @@ int luaH_next (lua_State *L, Table *t, S |
||
2591 | int i = findindex(L, t, key); /* find original element */ |
||
2592 | for (i++; i < t->sizearray; i++) { /* try first array part */ |
||
2593 | if (!ttisnil(&t->array[i])) { /* a non-nil value? */ |
||
2594 | - setnvalue(key, cast_num(i+1)); |
||
2595 | + setivalue(key, i+1); |
||
2596 | setobj2s(L, key+1, &t->array[i]); |
||
2597 | return 1; |
||
2598 | } |
||
2599 | @@ -209,8 +223,8 @@ static int computesizes (int nums[], int |
||
2600 | |||
2601 | |||
2602 | static int countint (const TValue *key, int *nums) { |
||
2603 | - int k = arrayindex(key); |
||
2604 | - if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ |
||
2605 | + int k = arrayindex(key,MAXASIZE); |
||
2606 | + if (k>0) { /* appropriate array index? */ |
||
2607 | nums[ceillog2(k)]++; /* count as such */ |
||
2608 | return 1; |
||
2609 | } |
||
2610 | @@ -308,7 +322,7 @@ static void resize (lua_State *L, Table |
||
2611 | /* re-insert elements from vanishing slice */ |
||
2612 | for (i=nasize; i<oldasize; i++) { |
||
2613 | if (!ttisnil(&t->array[i])) |
||
2614 | - setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); |
||
2615 | + setobjt2t(L, luaH_setint(L, t, i+1), &t->array[i]); |
||
2616 | } |
||
2617 | /* shrink array */ |
||
2618 | luaM_reallocvector(L, t->array, oldasize, nasize, TValue); |
||
2619 | @@ -409,7 +423,9 @@ static TValue *newkey (lua_State *L, Tab |
||
2620 | othern = mainposition(t, key2tval(mp)); |
||
2621 | if (othern != mp) { /* is colliding node out of its main position? */ |
||
2622 | /* yes; move colliding node into free position */ |
||
2623 | - while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ |
||
2624 | + while (gnext(othern) != mp) { |
||
2625 | + othern = gnext(othern); /* find previous */ |
||
2626 | + } |
||
2627 | gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ |
||
2628 | *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ |
||
2629 | gnext(mp) = NULL; /* now `mp' is free */ |
||
2630 | @@ -432,17 +448,18 @@ static TValue *newkey (lua_State *L, Tab |
||
2631 | /* |
||
2632 | ** search function for integers |
||
2633 | */ |
||
2634 | -const TValue *luaH_getnum (Table *t, int key) { |
||
2635 | +const TValue *luaH_getint (Table *t, lua_Integer key) { |
||
2636 | /* (1 <= key && key <= t->sizearray) */ |
||
2637 | if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) |
||
2638 | return &t->array[key-1]; |
||
2639 | else { |
||
2640 | - lua_Number nk = cast_num(key); |
||
2641 | - Node *n = hashnum(t, nk); |
||
2642 | + Node *n = hashint(t, key); |
||
2643 | do { /* check whether `key' is somewhere in the chain */ |
||
2644 | - if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) |
||
2645 | + if (ttisint(gkey(n)) && (ivalue(gkey(n)) == key)) { |
||
2646 | return gval(n); /* that's it */ |
||
2647 | - else n = gnext(n); |
||
2648 | + } else { |
||
2649 | + n = gnext(n); |
||
2650 | + } |
||
2651 | } while (n); |
||
2652 | return luaO_nilobject; |
||
2653 | } |
||
2654 | @@ -470,14 +487,12 @@ const TValue *luaH_get (Table *t, const |
||
2655 | switch (ttype(key)) { |
||
2656 | case LUA_TNIL: return luaO_nilobject; |
||
2657 | case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); |
||
2658 | + case LUA_TINT: return luaH_getint(t, ivalue(key)); |
||
2659 | case LUA_TNUMBER: { |
||
2660 | - int k; |
||
2661 | - lua_Number n = nvalue(key); |
||
2662 | - lua_number2int(k, n); |
||
2663 | - if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ |
||
2664 | - return luaH_getnum(t, k); /* use specialized version */ |
||
2665 | - /* else go through */ |
||
2666 | - } |
||
2667 | + lua_Integer i; |
||
2668 | + if (tt_integer_valued(key,&i)) |
||
2669 | + return luaH_getint(t,i); |
||
2670 | + } /* pass through */ |
||
2671 | default: { |
||
2672 | Node *n = mainposition(t, key); |
||
2673 | do { /* check whether `key' is somewhere in the chain */ |
||
2674 | @@ -498,20 +513,25 @@ TValue *luaH_set (lua_State *L, Table *t |
||
2675 | return cast(TValue *, p); |
||
2676 | else { |
||
2677 | if (ttisnil(key)) luaG_runerror(L, "table index is nil"); |
||
2678 | - else if (ttisnumber(key) && luai_numisnan(nvalue(key))) |
||
2679 | - luaG_runerror(L, "table index is NaN"); |
||
2680 | + else if (ttype(key)==LUA_TNUMBER) { |
||
2681 | + lua_Integer k; |
||
2682 | + if (luai_numisnan(nvalue_fast(key))) |
||
2683 | + luaG_runerror(L, "table index is NaN"); |
||
2684 | + if (tt_integer_valued(key,&k)) |
||
2685 | + return luaH_setint(L, t, k); |
||
2686 | + } |
||
2687 | return newkey(L, t, key); |
||
2688 | } |
||
2689 | } |
||
2690 | |||
2691 | |||
2692 | -TValue *luaH_setnum (lua_State *L, Table *t, int key) { |
||
2693 | - const TValue *p = luaH_getnum(t, key); |
||
2694 | +TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key) { |
||
2695 | + const TValue *p = luaH_getint(t, key); |
||
2696 | if (p != luaO_nilobject) |
||
2697 | return cast(TValue *, p); |
||
2698 | else { |
||
2699 | TValue k; |
||
2700 | - setnvalue(&k, cast_num(key)); |
||
2701 | + setivalue(&k, key); |
||
2702 | return newkey(L, t, &k); |
||
2703 | } |
||
2704 | } |
||
2705 | @@ -533,20 +553,21 @@ static int unbound_search (Table *t, uns |
||
2706 | unsigned int i = j; /* i is zero or a present index */ |
||
2707 | j++; |
||
2708 | /* find `i' and `j' such that i is present and j is not */ |
||
2709 | - while (!ttisnil(luaH_getnum(t, j))) { |
||
2710 | + while (!ttisnil(luaH_getint(t, j))) { |
||
2711 | i = j; |
||
2712 | j *= 2; |
||
2713 | if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ |
||
2714 | /* table was built with bad purposes: resort to linear search */ |
||
2715 | - i = 1; |
||
2716 | - while (!ttisnil(luaH_getnum(t, i))) i++; |
||
2717 | - return i - 1; |
||
2718 | + for( i = 1; i<MAX_INT+1; i++ ) { |
||
2719 | + if (ttisnil(luaH_getint(t, i))) break; |
||
2720 | + } |
||
2721 | + return i - 1; /* up to MAX_INT */ |
||
2722 | } |
||
2723 | } |
||
2724 | /* now do a binary search between them */ |
||
2725 | while (j - i > 1) { |
||
2726 | unsigned int m = (i+j)/2; |
||
2727 | - if (ttisnil(luaH_getnum(t, m))) j = m; |
||
2728 | + if (ttisnil(luaH_getint(t, m))) j = m; |
||
2729 | else i = m; |
||
2730 | } |
||
2731 | return i; |
||
2732 | --- a/src/ltable.h |
||
2733 | +++ b/src/ltable.h |
||
2734 | @@ -18,8 +18,8 @@ |
||
2735 | #define key2tval(n) (&(n)->i_key.tvk) |
||
2736 | |||
2737 | |||
2738 | -LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); |
||
2739 | -LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); |
||
2740 | +LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); |
||
2741 | +LUAI_FUNC TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key); |
||
2742 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); |
||
2743 | LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); |
||
2744 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); |
||
2745 | --- a/src/ltm.c |
||
2746 | +++ b/src/ltm.c |
||
2747 | @@ -19,7 +19,6 @@ |
||
2748 | #include "ltm.h" |
||
2749 | |||
2750 | |||
2751 | - |
||
2752 | const char *const luaT_typenames[] = { |
||
2753 | "nil", "boolean", "userdata", "number", |
||
2754 | "string", "table", "function", "userdata", "thread", |
||
2755 | @@ -67,6 +66,9 @@ const TValue *luaT_gettmbyobj (lua_State |
||
2756 | case LUA_TUSERDATA: |
||
2757 | mt = uvalue(o)->metatable; |
||
2758 | break; |
||
2759 | + case LUA_TINT: |
||
2760 | + mt = G(L)->mt[LUA_TNUMBER]; |
||
2761 | + break; |
||
2762 | default: |
||
2763 | mt = G(L)->mt[ttype(o)]; |
||
2764 | } |
||
2765 | --- a/src/lua.c |
||
2766 | +++ b/src/lua.c |
||
2767 | @@ -16,7 +16,7 @@ |
||
2768 | |||
2769 | #include "lauxlib.h" |
||
2770 | #include "lualib.h" |
||
2771 | - |
||
2772 | +#include "llimits.h" |
||
2773 | |||
2774 | |||
2775 | static lua_State *globalL = NULL; |
||
2776 | @@ -382,6 +382,15 @@ int main (int argc, char **argv) { |
||
2777 | l_message(argv[0], "cannot create state: not enough memory"); |
||
2778 | return EXIT_FAILURE; |
||
2779 | } |
||
2780 | + /* Checking 'sizeof(lua_Integer)' cannot be made in preprocessor on all compilers. |
||
2781 | + */ |
||
2782 | +#ifdef LNUM_INT16 |
||
2783 | + lua_assert( sizeof(lua_Integer) == 2 ); |
||
2784 | +#elif defined(LNUM_INT32) |
||
2785 | + lua_assert( sizeof(lua_Integer) == 4 ); |
||
2786 | +#elif defined(LNUM_INT64) |
||
2787 | + lua_assert( sizeof(lua_Integer) == 8 ); |
||
2788 | +#endif |
||
2789 | s.argc = argc; |
||
2790 | s.argv = argv; |
||
2791 | status = lua_cpcall(L, &pmain, &s); |
||
2792 | --- a/src/lua.h |
||
2793 | +++ b/src/lua.h |
||
2794 | @@ -19,7 +19,7 @@ |
||
2795 | #define LUA_VERSION "Lua 5.1" |
||
2796 | #define LUA_RELEASE "Lua 5.1.5" |
||
2797 | #define LUA_VERSION_NUM 501 |
||
2798 | -#define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio" |
||
2799 | +#define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio" " (" LUA_LNUM ")" |
||
2800 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" |
||
2801 | |||
2802 | |||
2803 | @@ -71,6 +71,16 @@ typedef void * (*lua_Alloc) (void *ud, v |
||
2804 | */ |
||
2805 | #define LUA_TNONE (-1) |
||
2806 | |||
2807 | +/* LUA_TINT is an internal type, not visible to applications. There are three |
||
2808 | + * potential values where it can be tweaked to (code autoadjusts to these): |
||
2809 | + * |
||
2810 | + * -2: not 'usual' type value; good since 'LUA_TINT' is not part of the API |
||
2811 | + * LUA_TNUMBER+1: shifts other type values upwards, breaking binary compatibility |
||
2812 | + * not acceptable for 5.1, maybe 5.2 onwards? |
||
2813 | + * 9: greater than existing (5.1) type values. |
||
2814 | +*/ |
||
2815 | +#define LUA_TINT (-2) |
||
2816 | + |
||
2817 | #define LUA_TNIL 0 |
||
2818 | #define LUA_TBOOLEAN 1 |
||
2819 | #define LUA_TLIGHTUSERDATA 2 |
||
2820 | @@ -139,6 +149,8 @@ LUA_API int (lua_isuserdata) |
||
2821 | LUA_API int (lua_type) (lua_State *L, int idx); |
||
2822 | LUA_API const char *(lua_typename) (lua_State *L, int tp); |
||
2823 | |||
2824 | +LUA_API int (lua_isinteger) (lua_State *L, int idx); |
||
2825 | + |
||
2826 | LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); |
||
2827 | LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); |
||
2828 | LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); |
||
2829 | @@ -244,6 +256,19 @@ LUA_API lua_Alloc (lua_getallocf) (lua_S |
||
2830 | LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); |
||
2831 | |||
2832 | |||
2833 | +/* |
||
2834 | +* It is unnecessary to break Lua C API 'lua_tonumber()' compatibility, just |
||
2835 | +* because the Lua number type is complex. Most C modules would use scalars |
||
2836 | +* only. We'll introduce new 'lua_tocomplex' and 'lua_pushcomplex' for when |
||
2837 | +* the module really wants to use them. |
||
2838 | +*/ |
||
2839 | +#ifdef LNUM_COMPLEX |
||
2840 | + #include <complex.h> |
||
2841 | + typedef LUA_NUMBER complex lua_Complex; |
||
2842 | + LUA_API lua_Complex (lua_tocomplex) (lua_State *L, int idx); |
||
2843 | + LUA_API void (lua_pushcomplex) (lua_State *L, lua_Complex v); |
||
2844 | +#endif |
||
2845 | + |
||
2846 | |||
2847 | /* |
||
2848 | ** =============================================================== |
||
2849 | @@ -268,7 +293,12 @@ LUA_API void lua_setallocf (lua_State *L |
||
2850 | #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) |
||
2851 | #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) |
||
2852 | #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) |
||
2853 | -#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) |
||
2854 | + |
||
2855 | +#if LUA_TINT < 0 |
||
2856 | +# define lua_isnoneornil(L, n) ( (lua_type(L,(n)) <= 0) && (lua_type(L,(n)) != LUA_TINT) ) |
||
2857 | +#else |
||
2858 | +# define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) |
||
2859 | +#endif |
||
2860 | |||
2861 | #define lua_pushliteral(L, s) \ |
||
2862 | lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) |
||
2863 | @@ -386,3 +416,4 @@ struct lua_Debug { |
||
2864 | |||
2865 | |||
2866 | #endif |
||
2867 | + |
||
2868 | --- a/src/luaconf.h |
||
2869 | +++ b/src/luaconf.h |
||
2870 | @@ -10,7 +10,9 @@ |
||
2871 | |||
2872 | #include <limits.h> |
||
2873 | #include <stddef.h> |
||
2874 | - |
||
2875 | +#ifdef lua_assert |
||
2876 | +# include <assert.h> |
||
2877 | +#endif |
||
2878 | |||
2879 | /* |
||
2880 | ** ================================================================== |
||
2881 | @@ -136,14 +138,38 @@ |
||
2882 | |||
2883 | |||
2884 | /* |
||
2885 | -@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. |
||
2886 | -** CHANGE that if ptrdiff_t is not adequate on your machine. (On most |
||
2887 | -** machines, ptrdiff_t gives a good choice between int or long.) |
||
2888 | +@@ LUAI_BITSINT defines the number of bits in an int. |
||
2889 | +** CHANGE here if Lua cannot automatically detect the number of bits of |
||
2890 | +** your machine. Probably you do not need to change this. |
||
2891 | */ |
||
2892 | -#define LUA_INTEGER ptrdiff_t |
||
2893 | +/* avoid overflows in comparison */ |
||
2894 | +#if INT_MAX-20 < 32760 |
||
2895 | +#define LUAI_BITSINT 16 |
||
2896 | +#elif INT_MAX > 2147483640L |
||
2897 | +/* int has at least 32 bits */ |
||
2898 | +#define LUAI_BITSINT 32 |
||
2899 | +#else |
||
2900 | +#error "you must define LUA_BITSINT with number of bits in an integer" |
||
2901 | +#endif |
||
2902 | |||
2903 | |||
2904 | /* |
||
2905 | +@@ LNUM_DOUBLE |Â LNUM_FLOAT |Â LNUM_LDOUBLE: Generic Lua number mode |
||
2906 | +@@ LNUM_INT32 | LNUM_INT64: Integer type |
||
2907 | +@@ LNUM_COMPLEX: Define for using 'a+bi' numbers |
||
2908 | +@@ |
||
2909 | +@@ You can combine LNUM_xxx but only one of each group. I.e. '-DLNUM_FLOAT |
||
2910 | +@@ -DLNUM_INT32 -DLNUM_COMPLEX' gives float range complex numbers, with |
||
2911 | +@@ 32-bit scalar integer range optimized. |
||
2912 | +** |
||
2913 | +** These are kept in a separate configuration file mainly for ease of patching |
||
2914 | +** (can be changed if integerated to Lua proper). |
||
2915 | +*/ |
||
2916 | +/*#define LNUM_DOUBLE*/ |
||
2917 | +/*#define LNUM_INT32*/ |
||
2918 | +#include "lnum_config.h" |
||
2919 | + |
||
2920 | +/* |
||
2921 | @@ LUA_API is a mark for all core API functions. |
||
2922 | @@ LUALIB_API is a mark for all standard library functions. |
||
2923 | ** CHANGE them if you need to define those functions in some special way. |
||
2924 | @@ -383,22 +409,6 @@ |
||
2925 | |||
2926 | |||
2927 | /* |
||
2928 | -@@ LUAI_BITSINT defines the number of bits in an int. |
||
2929 | -** CHANGE here if Lua cannot automatically detect the number of bits of |
||
2930 | -** your machine. Probably you do not need to change this. |
||
2931 | -*/ |
||
2932 | -/* avoid overflows in comparison */ |
||
2933 | -#if INT_MAX-20 < 32760 |
||
2934 | -#define LUAI_BITSINT 16 |
||
2935 | -#elif INT_MAX > 2147483640L |
||
2936 | -/* int has at least 32 bits */ |
||
2937 | -#define LUAI_BITSINT 32 |
||
2938 | -#else |
||
2939 | -#error "you must define LUA_BITSINT with number of bits in an integer" |
||
2940 | -#endif |
||
2941 | - |
||
2942 | - |
||
2943 | -/* |
||
2944 | @@ LUAI_UINT32 is an unsigned integer with at least 32 bits. |
||
2945 | @@ LUAI_INT32 is an signed integer with at least 32 bits. |
||
2946 | @@ LUAI_UMEM is an unsigned integer big enough to count the total |
||
2947 | @@ -425,6 +435,15 @@ |
||
2948 | #define LUAI_MEM long |
||
2949 | #endif |
||
2950 | |||
2951 | +/* |
||
2952 | +@@ LUAI_BOOL carries 0 and nonzero (normally 1). It may be defined as 'char' |
||
2953 | +** (to save memory), 'int' (for speed), 'bool' (for C++) or '_Bool' (C99) |
||
2954 | +*/ |
||
2955 | +#ifdef __cplusplus |
||
2956 | +# define LUAI_BOOL bool |
||
2957 | +#else |
||
2958 | +# define LUAI_BOOL int |
||
2959 | +#endif |
||
2960 | |||
2961 | /* |
||
2962 | @@ LUAI_MAXCALLS limits the number of nested calls. |
||
2963 | @@ -490,101 +509,6 @@ |
||
2964 | /* }================================================================== */ |
||
2965 | |||
2966 | |||
2967 | - |
||
2968 | - |
||
2969 | -/* |
||
2970 | -** {================================================================== |
||
2971 | -@@ LUA_NUMBER is the type of numbers in Lua. |
||
2972 | -** CHANGE the following definitions only if you want to build Lua |
||
2973 | -** with a number type different from double. You may also need to |
||
2974 | -** change lua_number2int & lua_number2integer. |
||
2975 | -** =================================================================== |
||
2976 | -*/ |
||
2977 | - |
||
2978 | -#define LUA_NUMBER_DOUBLE |
||
2979 | -#define LUA_NUMBER double |
||
2980 | - |
||
2981 | -/* |
||
2982 | -@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' |
||
2983 | -@* over a number. |
||
2984 | -*/ |
||
2985 | -#define LUAI_UACNUMBER double |
||
2986 | - |
||
2987 | - |
||
2988 | -/* |
||
2989 | -@@ LUA_NUMBER_SCAN is the format for reading numbers. |
||
2990 | -@@ LUA_NUMBER_FMT is the format for writing numbers. |
||
2991 | -@@ lua_number2str converts a number to a string. |
||
2992 | -@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. |
||
2993 | -@@ lua_str2number converts a string to a number. |
||
2994 | -*/ |
||
2995 | -#define LUA_NUMBER_SCAN "%lf" |
||
2996 | -#define LUA_NUMBER_FMT "%.14g" |
||
2997 | -#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) |
||
2998 | -#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ |
||
2999 | -#define lua_str2number(s,p) strtod((s), (p)) |
||
3000 | - |
||
3001 | - |
||
3002 | -/* |
||
3003 | -@@ The luai_num* macros define the primitive operations over numbers. |
||
3004 | -*/ |
||
3005 | -#if defined(LUA_CORE) |
||
3006 | -#include <math.h> |
||
3007 | -#define luai_numadd(a,b) ((a)+(b)) |
||
3008 | -#define luai_numsub(a,b) ((a)-(b)) |
||
3009 | -#define luai_nummul(a,b) ((a)*(b)) |
||
3010 | -#define luai_numdiv(a,b) ((a)/(b)) |
||
3011 | -#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) |
||
3012 | -#define luai_numpow(a,b) (pow(a,b)) |
||
3013 | -#define luai_numunm(a) (-(a)) |
||
3014 | -#define luai_numeq(a,b) ((a)==(b)) |
||
3015 | -#define luai_numlt(a,b) ((a)<(b)) |
||
3016 | -#define luai_numle(a,b) ((a)<=(b)) |
||
3017 | -#define luai_numisnan(a) (!luai_numeq((a), (a))) |
||
3018 | -#endif |
||
3019 | - |
||
3020 | - |
||
3021 | -/* |
||
3022 | -@@ lua_number2int is a macro to convert lua_Number to int. |
||
3023 | -@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. |
||
3024 | -** CHANGE them if you know a faster way to convert a lua_Number to |
||
3025 | -** int (with any rounding method and without throwing errors) in your |
||
3026 | -** system. In Pentium machines, a naive typecast from double to int |
||
3027 | -** in C is extremely slow, so any alternative is worth trying. |
||
3028 | -*/ |
||
3029 | - |
||
3030 | -/* On a Pentium, resort to a trick */ |
||
3031 | -#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ |
||
3032 | - (defined(__i386) || defined (_M_IX86) || defined(__i386__)) |
||
3033 | - |
||
3034 | -/* On a Microsoft compiler, use assembler */ |
||
3035 | -#if defined(_MSC_VER) |
||
3036 | - |
||
3037 | -#define lua_number2int(i,d) __asm fld d __asm fistp i |
||
3038 | -#define lua_number2integer(i,n) lua_number2int(i, n) |
||
3039 | - |
||
3040 | -/* the next trick should work on any Pentium, but sometimes clashes |
||
3041 | - with a DirectX idiosyncrasy */ |
||
3042 | -#else |
||
3043 | - |
||
3044 | -union luai_Cast { double l_d; long l_l; }; |
||
3045 | -#define lua_number2int(i,d) \ |
||
3046 | - { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } |
||
3047 | -#define lua_number2integer(i,n) lua_number2int(i, n) |
||
3048 | - |
||
3049 | -#endif |
||
3050 | - |
||
3051 | - |
||
3052 | -/* this option always works, but may be slow */ |
||
3053 | -#else |
||
3054 | -#define lua_number2int(i,d) ((i)=(int)(d)) |
||
3055 | -#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) |
||
3056 | - |
||
3057 | -#endif |
||
3058 | - |
||
3059 | -/* }================================================================== */ |
||
3060 | - |
||
3061 | - |
||
3062 | /* |
||
3063 | @@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. |
||
3064 | ** CHANGE it if your system requires alignments larger than double. (For |
||
3065 | @@ -728,28 +652,6 @@ union luai_Cast { double l_d; long l_l; |
||
3066 | #define luai_userstateyield(L,n) ((void)L) |
||
3067 | |||
3068 | |||
3069 | -/* |
||
3070 | -@@ LUA_INTFRMLEN is the length modifier for integer conversions |
||
3071 | -@* in 'string.format'. |
||
3072 | -@@ LUA_INTFRM_T is the integer type correspoding to the previous length |
||
3073 | -@* modifier. |
||
3074 | -** CHANGE them if your system supports long long or does not support long. |
||
3075 | -*/ |
||
3076 | - |
||
3077 | -#if defined(LUA_USELONGLONG) |
||
3078 | - |
||
3079 | -#define LUA_INTFRMLEN "ll" |
||
3080 | -#define LUA_INTFRM_T long long |
||
3081 | - |
||
3082 | -#else |
||
3083 | - |
||
3084 | -#define LUA_INTFRMLEN "l" |
||
3085 | -#define LUA_INTFRM_T long |
||
3086 | - |
||
3087 | -#endif |
||
3088 | - |
||
3089 | - |
||
3090 | - |
||
3091 | /* =================================================================== */ |
||
3092 | |||
3093 | /* |
||
3094 | --- a/src/lundump.c |
||
3095 | +++ b/src/lundump.c |
||
3096 | @@ -73,6 +73,13 @@ static lua_Number LoadNumber(LoadState* |
||
3097 | return x; |
||
3098 | } |
||
3099 | |||
3100 | +static lua_Integer LoadInteger(LoadState* S) |
||
3101 | +{ |
||
3102 | + lua_Integer x; |
||
3103 | + LoadVar(S,x); |
||
3104 | + return x; |
||
3105 | +} |
||
3106 | + |
||
3107 | static TString* LoadString(LoadState* S) |
||
3108 | { |
||
3109 | size_t size; |
||
3110 | @@ -119,6 +126,9 @@ static void LoadConstants(LoadState* S, |
||
3111 | case LUA_TNUMBER: |
||
3112 | setnvalue(o,LoadNumber(S)); |
||
3113 | break; |
||
3114 | + case LUA_TINT: /* Integer type saved in bytecode (see lcode.c) */ |
||
3115 | + setivalue(o,LoadInteger(S)); |
||
3116 | + break; |
||
3117 | case LUA_TSTRING: |
||
3118 | setsvalue2n(S->L,o,LoadString(S)); |
||
3119 | break; |
||
3120 | @@ -223,5 +233,22 @@ void luaU_header (char* h) |
||
3121 | *h++=(char)sizeof(size_t); |
||
3122 | *h++=(char)sizeof(Instruction); |
||
3123 | *h++=(char)sizeof(lua_Number); |
||
3124 | - *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ |
||
3125 | + |
||
3126 | + /* |
||
3127 | + * Last byte of header (0/1 in unpatched Lua 5.1.3): |
||
3128 | + * |
||
3129 | + * 0: lua_Number is float or double, lua_Integer not used. (nonpatched only) |
||
3130 | + * 1: lua_Number is integer (nonpatched only) |
||
3131 | + * |
||
3132 | + * +2: LNUM_INT16: sizeof(lua_Integer) |
||
3133 | + * +4: LNUM_INT32: sizeof(lua_Integer) |
||
3134 | + * +8: LNUM_INT64: sizeof(lua_Integer) |
||
3135 | + * |
||
3136 | + * +0x80: LNUM_COMPLEX |
||
3137 | + */ |
||
3138 | + *h++ = (char)(sizeof(lua_Integer) |
||
3139 | +#ifdef LNUM_COMPLEX |
||
3140 | + | 0x80 |
||
3141 | +#endif |
||
3142 | + ); |
||
3143 | } |
||
3144 | --- a/src/lvm.c |
||
3145 | +++ b/src/lvm.c |
||
3146 | @@ -25,22 +25,35 @@ |
||
3147 | #include "ltable.h" |
||
3148 | #include "ltm.h" |
||
3149 | #include "lvm.h" |
||
3150 | - |
||
3151 | - |
||
3152 | +#include "llex.h" |
||
3153 | +#include "lnum.h" |
||
3154 | |||
3155 | /* limit for table tag-method chains (to avoid loops) */ |
||
3156 | #define MAXTAGLOOP 100 |
||
3157 | |||
3158 | |||
3159 | -const TValue *luaV_tonumber (const TValue *obj, TValue *n) { |
||
3160 | - lua_Number num; |
||
3161 | +/* |
||
3162 | + * If 'obj' is a string, it is tried to be interpreted as a number. |
||
3163 | + */ |
||
3164 | +const TValue *luaV_tonumber ( const TValue *obj, TValue *n) { |
||
3165 | + lua_Number d; |
||
3166 | + lua_Integer i; |
||
3167 | + |
||
3168 | if (ttisnumber(obj)) return obj; |
||
3169 | - if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { |
||
3170 | - setnvalue(n, num); |
||
3171 | - return n; |
||
3172 | - } |
||
3173 | - else |
||
3174 | - return NULL; |
||
3175 | + |
||
3176 | + if (ttisstring(obj)) { |
||
3177 | + switch( luaO_str2d( svalue(obj), &d, &i ) ) { |
||
3178 | + case TK_INT: |
||
3179 | + setivalue(n,i); return n; |
||
3180 | + case TK_NUMBER: |
||
3181 | + setnvalue(n,d); return n; |
||
3182 | +#ifdef LNUM_COMPLEX |
||
3183 | + case TK_NUMBER2: /* "N.NNNi", != 0 */ |
||
3184 | + setnvalue_complex_fast(n, d*I); return n; |
||
3185 | +#endif |
||
3186 | + } |
||
3187 | + } |
||
3188 | + return NULL; |
||
3189 | } |
||
3190 | |||
3191 | |||
3192 | @@ -49,8 +62,7 @@ int luaV_tostring (lua_State *L, StkId o |
||
3193 | return 0; |
||
3194 | else { |
||
3195 | char s[LUAI_MAXNUMBER2STR]; |
||
3196 | - lua_Number n = nvalue(obj); |
||
3197 | - lua_number2str(s, n); |
||
3198 | + luaO_num2buf(s,obj); |
||
3199 | setsvalue2s(L, obj, luaS_new(L, s)); |
||
3200 | return 1; |
||
3201 | } |
||
3202 | @@ -222,59 +234,127 @@ static int l_strcmp (const TString *ls, |
||
3203 | } |
||
3204 | |||
3205 | |||
3206 | +#ifdef LNUM_COMPLEX |
||
3207 | +void error_complex( lua_State *L, const TValue *l, const TValue *r ) |
||
3208 | +{ |
||
3209 | + char buf1[ LUAI_MAXNUMBER2STR ]; |
||
3210 | + char buf2[ LUAI_MAXNUMBER2STR ]; |
||
3211 | + luaO_num2buf( buf1, l ); |
||
3212 | + luaO_num2buf( buf2, r ); |
||
3213 | + luaG_runerror( L, "unable to compare: %s with %s", buf1, buf2 ); |
||
3214 | + /* no return */ |
||
3215 | +} |
||
3216 | +#endif |
||
3217 | + |
||
3218 | + |
||
3219 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { |
||
3220 | int res; |
||
3221 | - if (ttype(l) != ttype(r)) |
||
3222 | + int tl,tr; |
||
3223 | + lua_Integer tmp; |
||
3224 | + |
||
3225 | + if (!ttype_ext_same(l,r)) |
||
3226 | return luaG_ordererror(L, l, r); |
||
3227 | - else if (ttisnumber(l)) |
||
3228 | - return luai_numlt(nvalue(l), nvalue(r)); |
||
3229 | - else if (ttisstring(l)) |
||
3230 | - return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; |
||
3231 | - else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) |
||
3232 | +#ifdef LNUM_COMPLEX |
||
3233 | + if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) ) |
||
3234 | + error_complex( L, l, r ); |
||
3235 | +#endif |
||
3236 | + tl= ttype(l); tr= ttype(r); |
||
3237 | + if (tl==tr) { /* clear arithmetics */ |
||
3238 | + switch(tl) { |
||
3239 | + case LUA_TINT: return ivalue(l) < ivalue(r); |
||
3240 | + case LUA_TNUMBER: return luai_numlt(nvalue_fast(l), nvalue_fast(r)); |
||
3241 | + case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; |
||
3242 | + } |
||
3243 | + } else if (tl==LUA_TINT) { /* l:int, r:num */ |
||
3244 | + /* Avoid accuracy losing casts: if 'r' is integer by value, do comparisons |
||
3245 | + * in integer realm. Only otherwise cast 'l' to FP (which might change its |
||
3246 | + * value). |
||
3247 | + */ |
||
3248 | + if (tt_integer_valued(r,&tmp)) |
||
3249 | + return ivalue(l) < tmp; |
||
3250 | + else |
||
3251 | + return luai_numlt( cast_num(ivalue(l)), nvalue_fast(r) ); |
||
3252 | + |
||
3253 | + } else if (tl==LUA_TNUMBER) { /* l:num, r:int */ |
||
3254 | + if (tt_integer_valued(l,&tmp)) |
||
3255 | + return tmp < ivalue(r); |
||
3256 | + else |
||
3257 | + return luai_numlt( nvalue_fast(l), cast_num(ivalue(r)) ); |
||
3258 | + |
||
3259 | + } else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) |
||
3260 | return res; |
||
3261 | + |
||
3262 | return luaG_ordererror(L, l, r); |
||
3263 | } |
||
3264 | |||
3265 | |||
3266 | static int lessequal (lua_State *L, const TValue *l, const TValue *r) { |
||
3267 | int res; |
||
3268 | - if (ttype(l) != ttype(r)) |
||
3269 | + int tl, tr; |
||
3270 | + lua_Integer tmp; |
||
3271 | + |
||
3272 | + if (!ttype_ext_same(l,r)) |
||
3273 | return luaG_ordererror(L, l, r); |
||
3274 | - else if (ttisnumber(l)) |
||
3275 | - return luai_numle(nvalue(l), nvalue(r)); |
||
3276 | - else if (ttisstring(l)) |
||
3277 | - return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; |
||
3278 | - else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ |
||
3279 | +#ifdef LNUM_COMPLEX |
||
3280 | + if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) ) |
||
3281 | + error_complex( L, l, r ); |
||
3282 | +#endif |
||
3283 | + tl= ttype(l); tr= ttype(r); |
||
3284 | + if (tl==tr) { /* clear arithmetics */ |
||
3285 | + switch(tl) { |
||
3286 | + case LUA_TINT: return ivalue(l) <= ivalue(r); |
||
3287 | + case LUA_TNUMBER: return luai_numle(nvalue_fast(l), nvalue_fast(r)); |
||
3288 | + case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; |
||
3289 | + } |
||
3290 | + } |
||
3291 | + if (tl==LUA_TINT) { /* l:int, r:num */ |
||
3292 | + if (tt_integer_valued(r,&tmp)) |
||
3293 | + return ivalue(l) <= tmp; |
||
3294 | + else |
||
3295 | + return luai_numle( cast_num(ivalue(l)), nvalue_fast(r) ); |
||
3296 | + |
||
3297 | + } else if (tl==LUA_TNUMBER) { /* l:num, r:int */ |
||
3298 | + if (tt_integer_valued(l,&tmp)) |
||
3299 | + return tmp <= ivalue(r); |
||
3300 | + else |
||
3301 | + return luai_numle( nvalue_fast(l), cast_num(ivalue(r)) ); |
||
3302 | + |
||
3303 | + } else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ |
||
3304 | return res; |
||
3305 | else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ |
||
3306 | return !res; |
||
3307 | + |
||
3308 | return luaG_ordererror(L, l, r); |
||
3309 | } |
||
3310 | |||
3311 | |||
3312 | -int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { |
||
3313 | +/* Note: 'luaV_equalval()' and 'luaO_rawequalObj()' have largely overlapping |
||
3314 | + * implementation. LUA_TNIL..LUA_TLIGHTUSERDATA cases could be handled |
||
3315 | + * simply by the 'default' case here. |
||
3316 | + */ |
||
3317 | +int luaV_equalval (lua_State *L, const TValue *l, const TValue *r) { |
||
3318 | const TValue *tm; |
||
3319 | - lua_assert(ttype(t1) == ttype(t2)); |
||
3320 | - switch (ttype(t1)) { |
||
3321 | + lua_assert(ttype_ext_same(l,r)); |
||
3322 | + switch (ttype(l)) { |
||
3323 | case LUA_TNIL: return 1; |
||
3324 | - case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); |
||
3325 | - case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ |
||
3326 | - case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); |
||
3327 | + case LUA_TINT: |
||
3328 | + case LUA_TNUMBER: return luaO_rawequalObj(l,r); |
||
3329 | + case LUA_TBOOLEAN: return bvalue(l) == bvalue(r); /* true must be 1 !! */ |
||
3330 | + case LUA_TLIGHTUSERDATA: return pvalue(l) == pvalue(r); |
||
3331 | case LUA_TUSERDATA: { |
||
3332 | - if (uvalue(t1) == uvalue(t2)) return 1; |
||
3333 | - tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, |
||
3334 | - TM_EQ); |
||
3335 | + if (uvalue(l) == uvalue(r)) return 1; |
||
3336 | + tm = get_compTM(L, uvalue(l)->metatable, uvalue(r)->metatable, TM_EQ); |
||
3337 | break; /* will try TM */ |
||
3338 | } |
||
3339 | case LUA_TTABLE: { |
||
3340 | - if (hvalue(t1) == hvalue(t2)) return 1; |
||
3341 | - tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); |
||
3342 | + if (hvalue(l) == hvalue(r)) return 1; |
||
3343 | + tm = get_compTM(L, hvalue(l)->metatable, hvalue(r)->metatable, TM_EQ); |
||
3344 | break; /* will try TM */ |
||
3345 | } |
||
3346 | - default: return gcvalue(t1) == gcvalue(t2); |
||
3347 | + default: return gcvalue(l) == gcvalue(r); |
||
3348 | } |
||
3349 | if (tm == NULL) return 0; /* no TM? */ |
||
3350 | - callTMres(L, L->top, tm, t1, t2); /* call TM */ |
||
3351 | + callTMres(L, L->top, tm, l, r); /* call TM */ |
||
3352 | return !l_isfalse(L->top); |
||
3353 | } |
||
3354 | |||
3355 | @@ -314,30 +394,6 @@ void luaV_concat (lua_State *L, int tota |
||
3356 | } |
||
3357 | |||
3358 | |||
3359 | -static void Arith (lua_State *L, StkId ra, const TValue *rb, |
||
3360 | - const TValue *rc, TMS op) { |
||
3361 | - TValue tempb, tempc; |
||
3362 | - const TValue *b, *c; |
||
3363 | - if ((b = luaV_tonumber(rb, &tempb)) != NULL && |
||
3364 | - (c = luaV_tonumber(rc, &tempc)) != NULL) { |
||
3365 | - lua_Number nb = nvalue(b), nc = nvalue(c); |
||
3366 | - switch (op) { |
||
3367 | - case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; |
||
3368 | - case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; |
||
3369 | - case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; |
||
3370 | - case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; |
||
3371 | - case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; |
||
3372 | - case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; |
||
3373 | - case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; |
||
3374 | - default: lua_assert(0); break; |
||
3375 | - } |
||
3376 | - } |
||
3377 | - else if (!call_binTM(L, rb, rc, ra, op)) |
||
3378 | - luaG_aritherror(L, rb, rc); |
||
3379 | -} |
||
3380 | - |
||
3381 | - |
||
3382 | - |
||
3383 | /* |
||
3384 | ** some macros for common tasks in `luaV_execute' |
||
3385 | */ |
||
3386 | @@ -361,17 +417,154 @@ static void Arith (lua_State *L, StkId r |
||
3387 | #define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } |
||
3388 | |||
3389 | |||
3390 | -#define arith_op(op,tm) { \ |
||
3391 | - TValue *rb = RKB(i); \ |
||
3392 | - TValue *rc = RKC(i); \ |
||
3393 | - if (ttisnumber(rb) && ttisnumber(rc)) { \ |
||
3394 | - lua_Number nb = nvalue(rb), nc = nvalue(rc); \ |
||
3395 | - setnvalue(ra, op(nb, nc)); \ |
||
3396 | - } \ |
||
3397 | - else \ |
||
3398 | - Protect(Arith(L, ra, rb, rc, tm)); \ |
||
3399 | +/* Note: if called for unary operations, 'rc'=='rb'. |
||
3400 | + */ |
||
3401 | +static void Arith (lua_State *L, StkId ra, const TValue *rb, |
||
3402 | + const TValue *rc, TMS op) { |
||
3403 | + TValue tempb, tempc; |
||
3404 | + const TValue *b, *c; |
||
3405 | + lua_Number nb,nc; |
||
3406 | + |
||
3407 | + if ((b = luaV_tonumber(rb, &tempb)) != NULL && |
||
3408 | + (c = luaV_tonumber(rc, &tempc)) != NULL) { |
||
3409 | + |
||
3410 | + /* Keep integer arithmetics in the integer realm, if possible. |
||
3411 | + */ |
||
3412 | + if (ttisint(b) && ttisint(c)) { |
||
3413 | + lua_Integer ib = ivalue(b), ic = ivalue(c); |
||
3414 | + lua_Integer *ri = &ra->value.i; |
||
3415 | + ra->tt= LUA_TINT; /* part of 'setivalue(ra)' */ |
||
3416 | + switch (op) { |
||
3417 | + case TM_ADD: if (try_addint( ri, ib, ic)) return; break; |
||
3418 | + case TM_SUB: if (try_subint( ri, ib, ic)) return; break; |
||
3419 | + case TM_MUL: if (try_mulint( ri, ib, ic)) return; break; |
||
3420 | + case TM_DIV: if (try_divint( ri, ib, ic)) return; break; |
||
3421 | + case TM_MOD: if (try_modint( ri, ib, ic)) return; break; |
||
3422 | + case TM_POW: if (try_powint( ri, ib, ic)) return; break; |
||
3423 | + case TM_UNM: if (try_unmint( ri, ib)) return; break; |
||
3424 | + default: lua_assert(0); |
||
3425 | } |
||
3426 | + } |
||
3427 | + /* Fallback to floating point, when leaving range. */ |
||
3428 | |||
3429 | +#ifdef LNUM_COMPLEX |
||
3430 | + if ((nvalue_img(b)!=0) || (nvalue_img(c)!=0)) { |
||
3431 | + lua_Complex r; |
||
3432 | + if (op==TM_UNM) { |
||
3433 | + r= -nvalue_complex_fast(b); /* never an integer (or scalar) */ |
||
3434 | + setnvalue_complex_fast( ra, r ); |
||
3435 | + } else { |
||
3436 | + lua_Complex bb= nvalue_complex(b), cc= nvalue_complex(c); |
||
3437 | + switch (op) { |
||
3438 | + case TM_ADD: r= bb + cc; break; |
||
3439 | + case TM_SUB: r= bb - cc; break; |
||
3440 | + case TM_MUL: r= bb * cc; break; |
||
3441 | + case TM_DIV: r= bb / cc; break; |
||
3442 | + case TM_MOD: |
||
3443 | + luaG_runerror(L, "attempt to use %% on complex numbers"); /* no return */ |
||
3444 | + case TM_POW: r= luai_vectpow( bb, cc ); break; |
||
3445 | + default: lua_assert(0); r=0; |
||
3446 | + } |
||
3447 | + setnvalue_complex( ra, r ); |
||
3448 | + } |
||
3449 | + return; |
||
3450 | + } |
||
3451 | +#endif |
||
3452 | + nb = nvalue(b); nc = nvalue(c); |
||
3453 | + switch (op) { |
||
3454 | + case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); return; |
||
3455 | + case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); return; |
||
3456 | + case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); return; |
||
3457 | + case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); return; |
||
3458 | + case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); return; |
||
3459 | + case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); return; |
||
3460 | + case TM_UNM: setnvalue(ra, luai_numunm(nb)); return; |
||
3461 | + default: lua_assert(0); |
||
3462 | + } |
||
3463 | + } |
||
3464 | + |
||
3465 | + /* Either operand not a number */ |
||
3466 | + if (!call_binTM(L, rb, rc, ra, op)) |
||
3467 | + luaG_aritherror(L, rb, rc); |
||
3468 | +} |
||
3469 | + |
||
3470 | +/* Helper macro to sort arithmetic operations into four categories: |
||
3471 | + * TK_INT: integer - integer operands |
||
3472 | + * TK_NUMBER: number - number (non complex, either may be integer) |
||
3473 | + * TK_NUMBER2: complex numbers (at least the other) |
||
3474 | + * 0: non-numeric (at least the other) |
||
3475 | +*/ |
||
3476 | +#ifdef LNUM_COMPLEX |
||
3477 | +static inline int arith_mode( const TValue *rb, const TValue *rc ) { |
||
3478 | + if (ttisint(rb) && ttisint(rc)) return TK_INT; |
||
3479 | + if (ttiscomplex(rb) || ttiscomplex(rc)) return TK_NUMBER2; |
||
3480 | + if (ttisnumber(rb) && ttisnumber(rc)) return TK_NUMBER; |
||
3481 | + return 0; |
||
3482 | +} |
||
3483 | +#else |
||
3484 | +# define arith_mode(rb,rc) \ |
||
3485 | + ( (ttisint(rb) && ttisint(rc)) ? TK_INT : \ |
||
3486 | + (ttisnumber(rb) && ttisnumber(rc)) ? TK_NUMBER : 0 ) |
||
3487 | +#endif |
||
3488 | + |
||
3489 | +/* arith_op macro for two operators: |
||
3490 | + * automatically chooses, which function (number, integer, complex) to use |
||
3491 | + */ |
||
3492 | +#define ARITH_OP2_START( op_num, op_int ) \ |
||
3493 | + int failed= 0; \ |
||
3494 | + switch( arith_mode(rb,rc) ) { \ |
||
3495 | + case TK_INT: \ |
||
3496 | + if (op_int ( &(ra)->value.i, ivalue(rb), ivalue(rc) )) \ |
||
3497 | + { ra->tt= LUA_TINT; break; } /* else flow through */ \ |
||
3498 | + case TK_NUMBER: \ |
||
3499 | + setnvalue(ra, op_num ( nvalue(rb), nvalue(rc) )); break; |
||
3500 | + |
||
3501 | +#define ARITH_OP2_END \ |
||
3502 | + default: \ |
||
3503 | + failed= 1; break; \ |
||
3504 | + } if (!failed) continue; |
||
3505 | + |
||
3506 | +#define arith_op_continue_scalar( op_num, op_int ) \ |
||
3507 | + ARITH_OP2_START( op_num, op_int ) \ |
||
3508 | + ARITH_OP2_END |
||
3509 | + |
||
3510 | +#ifdef LNUM_COMPLEX |
||
3511 | +# define arith_op_continue( op_num, op_int, op_complex ) \ |
||
3512 | + ARITH_OP2_START( op_num, op_int ) \ |
||
3513 | + case TK_NUMBER2: \ |
||
3514 | + setnvalue_complex( ra, op_complex ( nvalue_complex(rb), nvalue_complex(rc) ) ); break; \ |
||
3515 | + ARITH_OP2_END |
||
3516 | +#else |
||
3517 | +# define arith_op_continue(op_num,op_int,_) arith_op_continue_scalar(op_num,op_int) |
||
3518 | +#endif |
||
3519 | + |
||
3520 | +/* arith_op macro for one operator: |
||
3521 | + */ |
||
3522 | +#define ARITH_OP1_START( op_num, op_int ) \ |
||
3523 | + int failed= 0; \ |
||
3524 | + switch( arith_mode(rb,rb) ) { \ |
||
3525 | + case TK_INT: \ |
||
3526 | + if (op_int ( &(ra)->value.i, ivalue(rb) )) \ |
||
3527 | + { ra->tt= LUA_TINT; break; } /* else flow through */ \ |
||
3528 | + case TK_NUMBER: \ |
||
3529 | + setnvalue(ra, op_num (nvalue(rb))); break; \ |
||
3530 | + |
||
3531 | +#define ARITH_OP1_END \ |
||
3532 | + default: \ |
||
3533 | + failed= 1; break; \ |
||
3534 | + } if (!failed) continue; |
||
3535 | + |
||
3536 | +#ifdef LNUM_COMPLEX |
||
3537 | +# define arith_op1_continue( op_num, op_int, op_complex ) \ |
||
3538 | + ARITH_OP1_START( op_num, op_int ) \ |
||
3539 | + case TK_NUMBER2: \ |
||
3540 | + setnvalue_complex( ra, op_complex ( nvalue_complex_fast(rb) )); break; \ |
||
3541 | + ARITH_OP1_END |
||
3542 | +#else |
||
3543 | +# define arith_op1_continue( op_num, op_int, _ ) \ |
||
3544 | + ARITH_OP1_START( op_num, op_int ) \ |
||
3545 | + ARITH_OP1_END |
||
3546 | +#endif |
||
3547 | |||
3548 | |||
3549 | void luaV_execute (lua_State *L, int nexeccalls) { |
||
3550 | @@ -472,38 +665,45 @@ void luaV_execute (lua_State *L, int nex |
||
3551 | continue; |
||
3552 | } |
||
3553 | case OP_ADD: { |
||
3554 | - arith_op(luai_numadd, TM_ADD); |
||
3555 | + TValue *rb = RKB(i), *rc= RKC(i); |
||
3556 | + arith_op_continue( luai_numadd, try_addint, luai_vectadd ); |
||
3557 | + Protect(Arith(L, ra, rb, rc, TM_ADD)); \ |
||
3558 | continue; |
||
3559 | } |
||
3560 | case OP_SUB: { |
||
3561 | - arith_op(luai_numsub, TM_SUB); |
||
3562 | + TValue *rb = RKB(i), *rc= RKC(i); |
||
3563 | + arith_op_continue( luai_numsub, try_subint, luai_vectsub ); |
||
3564 | + Protect(Arith(L, ra, rb, rc, TM_SUB)); |
||
3565 | continue; |
||
3566 | } |
||
3567 | case OP_MUL: { |
||
3568 | - arith_op(luai_nummul, TM_MUL); |
||
3569 | + TValue *rb = RKB(i), *rc= RKC(i); |
||
3570 | + arith_op_continue(luai_nummul, try_mulint, luai_vectmul); |
||
3571 | + Protect(Arith(L, ra, rb, rc, TM_MUL)); |
||
3572 | continue; |
||
3573 | } |
||
3574 | case OP_DIV: { |
||
3575 | - arith_op(luai_numdiv, TM_DIV); |
||
3576 | + TValue *rb = RKB(i), *rc= RKC(i); |
||
3577 | + arith_op_continue(luai_numdiv, try_divint, luai_vectdiv); |
||
3578 | + Protect(Arith(L, ra, rb, rc, TM_DIV)); |
||
3579 | continue; |
||
3580 | } |
||
3581 | case OP_MOD: { |
||
3582 | - arith_op(luai_nummod, TM_MOD); |
||
3583 | + TValue *rb = RKB(i), *rc= RKC(i); |
||
3584 | + arith_op_continue_scalar(luai_nummod, try_modint); /* scalars only */ |
||
3585 | + Protect(Arith(L, ra, rb, rc, TM_MOD)); |
||
3586 | continue; |
||
3587 | } |
||
3588 | case OP_POW: { |
||
3589 | - arith_op(luai_numpow, TM_POW); |
||
3590 | + TValue *rb = RKB(i), *rc= RKC(i); |
||
3591 | + arith_op_continue(luai_numpow, try_powint, luai_vectpow); |
||
3592 | + Protect(Arith(L, ra, rb, rc, TM_POW)); |
||
3593 | continue; |
||
3594 | } |
||
3595 | case OP_UNM: { |
||
3596 | TValue *rb = RB(i); |
||
3597 | - if (ttisnumber(rb)) { |
||
3598 | - lua_Number nb = nvalue(rb); |
||
3599 | - setnvalue(ra, luai_numunm(nb)); |
||
3600 | - } |
||
3601 | - else { |
||
3602 | - Protect(Arith(L, ra, rb, rb, TM_UNM)); |
||
3603 | - } |
||
3604 | + arith_op1_continue(luai_numunm, try_unmint, luai_vectunm); |
||
3605 | + Protect(Arith(L, ra, rb, rb, TM_UNM)); |
||
3606 | continue; |
||
3607 | } |
||
3608 | case OP_NOT: { |
||
3609 | @@ -515,11 +715,11 @@ void luaV_execute (lua_State *L, int nex |
||
3610 | const TValue *rb = RB(i); |
||
3611 | switch (ttype(rb)) { |
||
3612 | case LUA_TTABLE: { |
||
3613 | - setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); |
||
3614 | + setivalue(ra, luaH_getn(hvalue(rb))); |
||
3615 | break; |
||
3616 | } |
||
3617 | case LUA_TSTRING: { |
||
3618 | - setnvalue(ra, cast_num(tsvalue(rb)->len)); |
||
3619 | + setivalue(ra, tsvalue(rb)->len); |
||
3620 | break; |
||
3621 | } |
||
3622 | default: { /* try metamethod */ |
||
3623 | @@ -652,14 +852,30 @@ void luaV_execute (lua_State *L, int nex |
||
3624 | } |
||
3625 | } |
||
3626 | case OP_FORLOOP: { |
||
3627 | - lua_Number step = nvalue(ra+2); |
||
3628 | - lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ |
||
3629 | - lua_Number limit = nvalue(ra+1); |
||
3630 | - if (luai_numlt(0, step) ? luai_numle(idx, limit) |
||
3631 | - : luai_numle(limit, idx)) { |
||
3632 | - dojump(L, pc, GETARG_sBx(i)); /* jump back */ |
||
3633 | - setnvalue(ra, idx); /* update internal index... */ |
||
3634 | - setnvalue(ra+3, idx); /* ...and external index */ |
||
3635 | + /* If start,step and limit are all integers, we don't need to check |
||
3636 | + * against overflow in the looping. |
||
3637 | + */ |
||
3638 | + if (ttisint(ra) && ttisint(ra+1) && ttisint(ra+2)) { |
||
3639 | + lua_Integer step = ivalue(ra+2); |
||
3640 | + lua_Integer idx = ivalue(ra) + step; /* increment index */ |
||
3641 | + lua_Integer limit = ivalue(ra+1); |
||
3642 | + if (step > 0 ? (idx <= limit) : (limit <= idx)) { |
||
3643 | + dojump(L, pc, GETARG_sBx(i)); /* jump back */ |
||
3644 | + setivalue(ra, idx); /* update internal index... */ |
||
3645 | + setivalue(ra+3, idx); /* ...and external index */ |
||
3646 | + } |
||
3647 | + } else { |
||
3648 | + /* non-integer looping (don't use 'nvalue_fast', some may be integer!) |
||
3649 | + */ |
||
3650 | + lua_Number step = nvalue(ra+2); |
||
3651 | + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ |
||
3652 | + lua_Number limit = nvalue(ra+1); |
||
3653 | + if (luai_numlt(0, step) ? luai_numle(idx, limit) |
||
3654 | + : luai_numle(limit, idx)) { |
||
3655 | + dojump(L, pc, GETARG_sBx(i)); /* jump back */ |
||
3656 | + setnvalue(ra, idx); /* update internal index... */ |
||
3657 | + setnvalue(ra+3, idx); /* ...and external index */ |
||
3658 | + } |
||
3659 | } |
||
3660 | continue; |
||
3661 | } |
||
3662 | @@ -668,13 +884,21 @@ void luaV_execute (lua_State *L, int nex |
||
3663 | const TValue *plimit = ra+1; |
||
3664 | const TValue *pstep = ra+2; |
||
3665 | L->savedpc = pc; /* next steps may throw errors */ |
||
3666 | + /* Using same location for tonumber's both arguments, effectively does |
||
3667 | + * in-place modification (string->number). */ |
||
3668 | if (!tonumber(init, ra)) |
||
3669 | luaG_runerror(L, LUA_QL("for") " initial value must be a number"); |
||
3670 | else if (!tonumber(plimit, ra+1)) |
||
3671 | luaG_runerror(L, LUA_QL("for") " limit must be a number"); |
||
3672 | else if (!tonumber(pstep, ra+2)) |
||
3673 | luaG_runerror(L, LUA_QL("for") " step must be a number"); |
||
3674 | - setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); |
||
3675 | + /* Step back one value (keep within integers if we can) |
||
3676 | + */ |
||
3677 | + if (!( ttisint(ra) && ttisint(pstep) && |
||
3678 | + try_subint( &ra->value.i, ivalue(ra), ivalue(pstep) ) )) { |
||
3679 | + /* don't use 'nvalue_fast()', values may be integer */ |
||
3680 | + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); |
||
3681 | + } |
||
3682 | dojump(L, pc, GETARG_sBx(i)); |
||
3683 | continue; |
||
3684 | } |
||
3685 | @@ -711,7 +935,7 @@ void luaV_execute (lua_State *L, int nex |
||
3686 | luaH_resizearray(L, h, last); /* pre-alloc it at once */ |
||
3687 | for (; n > 0; n--) { |
||
3688 | TValue *val = ra+n; |
||
3689 | - setobj2t(L, luaH_setnum(L, h, last--), val); |
||
3690 | + setobj2t(L, luaH_setint(L, h, last--), val); |
||
3691 | luaC_barriert(L, h, val); |
||
3692 | } |
||
3693 | continue; |
||
3694 | --- a/src/lvm.h |
||
3695 | +++ b/src/lvm.h |
||
3696 | @@ -15,11 +15,9 @@ |
||
3697 | |||
3698 | #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) |
||
3699 | |||
3700 | -#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ |
||
3701 | - (((o) = luaV_tonumber(o,n)) != NULL)) |
||
3702 | +#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) |
||
3703 | |||
3704 | -#define equalobj(L,o1,o2) \ |
||
3705 | - (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) |
||
3706 | +#define equalobj(L,o1,o2) (ttype_ext_same(o1,o2) && luaV_equalval(L, o1, o2)) |
||
3707 | |||
3708 | |||
3709 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); |
||
3710 | --- a/src/print.c |
||
3711 | +++ b/src/print.c |
||
3712 | @@ -14,6 +14,7 @@ |
||
3713 | #include "lobject.h" |
||
3714 | #include "lopcodes.h" |
||
3715 | #include "lundump.h" |
||
3716 | +#include "lnum.h" |
||
3717 | |||
3718 | #define PrintFunction luaU_print |
||
3719 | |||
3720 | @@ -59,8 +60,16 @@ static void PrintConstant(const Proto* f |
||
3721 | case LUA_TBOOLEAN: |
||
3722 | printf(bvalue(o) ? "true" : "false"); |
||
3723 | break; |
||
3724 | + case LUA_TINT: |
||
3725 | + printf(LUA_INTEGER_FMT,ivalue(o)); |
||
3726 | + break; |
||
3727 | case LUA_TNUMBER: |
||
3728 | - printf(LUA_NUMBER_FMT,nvalue(o)); |
||
3729 | +#ifdef LNUM_COMPLEX |
||
3730 | + // TBD: Do we get complex values here? |
||
3731 | + { lua_Number b= nvalue_img_fast(o); |
||
3732 | + printf( LUA_NUMBER_FMT "%s" LUA_NUMBER_FMT "i", nvalue_fast(o), b>=0 ? "+":"", b ); } |
||
3733 | +#endif |
||
3734 | + printf(LUA_NUMBER_FMT,nvalue_fast(o)); |
||
3735 | break; |
||
3736 | case LUA_TSTRING: |
||
3737 | PrintString(rawtsvalue(o)); |