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