blob: fd398c28d1188c36fb1040dd1013d1f0ad68f12c [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001--- a/Makefile
2+++ b/Makefile
3@@ -42,7 +42,7 @@ PLATS= aix ansi bsd freebsd generic linu
4
5 # What to install.
6 TO_BIN= lua$V luac$V
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$V.1 luac$V.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-
1024+#ifdef LNUM_FLOAT
1025+# define PI (3.14159265358979323846F)
1026+#elif defined(M_PI)
1027+# define PI M_PI
1028+#else
1029+# define PI (3.14159265358979323846264338327950288)
1030+#endif
1031+#define RADIANS_PER_DEGREE (PI/180)
1032+
1033+#undef HUGE
1034+#ifdef LNUM_FLOAT
1035+# define HUGE HUGE_VALF
1036+#elif defined(LNUM_LDOUBLE)
1037+# define HUGE HUGE_VALL
1038+#else
1039+# define HUGE HUGE_VAL
1040+#endif
1041
1042 static int math_abs (lua_State *L) {
1043- lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
1044+#ifdef LNUM_COMPLEX
1045+ lua_pushnumber(L, _LF(cabs) (luaL_checkcomplex(L,1)));
1046+#else
1047+ lua_pushnumber(L, _LF(fabs) (luaL_checknumber(L, 1)));
1048+#endif
1049 return 1;
1050 }
1051
1052 static int math_sin (lua_State *L) {
1053- lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
1054+#ifdef LNUM_COMPLEX
1055+ lua_pushcomplex(L, _LF(csin) (luaL_checkcomplex(L,1)));
1056+#else
1057+ lua_pushnumber(L, _LF(sin) (luaL_checknumber(L, 1)));
1058+#endif
1059 return 1;
1060 }
1061
1062 static int math_sinh (lua_State *L) {
1063- lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
1064+#ifdef LNUM_COMPLEX
1065+ lua_pushcomplex(L, _LF(csinh) (luaL_checkcomplex(L,1)));
1066+#else
1067+ lua_pushnumber(L, _LF(sinh) (luaL_checknumber(L, 1)));
1068+#endif
1069 return 1;
1070 }
1071
1072 static int math_cos (lua_State *L) {
1073- lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
1074+#ifdef LNUM_COMPLEX
1075+ lua_pushcomplex(L, _LF(ccos) (luaL_checkcomplex(L,1)));
1076+#else
1077+ lua_pushnumber(L, _LF(cos) (luaL_checknumber(L, 1)));
1078+#endif
1079 return 1;
1080 }
1081
1082 static int math_cosh (lua_State *L) {
1083- lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
1084+#ifdef LNUM_COMPLEX
1085+ lua_pushcomplex(L, _LF(ccosh) (luaL_checkcomplex(L,1)));
1086+#else
1087+ lua_pushnumber(L, _LF(cosh) (luaL_checknumber(L, 1)));
1088+#endif
1089 return 1;
1090 }
1091
1092 static int math_tan (lua_State *L) {
1093- lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
1094+#ifdef LNUM_COMPLEX
1095+ lua_pushcomplex(L, _LF(ctan) (luaL_checkcomplex(L,1)));
1096+#else
1097+ lua_pushnumber(L, _LF(tan) (luaL_checknumber(L, 1)));
1098+#endif
1099 return 1;
1100 }
1101
1102 static int math_tanh (lua_State *L) {
1103- lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
1104+#ifdef LNUM_COMPLEX
1105+ lua_pushcomplex(L, _LF(ctanh) (luaL_checkcomplex(L,1)));
1106+#else
1107+ lua_pushnumber(L, _LF(tanh) (luaL_checknumber(L, 1)));
1108+#endif
1109 return 1;
1110 }
1111
1112 static int math_asin (lua_State *L) {
1113- lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
1114+#ifdef LNUM_COMPLEX
1115+ lua_pushcomplex(L, _LF(casin) (luaL_checkcomplex(L,1)));
1116+#else
1117+ lua_pushnumber(L, _LF(asin) (luaL_checknumber(L, 1)));
1118+#endif
1119 return 1;
1120 }
1121
1122 static int math_acos (lua_State *L) {
1123- lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
1124+#ifdef LNUM_COMPLEX
1125+ lua_pushcomplex(L, _LF(cacos) (luaL_checkcomplex(L,1)));
1126+#else
1127+ lua_pushnumber(L, _LF(acos) (luaL_checknumber(L, 1)));
1128+#endif
1129 return 1;
1130 }
1131
1132 static int math_atan (lua_State *L) {
1133- lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
1134+#ifdef LNUM_COMPLEX
1135+ lua_pushcomplex(L, _LF(catan) (luaL_checkcomplex(L,1)));
1136+#else
1137+ lua_pushnumber(L, _LF(atan) (luaL_checknumber(L, 1)));
1138+#endif
1139 return 1;
1140 }
1141
1142 static int math_atan2 (lua_State *L) {
1143- lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1144+ /* scalars only */
1145+ lua_pushnumber(L, _LF(atan2) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1146 return 1;
1147 }
1148
1149 static int math_ceil (lua_State *L) {
1150- lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
1151+#ifdef LNUM_COMPLEX
1152+ lua_Complex v= luaL_checkcomplex(L, 1);
1153+ lua_pushcomplex(L, _LF(ceil) (_LF(creal)(v)) + _LF(ceil) (_LF(cimag)(v))*I);
1154+#else
1155+ lua_pushnumber(L, _LF(ceil) (luaL_checknumber(L, 1)));
1156+#endif
1157 return 1;
1158 }
1159
1160 static int math_floor (lua_State *L) {
1161- lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
1162+#ifdef LNUM_COMPLEX
1163+ lua_Complex v= luaL_checkcomplex(L, 1);
1164+ lua_pushcomplex(L, _LF(floor) (_LF(creal)(v)) + _LF(floor) (_LF(cimag)(v))*I);
1165+#else
1166+ lua_pushnumber(L, _LF(floor) (luaL_checknumber(L, 1)));
1167+#endif
1168 return 1;
1169 }
1170
1171-static int math_fmod (lua_State *L) {
1172- lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1173+static int math_fmod (lua_State *L) {
1174+ /* scalars only */
1175+ lua_pushnumber(L, _LF(fmod) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1176 return 1;
1177 }
1178
1179 static int math_modf (lua_State *L) {
1180- double ip;
1181- double fp = modf(luaL_checknumber(L, 1), &ip);
1182+ /* scalars only */
1183+ lua_Number ip;
1184+ lua_Number fp = _LF(modf) (luaL_checknumber(L, 1), &ip);
1185 lua_pushnumber(L, ip);
1186 lua_pushnumber(L, fp);
1187 return 2;
1188 }
1189
1190 static int math_sqrt (lua_State *L) {
1191- lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
1192+#ifdef LNUM_COMPLEX
1193+ lua_pushcomplex(L, _LF(csqrt) (luaL_checkcomplex(L,1)));
1194+#else
1195+ lua_pushnumber(L, _LF(sqrt) (luaL_checknumber(L, 1)));
1196+#endif
1197 return 1;
1198 }
1199
1200 static int math_pow (lua_State *L) {
1201- lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1202+#ifdef LNUM_COMPLEX
1203+ /* C99 'cpow' gives somewhat inaccurate results (i.e. (-1)^2 = -1+1.2246467991474e-16i).
1204+ * 'luai_vectpow' smoothens such, reusing it is the reason we need to #include "lnum.h".
1205+ */
1206+ lua_pushcomplex(L, luai_vectpow(luaL_checkcomplex(L,1), luaL_checkcomplex(L,2)));
1207+#else
1208+ lua_pushnumber(L, _LF(pow) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1209+#endif
1210 return 1;
1211 }
1212
1213 static int math_log (lua_State *L) {
1214- lua_pushnumber(L, log(luaL_checknumber(L, 1)));
1215+#ifdef LNUM_COMPLEX
1216+ lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)));
1217+#else
1218+ lua_pushnumber(L, _LF(log) (luaL_checknumber(L, 1)));
1219+#endif
1220 return 1;
1221 }
1222
1223 static int math_log10 (lua_State *L) {
1224- lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
1225+#ifdef LNUM_COMPLEX
1226+ /* Not in standard <complex.h> , but easy to calculate: log_a(x) = log_b(x) / log_b(a)
1227+ */
1228+ lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)) / _LF(log) (10));
1229+#else
1230+ lua_pushnumber(L, _LF(log10) (luaL_checknumber(L, 1)));
1231+#endif
1232 return 1;
1233 }
1234
1235 static int math_exp (lua_State *L) {
1236- lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
1237+#ifdef LNUM_COMPLEX
1238+ lua_pushcomplex(L, _LF(cexp) (luaL_checkcomplex(L,1)));
1239+#else
1240+ lua_pushnumber(L, _LF(exp) (luaL_checknumber(L, 1)));
1241+#endif
1242 return 1;
1243 }
1244
1245@@ -138,19 +234,20 @@ static int math_rad (lua_State *L) {
1246
1247 static int math_frexp (lua_State *L) {
1248 int e;
1249- lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
1250+ lua_pushnumber(L, _LF(frexp) (luaL_checknumber(L, 1), &e));
1251 lua_pushinteger(L, e);
1252 return 2;
1253 }
1254
1255 static int math_ldexp (lua_State *L) {
1256- lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
1257+ lua_pushnumber(L, _LF(ldexp) (luaL_checknumber(L, 1), luaL_checkint(L, 2)));
1258 return 1;
1259 }
1260
1261
1262
1263 static int math_min (lua_State *L) {
1264+ /* scalars only */
1265 int n = lua_gettop(L); /* number of arguments */
1266 lua_Number dmin = luaL_checknumber(L, 1);
1267 int i;
1268@@ -165,6 +262,7 @@ static int math_min (lua_State *L) {
1269
1270
1271 static int math_max (lua_State *L) {
1272+ /* scalars only */
1273 int n = lua_gettop(L); /* number of arguments */
1274 lua_Number dmax = luaL_checknumber(L, 1);
1275 int i;
1276@@ -182,25 +280,20 @@ static int math_random (lua_State *L) {
1277 /* the `%' avoids the (rare) case of r==1, and is needed also because on
1278 some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
1279 lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
1280- switch (lua_gettop(L)) { /* check number of arguments */
1281- case 0: { /* no arguments */
1282- lua_pushnumber(L, r); /* Number between 0 and 1 */
1283- break;
1284- }
1285- case 1: { /* only upper limit */
1286- int u = luaL_checkint(L, 1);
1287- luaL_argcheck(L, 1<=u, 1, "interval is empty");
1288- lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
1289- break;
1290- }
1291- case 2: { /* lower and upper limits */
1292- int l = luaL_checkint(L, 1);
1293- int u = luaL_checkint(L, 2);
1294- luaL_argcheck(L, l<=u, 2, "interval is empty");
1295- lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
1296- break;
1297- }
1298- default: return luaL_error(L, "wrong number of arguments");
1299+ int n= lua_gettop(L); /* number of arguments */
1300+ if (n==0) { /* no arguments: range [0,1) */
1301+ lua_pushnumber(L, r);
1302+ } else if (n<=2) { /* int range [1,u] or [l,u] */
1303+ int l= n==1 ? 1 : luaL_checkint(L, 1);
1304+ int u = luaL_checkint(L, n);
1305+ int tmp;
1306+ lua_Number d;
1307+ luaL_argcheck(L, l<=u, n, "interval is empty");
1308+ d= _LF(floor)(r*(u-l+1));
1309+ lua_number2int(tmp,d);
1310+ lua_pushinteger(L, l+tmp);
1311+ } else {
1312+ return luaL_error(L, "wrong number of arguments");
1313 }
1314 return 1;
1315 }
1316@@ -211,6 +304,66 @@ static int math_randomseed (lua_State *L
1317 return 0;
1318 }
1319
1320+/*
1321+* Lua 5.1 does not have acosh, asinh, atanh for scalars (not ANSI C)
1322+*/
1323+#if __STDC_VERSION__ >= 199901L
1324+static int math_acosh (lua_State *L) {
1325+# ifdef LNUM_COMPLEX
1326+ lua_pushcomplex(L, _LF(cacosh) (luaL_checkcomplex(L,1)));
1327+# else
1328+ lua_pushnumber(L, _LF(acosh) (luaL_checknumber(L,1)));
1329+# endif
1330+ return 1;
1331+}
1332+static int math_asinh (lua_State *L) {
1333+# ifdef LNUM_COMPLEX
1334+ lua_pushcomplex(L, _LF(casinh) (luaL_checkcomplex(L,1)));
1335+# else
1336+ lua_pushnumber(L, _LF(asinh) (luaL_checknumber(L,1)));
1337+# endif
1338+ return 1;
1339+}
1340+static int math_atanh (lua_State *L) {
1341+# ifdef LNUM_COMPLEX
1342+ lua_pushcomplex(L, _LF(catanh) (luaL_checkcomplex(L,1)));
1343+# else
1344+ lua_pushnumber(L, _LF(atanh) (luaL_checknumber(L,1)));
1345+# endif
1346+ return 1;
1347+}
1348+#endif
1349+
1350+/*
1351+ * C99 complex functions, not covered above.
1352+*/
1353+#ifdef LNUM_COMPLEX
1354+static int math_arg (lua_State *L) {
1355+ lua_pushnumber(L, _LF(carg) (luaL_checkcomplex(L,1)));
1356+ return 1;
1357+}
1358+
1359+static int math_imag (lua_State *L) {
1360+ lua_pushnumber(L, _LF(cimag) (luaL_checkcomplex(L,1)));
1361+ return 1;
1362+}
1363+
1364+static int math_real (lua_State *L) {
1365+ lua_pushnumber(L, _LF(creal) (luaL_checkcomplex(L,1)));
1366+ return 1;
1367+}
1368+
1369+static int math_conj (lua_State *L) {
1370+ lua_pushcomplex(L, _LF(conj) (luaL_checkcomplex(L,1)));
1371+ return 1;
1372+}
1373+
1374+static int math_proj (lua_State *L) {
1375+ lua_pushcomplex(L, _LF(cproj) (luaL_checkcomplex(L,1)));
1376+ return 1;
1377+}
1378+#endif
1379+
1380
1381 static const luaL_Reg mathlib[] = {
1382 {"abs", math_abs},
1383@@ -241,6 +394,18 @@ static const luaL_Reg mathlib[] = {
1384 {"sqrt", math_sqrt},
1385 {"tanh", math_tanh},
1386 {"tan", math_tan},
1387+#if __STDC_VERSION__ >= 199901L
1388+ {"acosh", math_acosh},
1389+ {"asinh", math_asinh},
1390+ {"atanh", math_atanh},
1391+#endif
1392+#ifdef LNUM_COMPLEX
1393+ {"arg", math_arg},
1394+ {"imag", math_imag},
1395+ {"real", math_real},
1396+ {"conj", math_conj},
1397+ {"proj", math_proj},
1398+#endif
1399 {NULL, NULL}
1400 };
1401
1402@@ -252,8 +417,10 @@ LUALIB_API int luaopen_math (lua_State *
1403 luaL_register(L, LUA_MATHLIBNAME, mathlib);
1404 lua_pushnumber(L, PI);
1405 lua_setfield(L, -2, "pi");
1406- lua_pushnumber(L, HUGE_VAL);
1407+ lua_pushnumber(L, HUGE);
1408 lua_setfield(L, -2, "huge");
1409+ lua_pushinteger(L, LUA_INTEGER_MAX );
1410+ lua_setfield(L, -2, "hugeint");
1411 #if defined(LUA_COMPAT_MOD)
1412 lua_getfield(L, -1, "fmod");
1413 lua_setfield(L, -2, "mod");
1414--- /dev/null
1415+++ b/src/lnum.c
1416@@ -0,0 +1,312 @@
1417+/*
1418+** $Id: lnum.c,v ... $
1419+** Internal number model
1420+** See Copyright Notice in lua.h
1421+*/
1422+
1423+#include <stdlib.h>
1424+#include <math.h>
1425+#include <ctype.h>
1426+#include <string.h>
1427+#include <stdio.h>
1428+#include <errno.h>
1429+
1430+#define lnum_c
1431+#define LUA_CORE
1432+
1433+#include "lua.h"
1434+#include "llex.h"
1435+#include "lnum.h"
1436+
1437+/*
1438+** lua_real2str converts a (non-complex) number to a string.
1439+** lua_str2real converts a string to a (non-complex) number.
1440+*/
1441+#define lua_real2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
1442+
1443+/*
1444+* Note: Only 'strtod()' is part of ANSI C; others are C99 and
1445+* may need '--std=c99' compiler setting (at least on Ubuntu 7.10).
1446+*
1447+* Visual C++ 2008 Express does not have 'strtof()', nor 'strtold()'.
1448+* References to '_strtold()' exist but don't compile. It seems best
1449+* to leave Windows users with DOUBLE only (or compile with MinGW).
1450+*
1451+* In practise, using '(long double)strtod' is a risky thing, since
1452+* it will cause accuracy loss in reading in numbers, and such losses
1453+* will pile up in later processing. Get a real 'strtold()' or don't
1454+* use that mode at all.
1455+*/
1456+#ifdef LNUM_DOUBLE
1457+# define lua_str2real strtod
1458+#elif defined(LNUM_FLOAT)
1459+# define lua_str2real strtof
1460+#elif defined(LNUM_LDOUBLE)
1461+# define lua_str2real strtold
1462+#endif
1463+
1464+#define lua_integer2str(s,v) sprintf((s), LUA_INTEGER_FMT, (v))
1465+
1466+/* 's' is expected to be LUAI_MAXNUMBER2STR long (enough for any number)
1467+*/
1468+void luaO_num2buf( char *s, const TValue *o )
1469+{
1470+ lua_Number n;
1471+ lua_assert( ttisnumber(o) );
1472+
1473+ /* Reason to handle integers differently is not only speed, but accuracy as
1474+ * well. We want to make any integer tostring() without roundings, at all.
1475+ */
1476+ if (ttisint(o)) {
1477+ lua_integer2str( s, ivalue(o) );
1478+ return;
1479+ }
1480+ n= nvalue_fast(o);
1481+ lua_real2str(s, n);
1482+
1483+#ifdef LNUM_COMPLEX
1484+ lua_Number n2= nvalue_img_fast(o);
1485+ if (n2!=0) { /* Postfix with +-Ni */
1486+ int re0= (n == 0);
1487+ char *s2= re0 ? s : strchr(s,'\0');
1488+ if ((!re0) && (n2>0)) *s2++= '+';
1489+ lua_real2str( s2, n2 );
1490+ strcat(s2,"i");
1491+ }
1492+#endif
1493+}
1494+
1495+/*
1496+* If a LUA_TNUMBER has integer value, give it.
1497+*/
1498+int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref ) {
1499+ lua_Number d;
1500+ lua_Integer i;
1501+
1502+ lua_assert( ttype(o)==LUA_TNUMBER );
1503+ lua_assert( ref );
1504+#ifdef LNUM_COMPLEX
1505+ if (nvalue_img_fast(o)!=0) return 0;
1506+#endif
1507+ d= nvalue_fast(o);
1508+ lua_number2integer(i, d);
1509+ if (cast_num(i) == d) {
1510+ *ref= i; return 1;
1511+ }
1512+ return 0;
1513+}
1514+
1515+/*
1516+ * Lua 5.1.3 (using 'strtod()') allows 0x+hex but not 0+octal. This is good,
1517+ * and we should NOT use 'autobase' 0 with 'strtoul[l]()' for this reason.
1518+ *
1519+ * Lua 5.1.3 allows '0x...' numbers to overflow and lose precision; this is not
1520+ * good. On Visual C++ 2008, 'strtod()' does not even take them in. Better to
1521+ * require hex values to fit 'lua_Integer' or give an error that they don't?
1522+ *
1523+ * Full hex range (0 .. 0xff..ff) is stored as integers, not to lose any bits.
1524+ * Numerical value of 0xff..ff will be -1, if used in calculations.
1525+ *
1526+ * Returns: TK_INT for a valid integer, '*endptr_ref' updated
1527+ * TK_NUMBER for seemingly numeric, to be parsed as floating point
1528+ * 0 for bad characters, not a number (or '0x' out of range)
1529+ */
1530+static int luaO_str2i (const char *s, lua_Integer *res, char **endptr_ref) {
1531+ char *endptr;
1532+ /* 'v' gets ULONG_MAX on possible overflow (which is > LUA_INTEGER_MAX);
1533+ * we don't have to check 'errno' here.
1534+ */
1535+ unsigned LUA_INTEGER v= lua_str2ul(s, &endptr, 10);
1536+ if (endptr == s) return 0; /* nothing numeric */
1537+ if (v==0 && *endptr=='x') {
1538+ errno= 0; /* needs to be set, 'strtoul[l]' does not clear it */
1539+ v= lua_str2ul(endptr+1, &endptr, 16); /* retry as hex, unsigned range */
1540+ if (errno==ERANGE) { /* clamped to 0xff..ff */
1541+#if (defined(LNUM_INT32) && !defined(LNUM_FLOAT)) || defined(LNUM_LDOUBLE)
1542+ return TK_NUMBER; /* Allow to be read as floating point (has more integer range) */
1543+#else
1544+ return 0; /* Reject the number */
1545+#endif
1546+ }
1547+ } else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
1548+ return TK_NUMBER; /* not in signed range, or has '.', 'e' etc. trailing */
1549+ }
1550+ *res= (lua_Integer)v;
1551+ *endptr_ref= endptr;
1552+ return TK_INT;
1553+}
1554+
1555+/* 0 / TK_NUMBER / TK_INT (/ TK_NUMBER2) */
1556+int luaO_str2d (const char *s, lua_Number *res_n, lua_Integer *res_i) {
1557+ char *endptr;
1558+ int ret= TK_NUMBER;
1559+ /* Check integers first, if caller is allowing.
1560+ * If 'res2'==NULL, they're only looking for floating point.
1561+ */
1562+ if (res_i) {
1563+ ret= luaO_str2i(s,res_i,&endptr);
1564+ if (ret==0) return 0;
1565+ }
1566+ if (ret==TK_NUMBER) {
1567+ lua_assert(res_n);
1568+ /* Note: Visual C++ 2008 Express 'strtod()' does not read in "0x..."
1569+ * numbers; it will read '0' and spit 'x' as endptr.
1570+ * This means hex constants not fitting in 'lua_Integer' won't
1571+ * be read in at all. What to do?
1572+ */
1573+ *res_n = lua_str2real(s, &endptr);
1574+ if (endptr == s) return 0; /* conversion failed */
1575+ /* Visual C++ 2008 'strtod()' does not allow "0x..." input. */
1576+#if defined(_MSC_VER) && !defined(LNUM_FLOAT) && !defined(LNUM_INT64)
1577+ if (*res_n==0 && *endptr=='x') {
1578+ /* Hex constant too big for 'lua_Integer' but that could fit in 'lua_Number'
1579+ * integer bits
1580+ */
1581+ unsigned __int64 v= _strtoui64( s, &endptr, 16 );
1582+ /* We just let > 64 bit values be clamped to _UI64_MAX (MSDN does not say 'errno'==ERANGE would be set) */
1583+ *res_n= cast_num(v);
1584+ if (*res_n != v) return 0; /* Would have lost accuracy */
1585+ }
1586+#endif
1587+#ifdef LNUM_COMPLEX
1588+ if (*endptr == 'i') { endptr++; ret= TK_NUMBER2; }
1589+#endif
1590+ }
1591+ if (*endptr) {
1592+ while (isspace(cast(unsigned char, *endptr))) endptr++;
1593+ if (*endptr) return 0; /* invalid trail */
1594+ }
1595+ return ret;
1596+}
1597+
1598+
1599+/* Functions for finding out, when integer operations remain in range
1600+ * (and doing them).
1601+ */
1602+int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1603+ /* Signed int overflow is undefined behavior, so catch it without causing it. */
1604+ if (ic>0) { if (ib > LUA_INTEGER_MAX - ic) return 0; /*overflow, use floats*/ }
1605+ else { if (ib < LUA_INTEGER_MIN - ic) return 0; }
1606+ *r = ib + ic;
1607+ return 1;
1608+}
1609+
1610+int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1611+ /* Signed int overflow is undefined behavior, so catch it without causing it. */
1612+ if (ic>0) { if (ib < LUA_INTEGER_MIN + ic) return 0; /*overflow, use floats*/ }
1613+ else { if (ib > LUA_INTEGER_MAX + ic) return 0; }
1614+ *r = ib - ic;
1615+ return 1;
1616+}
1617+
1618+int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1619+ if (ib!=LUA_INTEGER_MIN && ic!=LUA_INTEGER_MIN) {
1620+ lua_Integer b= luai_abs(ib), c= luai_abs(ic);
1621+ if ( (ib==0) || (LUA_INTEGER_MAX/b >= c) ) {
1622+ *r= ib*ic; /* no overflow */
1623+ return 1;
1624+ }
1625+ } else if (ib==0 || ic==0) {
1626+ *r= 0; return 1;
1627+ }
1628+
1629+ /* Result can be LUA_INTEGER_MIN; if it is, calculating it using floating
1630+ * point will not cause accuracy loss.
1631+ */
1632+ if ( luai_nummul( cast_num(ib), cast_num(ic) ) == LUA_INTEGER_MIN ) {
1633+ *r= LUA_INTEGER_MIN;
1634+ return 1;
1635+ }
1636+ return 0;
1637+}
1638+
1639+int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1640+ /* N/0: leave to float side, to give an error
1641+ */
1642+ if (ic==0) return 0;
1643+
1644+ /* N/LUA_INTEGER_MIN: always non-integer results, or 0 or +1
1645+ */
1646+ if (ic==LUA_INTEGER_MIN) {
1647+ if (ib==LUA_INTEGER_MIN) { *r=1; return 1; }
1648+ if (ib==0) { *r=0; return 1; }
1649+
1650+ /* LUA_INTEGER_MIN (-2^31|63)/N: calculate using float side (either the division
1651+ * causes non-integer results, or there is no accuracy loss in int->fp->int
1652+ * conversions (N=2,4,8,..,256 and N=2^30,2^29,..2^23).
1653+ */
1654+ } else if (ib==LUA_INTEGER_MIN) {
1655+ lua_Number d= luai_numdiv( cast_num(LUA_INTEGER_MIN), cast_num(ic) );
1656+ lua_Integer i; lua_number2integer(i,d);
1657+ if (cast_num(i)==d) { *r= i; return 1; }
1658+
1659+ } else {
1660+ /* Note: We _can_ use ANSI C mod here, even on negative values, since
1661+ * we only test for == 0 (the sign would be implementation dependent).
1662+ */
1663+ if (ib%ic == 0) { *r= ib/ic; return 1; }
1664+ }
1665+
1666+ return 0;
1667+}
1668+
1669+int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1670+ if (ic!=0) {
1671+ /* ANSI C can be trusted when b%c==0, or when values are non-negative.
1672+ * b - (floor(b/c) * c)
1673+ * -->
1674+ * + +: b - (b/c) * c (b % c can be used)
1675+ * - -: b - (b/c) * c (b % c could work, but not defined by ANSI C)
1676+ * 0 -: b - (b/c) * c (=0, b % c could work, but not defined by ANSI C)
1677+ * - +: b - (b/c-1) * c (when b!=-c)
1678+ * + -: b - (b/c-1) * c (when b!=-c)
1679+ *
1680+ * o MIN%MIN ends up 0, via overflow in calcs but that does not matter.
1681+ * o MIN%MAX ends up MAX-1 (and other such numbers), also after overflow,
1682+ * but that does not matter, results do.
1683+ */
1684+ lua_Integer v= ib % ic;
1685+ if ( v!=0 && (ib<0 || ic<0) ) {
1686+ v= ib - ((ib/ic) - ((ib<=0 && ic<0) ? 0:1)) * ic;
1687+ }
1688+ /* Result should always have same sign as 2nd argument. (PIL2) */
1689+ lua_assert( (v<0) ? (ic<0) : (v>0) ? (ic>0) : 1 );
1690+ *r= v;
1691+ return 1;
1692+ }
1693+ return 0; /* let float side return NaN */
1694+}
1695+
1696+int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1697+
1698+ /* In FLOAT/INT32 or FLOAT|DOUBLE/INT64 modes, calculating integer powers
1699+ * via FP realm may lose accuracy (i.e. 7^11 = 1977326743, which fits int32
1700+ * but not 23-bit float mantissa).
1701+ *
1702+ * The current solution is dumb, but it works and uses little code. Use of
1703+ * integer powers is not anticipated to be very frequent (apart from 2^x,
1704+ * which is separately optimized).
1705+ */
1706+ if (ib==0) *r=0;
1707+ else if (ic<0) return 0; /* FP realm */
1708+ else if (ib==2 && ic < (int)sizeof(lua_Integer)*8-1) *r= ((lua_Integer)1)<<ic; /* 1,2,4,...2^30 | 2^62 optimization */
1709+ else if (ic==0) *r=1;
1710+ else if (luai_abs(ib)==1) *r= (ic%2) ? ib:1;
1711+ else {
1712+ lua_Integer x= ib;
1713+ while( --ic ) {
1714+ if (!try_mulint( &x, x, ib ))
1715+ return 0; /* FP realm */
1716+ }
1717+ *r= x;
1718+ }
1719+ return 1;
1720+}
1721+
1722+int try_unmint( lua_Integer *r, lua_Integer ib ) {
1723+ /* Negating LUA_INTEGER_MIN leaves the range. */
1724+ if ( ib != LUA_INTEGER_MIN )
1725+ { *r= -ib; return 1; }
1726+ return 0;
1727+}
1728+
1729--- /dev/null
1730+++ b/src/lnum.h
1731@@ -0,0 +1,116 @@
1732+/*
1733+** $Id: lnum.h,v ... $
1734+** Internal Number model
1735+** See Copyright Notice in lua.h
1736+*/
1737+
1738+#ifndef lnum_h
1739+#define lnum_h
1740+
1741+#include <math.h>
1742+
1743+#include "lobject.h"
1744+
1745+/*
1746+** The luai_num* macros define the primitive operations over 'lua_Number's
1747+** (not 'lua_Integer's, not 'lua_Complex').
1748+*/
1749+#define luai_numadd(a,b) ((a)+(b))
1750+#define luai_numsub(a,b) ((a)-(b))
1751+#define luai_nummul(a,b) ((a)*(b))
1752+#define luai_numdiv(a,b) ((a)/(b))
1753+#define luai_nummod(a,b) ((a) - _LF(floor)((a)/(b))*(b))
1754+#define luai_numpow(a,b) (_LF(pow)(a,b))
1755+#define luai_numunm(a) (-(a))
1756+#define luai_numeq(a,b) ((a)==(b))
1757+#define luai_numlt(a,b) ((a)<(b))
1758+#define luai_numle(a,b) ((a)<=(b))
1759+#define luai_numisnan(a) (!luai_numeq((a), (a)))
1760+
1761+int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1762+int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1763+int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1764+int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1765+int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1766+int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1767+int try_unmint( lua_Integer *r, lua_Integer ib );
1768+
1769+#ifdef LNUM_COMPLEX
1770+ static inline lua_Complex luai_vectunm( lua_Complex a ) { return -a; }
1771+ static inline lua_Complex luai_vectadd( lua_Complex a, lua_Complex b ) { return a+b; }
1772+ static inline lua_Complex luai_vectsub( lua_Complex a, lua_Complex b ) { return a-b; }
1773+ static inline lua_Complex luai_vectmul( lua_Complex a, lua_Complex b ) { return a*b; }
1774+ static inline lua_Complex luai_vectdiv( lua_Complex a, lua_Complex b ) { return a/b; }
1775+
1776+/*
1777+ * C99 does not provide modulus for complex numbers. It most likely is not
1778+ * meaningful at all.
1779+ */
1780+
1781+/*
1782+ * Complex power
1783+ *
1784+ * C99 'cpow' gives inaccurate results for many common cases s.a. (1i)^2 ->
1785+ * -1+1.2246467991474e-16i (OS X 10.4, gcc 4.0.1 build 5367)
1786+ *
1787+ * [(a+bi)^(c+di)] = (r^c) * exp(-d*t) * cos(c*t + d*ln(r)) +
1788+ * = (r^c) * exp(-d*t) * sin(c*t + d*ln(r)) *i
1789+ * r = sqrt(a^2+b^2), t = arctan( b/a )
1790+ *
1791+ * Reference: <http://home.att.net/~srschmitt/complexnumbers.html>
1792+ * Could also be calculated using: x^y = exp(ln(x)*y)
1793+ *
1794+ * Note: Defined here (and not in .c) so 'lmathlib.c' can share the
1795+ * implementation.
1796+ */
1797+ static inline
1798+ lua_Complex luai_vectpow( lua_Complex a, lua_Complex b )
1799+ {
1800+# if 1
1801+ lua_Number ar= _LF(creal)(a), ai= _LF(cimag)(a);
1802+ lua_Number br= _LF(creal)(b), bi= _LF(cimag)(b);
1803+
1804+ if (ai==0 && bi==0) { /* a^c (real) */
1805+ return luai_numpow( ar, br );
1806+ }
1807+
1808+ int br_int= (int)br;
1809+
1810+ if ( ai!=0 && bi==0 && br_int==br && br_int!=0 && br_int!=INT_MIN ) {
1811+ /* (a+bi)^N, N = { +-1,+-2, ... +-INT_MAX }
1812+ */
1813+ lua_Number k= luai_numpow( _LF(sqrt) (ar*ar + ai*ai), br );
1814+ lua_Number cos_z, sin_z;
1815+
1816+ /* Situation depends upon c (N) in the following manner:
1817+ *
1818+ * N%4==0 => cos(c*t)=1, sin(c*t)=0
1819+ * (N*sign(b))%4==1 or (N*sign(b))%4==-3 => cos(c*t)=0, sin(c*t)=1
1820+ * N%4==2 or N%4==-2 => cos(c*t)=-1, sin(c*t)=0
1821+ * (N*sign(b))%4==-1 or (N*sign(b))%4==3 => cos(c*t)=0, sin(c*t)=-1
1822+ */
1823+ int br_int_abs = br_int<0 ? -br_int:br_int;
1824+
1825+ switch( (br_int_abs%4) * (br_int<0 ? -1:1) * (ai<0 ? -1:1) ) {
1826+ case 0: cos_z=1, sin_z=0; break;
1827+ case 2: case -2: cos_z=-1, sin_z=0; break;
1828+ case 1: case -3: cos_z=0, sin_z=1; break;
1829+ case 3: case -1: cos_z=0, sin_z=-1; break;
1830+ default: lua_assert(0); return 0;
1831+ }
1832+ return k*cos_z + (k*sin_z)*I;
1833+ }
1834+# endif
1835+ return _LF(cpow) ( a, b );
1836+ }
1837+#endif
1838+
1839+LUAI_FUNC int luaO_str2d (const char *s, lua_Number *res1, lua_Integer *res2);
1840+LUAI_FUNC void luaO_num2buf( char *s, const TValue *o );
1841+
1842+LUAI_FUNC int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref );
1843+
1844+#define luai_normalize(o) \
1845+{ lua_Integer _i; if (tt_integer_valued(o,&_i)) setivalue(o,_i); }
1846+
1847+#endif
1848--- /dev/null
1849+++ b/src/lnum_config.h
1850@@ -0,0 +1,221 @@
1851+/*
1852+** $Id: lnum_config.h,v ... $
1853+** Internal Number model
1854+** See Copyright Notice in lua.h
1855+*/
1856+
1857+#ifndef lnum_config_h
1858+#define lnum_config_h
1859+
1860+/*
1861+** Default number modes
1862+*/
1863+#if (!defined LNUM_DOUBLE) && (!defined LNUM_FLOAT) && (!defined LNUM_LDOUBLE)
1864+# define LNUM_FLOAT
1865+#endif
1866+#if (!defined LNUM_INT16) && (!defined LNUM_INT32) && (!defined LNUM_INT64)
1867+# define LNUM_INT32
1868+#endif
1869+
1870+/*
1871+** Require C99 mode for COMPLEX, FLOAT and LDOUBLE (only DOUBLE is ANSI C).
1872+*/
1873+#if defined(LNUM_COMPLEX) && (__STDC_VERSION__ < 199901L)
1874+# error "Need C99 for complex (use '--std=c99' or similar)"
1875+#elif defined(LNUM_LDOUBLE) && (__STDC_VERSION__ < 199901L) && !defined(_MSC_VER)
1876+# error "Need C99 for 'long double' (use '--std=c99' or similar)"
1877+#elif defined(LNUM_FLOAT) && (__STDC_VERSION__ < 199901L)
1878+/* LNUM_FLOAT not supported on Windows */
1879+# error "Need C99 for 'float' (use '--std=c99' or similar)"
1880+#endif
1881+
1882+/*
1883+** Number mode identifier to accompany the version string.
1884+*/
1885+#ifdef LNUM_COMPLEX
1886+# define _LNUM1 "complex "
1887+#else
1888+# define _LNUM1 ""
1889+#endif
1890+#ifdef LNUM_DOUBLE
1891+# define _LNUM2 "double"
1892+#elif defined(LNUM_FLOAT)
1893+# define _LNUM2 "float"
1894+#elif defined(LNUM_LDOUBLE)
1895+# define _LNUM2 "ldouble"
1896+#endif
1897+#ifdef LNUM_INT32
1898+# define _LNUM3 "int32"
1899+#elif defined(LNUM_INT64)
1900+# define _LNUM3 "int64"
1901+#elif defined(LNUM_INT16)
1902+# define _LNUM3 "int16"
1903+#endif
1904+#define LUA_LNUM _LNUM1 _LNUM2 " " _LNUM3
1905+
1906+/*
1907+** LUA_NUMBER is the type of floating point number in Lua
1908+** LUA_NUMBER_SCAN is the format for reading numbers.
1909+** LUA_NUMBER_FMT is the format for writing numbers.
1910+*/
1911+#ifdef LNUM_FLOAT
1912+# define LUA_NUMBER float
1913+# define LUA_NUMBER_SCAN "%f"
1914+# define LUA_NUMBER_FMT "%g"
1915+#elif (defined LNUM_DOUBLE)
1916+# define LUA_NUMBER double
1917+# define LUA_NUMBER_SCAN "%lf"
1918+# define LUA_NUMBER_FMT "%.14g"
1919+#elif (defined LNUM_LDOUBLE)
1920+# define LUA_NUMBER long double
1921+# define LUA_NUMBER_SCAN "%Lg"
1922+# define LUA_NUMBER_FMT "%.20Lg"
1923+#endif
1924+
1925+
1926+/*
1927+** LUAI_MAXNUMBER2STR: size of a buffer fitting any number->string result.
1928+**
1929+** double: 24 (sign, x.xxxxxxxxxxxxxxe+nnnn, and \0)
1930+** int64: 21 (19 digits, sign, and \0)
1931+** long double: 43 for 128-bit (sign, x.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe+nnnn, and \0)
1932+** 30 for 80-bit (sign, x.xxxxxxxxxxxxxxxxxxxxe+nnnn, and \0)
1933+*/
1934+#ifdef LNUM_LDOUBLE
1935+# define _LUAI_MN2S 44
1936+#else
1937+# define _LUAI_MN2S 24
1938+#endif
1939+
1940+#ifdef LNUM_COMPLEX
1941+# define LUAI_MAXNUMBER2STR (2*_LUAI_MN2S)
1942+#else
1943+# define LUAI_MAXNUMBER2STR _LUAI_MN2S
1944+#endif
1945+
1946+/*
1947+** LUA_INTEGER is the integer type used by lua_pushinteger/lua_tointeger/lua_isinteger.
1948+** LUA_INTEGER_SCAN is the format for reading integers
1949+** LUA_INTEGER_FMT is the format for writing integers
1950+**
1951+** Note: Visual C++ 2005 does not have 'strtoull()', use '_strtoui64()' instead.
1952+*/
1953+#ifdef LNUM_INT32
1954+# if LUAI_BITSINT > 16
1955+# define LUA_INTEGER int
1956+# define LUA_INTEGER_SCAN "%d"
1957+# define LUA_INTEGER_FMT "%d"
1958+# else
1959+/* Note: 'LUA_INTEGER' being 'ptrdiff_t' (as in Lua 5.1) causes problems with
1960+ * 'printf()' operations. Also 'unsigned ptrdiff_t' is invalid.
1961+ */
1962+# define LUA_INTEGER long
1963+# define LUA_INTEGER_SCAN "%ld"
1964+# define LUA_INTEGER_FMT "%ld"
1965+# endif
1966+# define LUA_INTEGER_MAX 0x7FFFFFFF /* 2^31-1 */
1967+/* */
1968+#elif defined(LNUM_INT64)
1969+# define LUA_INTEGER long long
1970+# ifdef _MSC_VER
1971+# define lua_str2ul _strtoui64
1972+# else
1973+# define lua_str2ul strtoull
1974+# endif
1975+# define LUA_INTEGER_SCAN "%lld"
1976+# define LUA_INTEGER_FMT "%lld"
1977+# define LUA_INTEGER_MAX 0x7fffffffffffffffLL /* 2^63-1 */
1978+# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX - 1LL) /* -2^63 */
1979+/* */
1980+#elif defined(LNUM_INT16)
1981+# if LUAI_BITSINT > 16
1982+# define LUA_INTEGER short
1983+# define LUA_INTEGER_SCAN "%hd"
1984+# define LUA_INTEGER_FMT "%hd"
1985+# else
1986+# define LUA_INTEGER int
1987+# define LUA_INTEGER_SCAN "%d"
1988+# define LUA_INTEGER_FMT "%d"
1989+# endif
1990+# define LUA_INTEGER_MAX 0x7FFF /* 2^16-1 */
1991+#endif
1992+
1993+#ifndef lua_str2ul
1994+# define lua_str2ul (unsigned LUA_INTEGER)strtoul
1995+#endif
1996+#ifndef LUA_INTEGER_MIN
1997+# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
1998+#endif
1999+
2000+/*
2001+@@ lua_number2int is a macro to convert lua_Number to int.
2002+@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
2003+** CHANGE them if you know a faster way to convert a lua_Number to
2004+** int (with any rounding method and without throwing errors) in your
2005+** system. In Pentium machines, a naive typecast from double to int
2006+** in C is extremely slow, so any alternative is worth trying.
2007+*/
2008+
2009+/* On a Pentium, resort to a trick */
2010+#if defined(LNUM_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
2011+ (defined(__i386) || defined (_M_IX86) || defined(__i386__))
2012+
2013+/* On a Microsoft compiler, use assembler */
2014+# if defined(_MSC_VER)
2015+# define lua_number2int(i,d) __asm fld d __asm fistp i
2016+# else
2017+
2018+/* the next trick should work on any Pentium, but sometimes clashes
2019+ with a DirectX idiosyncrasy */
2020+union luai_Cast { double l_d; long l_l; };
2021+# define lua_number2int(i,d) \
2022+ { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
2023+# endif
2024+
2025+# ifndef LNUM_INT64
2026+# define lua_number2integer lua_number2int
2027+# endif
2028+
2029+/* this option always works, but may be slow */
2030+#else
2031+# define lua_number2int(i,d) ((i)=(int)(d))
2032+#endif
2033+
2034+/* Note: Some compilers (OS X gcc 4.0?) may choke on double->long long conversion
2035+ * since it can lose precision. Others do require 'long long' there.
2036+ */
2037+#ifndef lua_number2integer
2038+# define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
2039+#endif
2040+
2041+/*
2042+** 'luai_abs()' to give absolute value of 'lua_Integer'
2043+*/
2044+#ifdef LNUM_INT32
2045+# define luai_abs abs
2046+#elif defined(LNUM_INT64) && (__STDC_VERSION__ >= 199901L)
2047+# define luai_abs llabs
2048+#else
2049+# define luai_abs(v) ((v) >= 0 ? (v) : -(v))
2050+#endif
2051+
2052+/*
2053+** LUAI_UACNUMBER is the result of an 'usual argument conversion' over a number.
2054+** LUAI_UACINTEGER the same, over an integer.
2055+*/
2056+#define LUAI_UACNUMBER double
2057+#define LUAI_UACINTEGER long
2058+
2059+/* ANSI C only has math funcs for 'double. C99 required for float and long double
2060+ * variants.
2061+ */
2062+#ifdef LNUM_DOUBLE
2063+# define _LF(name) name
2064+#elif defined(LNUM_FLOAT)
2065+# define _LF(name) name ## f
2066+#elif defined(LNUM_LDOUBLE)
2067+# define _LF(name) name ## l
2068+#endif
2069+
2070+#endif
2071+
2072--- a/src/lobject.c
2073+++ b/src/lobject.c
2074@@ -21,7 +21,8 @@
2075 #include "lstate.h"
2076 #include "lstring.h"
2077 #include "lvm.h"
2078-
2079+#include "llex.h"
2080+#include "lnum.h"
2081
2082
2083 const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
2084@@ -70,12 +71,31 @@ int luaO_log2 (unsigned int x) {
2085
2086
2087 int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
2088- if (ttype(t1) != ttype(t2)) return 0;
2089+ if (!ttype_ext_same(t1,t2)) return 0;
2090 else switch (ttype(t1)) {
2091 case LUA_TNIL:
2092 return 1;
2093+ case LUA_TINT:
2094+ if (ttype(t2)==LUA_TINT)
2095+ return ivalue(t1) == ivalue(t2);
2096+ else { /* t1:int, t2:num */
2097+#ifdef LNUM_COMPLEX
2098+ if (nvalue_img_fast(t2) != 0) return 0;
2099+#endif
2100+ /* Avoid doing accuracy losing cast, if possible. */
2101+ lua_Integer tmp;
2102+ if (tt_integer_valued(t2,&tmp))
2103+ return ivalue(t1) == tmp;
2104+ else
2105+ return luai_numeq( cast_num(ivalue(t1)), nvalue_fast(t2) );
2106+ }
2107 case LUA_TNUMBER:
2108- return luai_numeq(nvalue(t1), nvalue(t2));
2109+ if (ttype(t2)==LUA_TINT)
2110+ return luaO_rawequalObj(t2, t1); /* swap LUA_TINT to left */
2111+#ifdef LNUM_COMPLEX
2112+ if (!luai_numeq(nvalue_img_fast(t1), nvalue_img_fast(t2))) return 0;
2113+#endif
2114+ return luai_numeq(nvalue_fast(t1), nvalue_fast(t2));
2115 case LUA_TBOOLEAN:
2116 return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
2117 case LUA_TLIGHTUSERDATA:
2118@@ -86,21 +106,6 @@ int luaO_rawequalObj (const TValue *t1,
2119 }
2120 }
2121
2122-
2123-int luaO_str2d (const char *s, lua_Number *result) {
2124- char *endptr;
2125- *result = lua_str2number(s, &endptr);
2126- if (endptr == s) return 0; /* conversion failed */
2127- if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
2128- *result = cast_num(strtoul(s, &endptr, 16));
2129- if (*endptr == '\0') return 1; /* most common case */
2130- while (isspace(cast(unsigned char, *endptr))) endptr++;
2131- if (*endptr != '\0') return 0; /* invalid trailing characters? */
2132- return 1;
2133-}
2134-
2135-
2136-
2137 static void pushstr (lua_State *L, const char *str) {
2138 setsvalue2s(L, L->top, luaS_new(L, str));
2139 incr_top(L);
2140@@ -131,7 +136,11 @@ const char *luaO_pushvfstring (lua_State
2141 break;
2142 }
2143 case 'd': {
2144- setnvalue(L->top, cast_num(va_arg(argp, int)));
2145+ /* This is tricky for 64-bit integers; maybe they even cannot be
2146+ * supported on all compilers; depends on the conversions applied to
2147+ * variable argument lists. TBD: test!
2148+ */
2149+ setivalue(L->top, (lua_Integer) va_arg(argp, l_uacInteger));
2150 incr_top(L);
2151 break;
2152 }
2153@@ -212,3 +221,4 @@ void luaO_chunkid (char *out, const char
2154 }
2155 }
2156 }
2157+
2158--- a/src/lobject.h
2159+++ b/src/lobject.h
2160@@ -17,7 +17,11 @@
2161
2162
2163 /* tags for values visible from Lua */
2164-#define LAST_TAG LUA_TTHREAD
2165+#if LUA_TINT > LUA_TTHREAD
2166+# define LAST_TAG LUA_TINT
2167+#else
2168+# define LAST_TAG LUA_TTHREAD
2169+#endif
2170
2171 #define NUM_TAGS (LAST_TAG+1)
2172
2173@@ -59,7 +63,12 @@ typedef struct GCheader {
2174 typedef union {
2175 GCObject *gc;
2176 void *p;
2177+#ifdef LNUM_COMPLEX
2178+ lua_Complex n;
2179+#else
2180 lua_Number n;
2181+#endif
2182+ lua_Integer i;
2183 int b;
2184 } Value;
2185
2186@@ -77,7 +86,11 @@ typedef struct lua_TValue {
2187
2188 /* Macros to test type */
2189 #define ttisnil(o) (ttype(o) == LUA_TNIL)
2190-#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
2191+#define ttisint(o) (ttype(o) == LUA_TINT)
2192+#define ttisnumber(o) ((ttype(o) == LUA_TINT) || (ttype(o) == LUA_TNUMBER))
2193+#ifdef LNUM_COMPLEX
2194+# define ttiscomplex(o) ((ttype(o) == LUA_TNUMBER) && (nvalue_img_fast(o)!=0))
2195+#endif
2196 #define ttisstring(o) (ttype(o) == LUA_TSTRING)
2197 #define ttistable(o) (ttype(o) == LUA_TTABLE)
2198 #define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
2199@@ -90,7 +103,25 @@ typedef struct lua_TValue {
2200 #define ttype(o) ((o)->tt)
2201 #define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
2202 #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
2203-#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
2204+
2205+#define ttype_ext(o) ( ttype(o) == LUA_TINT ? LUA_TNUMBER : ttype(o) )
2206+#define ttype_ext_same(o1,o2) ( (ttype(o1)==ttype(o2)) || (ttisnumber(o1) && ttisnumber(o2)) )
2207+
2208+/* '_fast' variants are for cases where 'ttype(o)' is known to be LUA_TNUMBER.
2209+ */
2210+#ifdef LNUM_COMPLEX
2211+# define nvalue_complex_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n )
2212+# define nvalue_fast(o) ( _LF(creal) ( nvalue_complex_fast(o) ) )
2213+# define nvalue_img_fast(o) ( _LF(cimag) ( nvalue_complex_fast(o) ) )
2214+# define nvalue_complex(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? (o)->value.i : (o)->value.n )
2215+# define nvalue_img(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? 0 : _LF(cimag)( (o)->value.n ) )
2216+# define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : _LF(creal)((o)->value.n) )
2217+#else
2218+# define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : (o)->value.n )
2219+# define nvalue_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n )
2220+#endif
2221+#define ivalue(o) check_exp( ttype(o)==LUA_TINT, (o)->value.i )
2222+
2223 #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
2224 #define tsvalue(o) (&rawtsvalue(o)->tsv)
2225 #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
2226@@ -116,8 +147,27 @@ typedef struct lua_TValue {
2227 /* Macros to set values */
2228 #define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
2229
2230-#define setnvalue(obj,x) \
2231- { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
2232+/* Must not have side effects, 'x' may be expression.
2233+*/
2234+#define setivalue(obj,x) \
2235+ { TValue *i_o=(obj); i_o->value.i=(x); i_o->tt=LUA_TINT; }
2236+
2237+# define setnvalue(obj,x) \
2238+ { TValue *i_o=(obj); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; }
2239+
2240+/* Note: Complex always has "inline", both are C99.
2241+*/
2242+#ifdef LNUM_COMPLEX
2243+ static inline void setnvalue_complex_fast( TValue *obj, lua_Complex x ) {
2244+ lua_assert( _LF(cimag)(x) != 0 );
2245+ obj->value.n= x; obj->tt= LUA_TNUMBER;
2246+ }
2247+ static inline void setnvalue_complex( TValue *obj, lua_Complex x ) {
2248+ if (_LF(cimag)(x) == 0) { setnvalue(obj, _LF(creal)(x)); }
2249+ else { obj->value.n= x; obj->tt= LUA_TNUMBER; }
2250+ }
2251+#endif
2252+
2253
2254 #define setpvalue(obj,x) \
2255 { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
2256@@ -155,9 +205,6 @@ typedef struct lua_TValue {
2257 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
2258 checkliveness(G(L),i_o); }
2259
2260-
2261-
2262-
2263 #define setobj(L,obj1,obj2) \
2264 { const TValue *o2=(obj2); TValue *o1=(obj1); \
2265 o1->value = o2->value; o1->tt=o2->tt; \
2266@@ -185,8 +232,11 @@ typedef struct lua_TValue {
2267
2268 #define setttype(obj, tt) (ttype(obj) = (tt))
2269
2270-
2271-#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
2272+#if LUA_TINT >= LUA_TSTRING
2273+# define iscollectable(o) ((ttype(o) >= LUA_TSTRING) && (ttype(o) != LUA_TINT))
2274+#else
2275+# define iscollectable(o) (ttype(o) >= LUA_TSTRING)
2276+#endif
2277
2278
2279
2280@@ -370,12 +420,10 @@ LUAI_FUNC int luaO_log2 (unsigned int x)
2281 LUAI_FUNC int luaO_int2fb (unsigned int x);
2282 LUAI_FUNC int luaO_fb2int (int x);
2283 LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
2284-LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
2285 LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
2286 va_list argp);
2287 LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
2288 LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
2289
2290-
2291 #endif
2292
2293--- a/src/loslib.c
2294+++ b/src/loslib.c
2295@@ -186,15 +186,30 @@ static int os_time (lua_State *L) {
2296 }
2297 if (t == (time_t)(-1))
2298 lua_pushnil(L);
2299- else
2300- lua_pushnumber(L, (lua_Number)t);
2301+ else {
2302+ /* On float systems the pushed value must be an integer, NOT a number.
2303+ * Otherwise, accuracy is lost in the time_t->float conversion.
2304+ */
2305+#ifdef LNUM_FLOAT
2306+ lua_pushinteger(L, (lua_Integer) t);
2307+#else
2308+ lua_pushnumber(L, (lua_Number) t);
2309+#endif
2310+ }
2311 return 1;
2312 }
2313
2314
2315 static int os_difftime (lua_State *L) {
2316+#ifdef LNUM_FLOAT
2317+ lua_Integer i= (lua_Integer)
2318+ difftime( (time_t)(luaL_checkinteger(L, 1)),
2319+ (time_t)(luaL_optinteger(L, 2, 0)));
2320+ lua_pushinteger(L, i);
2321+#else
2322 lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
2323 (time_t)(luaL_optnumber(L, 2, 0))));
2324+#endif
2325 return 1;
2326 }
2327
2328--- a/src/lparser.c
2329+++ b/src/lparser.c
2330@@ -33,7 +33,6 @@
2331
2332 #define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
2333
2334-
2335 /*
2336 ** nodes for block list (list of active blocks)
2337 */
2338@@ -72,7 +71,7 @@ static void errorlimit (FuncState *fs, i
2339 const char *msg = (fs->f->linedefined == 0) ?
2340 luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
2341 luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
2342- fs->f->linedefined, limit, what);
2343+ (fs->f->linedefined), limit, what);
2344 luaX_lexerror(fs->ls, msg, 0);
2345 }
2346
2347@@ -733,6 +732,18 @@ static void simpleexp (LexState *ls, exp
2348 v->u.nval = ls->t.seminfo.r;
2349 break;
2350 }
2351+ case TK_INT: {
2352+ init_exp(v, VKINT, 0);
2353+ v->u.ival = ls->t.seminfo.i;
2354+ break;
2355+ }
2356+#ifdef LNUM_COMPLEX
2357+ case TK_NUMBER2: {
2358+ init_exp(v, VKNUM2, 0);
2359+ v->u.nval = ls->t.seminfo.r;
2360+ break;
2361+ }
2362+#endif
2363 case TK_STRING: {
2364 codestring(ls, v, ls->t.seminfo.ts);
2365 break;
2366@@ -1079,7 +1090,7 @@ static void fornum (LexState *ls, TStrin
2367 if (testnext(ls, ','))
2368 exp1(ls); /* optional step */
2369 else { /* default step = 1 */
2370- luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
2371+ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_integerK(fs, 1));
2372 luaK_reserveregs(fs, 1);
2373 }
2374 forbody(ls, base, line, 1, 1);
2375--- a/src/lparser.h
2376+++ b/src/lparser.h
2377@@ -31,7 +31,11 @@ typedef enum {
2378 VRELOCABLE, /* info = instruction pc */
2379 VNONRELOC, /* info = result register */
2380 VCALL, /* info = instruction pc */
2381- VVARARG /* info = instruction pc */
2382+ VVARARG, /* info = instruction pc */
2383+ VKINT /* ival = integer value */
2384+#ifdef LNUM_COMPLEX
2385+ ,VKNUM2 /* nval = imaginary value */
2386+#endif
2387 } expkind;
2388
2389 typedef struct expdesc {
2390@@ -39,6 +43,7 @@ typedef struct expdesc {
2391 union {
2392 struct { int info, aux; } s;
2393 lua_Number nval;
2394+ lua_Integer ival;
2395 } u;
2396 int t; /* patch list of `exit when true' */
2397 int f; /* patch list of `exit when false' */
2398--- a/src/lstrlib.c
2399+++ b/src/lstrlib.c
2400@@ -43,8 +43,8 @@ static ptrdiff_t posrelat (ptrdiff_t pos
2401 static int str_sub (lua_State *L) {
2402 size_t l;
2403 const char *s = luaL_checklstring(L, 1, &l);
2404- ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
2405- ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
2406+ ptrdiff_t start = posrelat(luaL_checkint32(L, 2), l);
2407+ ptrdiff_t end = posrelat(luaL_optint32(L, 3, -1), l);
2408 if (start < 1) start = 1;
2409 if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
2410 if (start <= end)
2411@@ -106,8 +106,8 @@ static int str_rep (lua_State *L) {
2412 static int str_byte (lua_State *L) {
2413 size_t l;
2414 const char *s = luaL_checklstring(L, 1, &l);
2415- ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
2416- ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
2417+ ptrdiff_t posi = posrelat(luaL_optint32(L, 2, 1), l);
2418+ ptrdiff_t pose = posrelat(luaL_optint32(L, 3, posi), l);
2419 int n, i;
2420 if (posi <= 0) posi = 1;
2421 if ((size_t)pose > l) pose = l;
2422@@ -496,7 +496,7 @@ static int str_find_aux (lua_State *L, i
2423 size_t l1, l2;
2424 const char *s = luaL_checklstring(L, 1, &l1);
2425 const char *p = luaL_checklstring(L, 2, &l2);
2426- ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
2427+ ptrdiff_t init = posrelat(luaL_optint32(L, 3, 1), l1) - 1;
2428 if (init < 0) init = 0;
2429 else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
2430 if (find && (lua_toboolean(L, 4) || /* explicit request? */
2431@@ -690,7 +690,7 @@ static int str_gsub (lua_State *L) {
2432 ** maximum size of each format specification (such as '%-099.99d')
2433 ** (+10 accounts for %99.99x plus margin of error)
2434 */
2435-#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
2436+#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTEGER_FMT)-2 + 10)
2437
2438
2439 static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
2440@@ -747,9 +747,9 @@ static const char *scanformat (lua_State
2441 static void addintlen (char *form) {
2442 size_t l = strlen(form);
2443 char spec = form[l - 1];
2444- strcpy(form + l - 1, LUA_INTFRMLEN);
2445- form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
2446- form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
2447+ const char *tmp= LUA_INTEGER_FMT; /* "%lld" or "%ld" */
2448+ strcpy(form + l - 1, tmp+1);
2449+ form[l + sizeof(LUA_INTEGER_FMT)-4] = spec;
2450 }
2451
2452
2453@@ -779,12 +779,12 @@ static int str_format (lua_State *L) {
2454 }
2455 case 'd': case 'i': {
2456 addintlen(form);
2457- sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
2458+ sprintf(buff, form, luaL_checkinteger(L, arg));
2459 break;
2460 }
2461 case 'o': case 'u': case 'x': case 'X': {
2462 addintlen(form);
2463- sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
2464+ sprintf(buff, form, (unsigned LUA_INTEGER)luaL_checkinteger(L, arg));
2465 break;
2466 }
2467 case 'e': case 'E': case 'f':
2468--- a/src/ltable.c
2469+++ b/src/ltable.c
2470@@ -33,6 +33,7 @@
2471 #include "lobject.h"
2472 #include "lstate.h"
2473 #include "ltable.h"
2474+#include "lnum.h"
2475
2476
2477 /*
2478@@ -51,25 +52,15 @@
2479
2480 #define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
2481 #define hashboolean(t,p) hashpow2(t, p)
2482-
2483+#define hashint(t,i) hashpow2(t,i)
2484
2485 /*
2486 ** for some types, it is better to avoid modulus by power of 2, as
2487 ** they tend to have many 2 factors.
2488 */
2489 #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
2490-
2491-
2492 #define hashpointer(t,p) hashmod(t, IntPoint(p))
2493
2494-
2495-/*
2496-** number of ints inside a lua_Number
2497-*/
2498-#define numints cast_int(sizeof(lua_Number)/sizeof(int))
2499-
2500-
2501-
2502 #define dummynode (&dummynode_)
2503
2504 static const Node dummynode_ = {
2505@@ -80,27 +71,46 @@ static const Node dummynode_ = {
2506
2507 /*
2508 ** hash for lua_Numbers
2509+**
2510+** for non-complex modes, never called with 'lua_Integer' value range (s.a. 0)
2511 */
2512 static Node *hashnum (const Table *t, lua_Number n) {
2513- unsigned int a[numints];
2514- int i;
2515- if (luai_numeq(n, 0)) /* avoid problems with -0 */
2516- return gnode(t, 0);
2517- memcpy(a, &n, sizeof(a));
2518- for (i = 1; i < numints; i++) a[0] += a[i];
2519- return hashmod(t, a[0]);
2520+ const unsigned int *p= cast(const unsigned int *,&n);
2521+ unsigned int sum= *p;
2522+ unsigned int m= sizeof(lua_Number)/sizeof(int);
2523+ unsigned int i;
2524+ /* OS X Intel has 'm'==4 and gives "Bus error" if the last integer of
2525+ * 'n' is read; the actual size of long double is only 80 bits = 10 bytes.
2526+ * Linux x86 has 'm'==3, and does not require reduction.
2527+ */
2528+#if defined(LNUM_LDOUBLE) && defined(__i386__)
2529+ if (m>3) m--;
2530+#endif
2531+ for (i = 1; i < m; i++) sum += p[i];
2532+ return hashmod(t, sum);
2533 }
2534
2535
2536-
2537 /*
2538 ** returns the `main' position of an element in a table (that is, the index
2539 ** of its hash value)
2540+**
2541+** Floating point numbers with integer value give the hash position of the
2542+** integer (so they use the same table position).
2543 */
2544 static Node *mainposition (const Table *t, const TValue *key) {
2545+ lua_Integer i;
2546 switch (ttype(key)) {
2547 case LUA_TNUMBER:
2548- return hashnum(t, nvalue(key));
2549+ if (tt_integer_valued(key,&i))
2550+ return hashint(t, i);
2551+#ifdef LNUM_COMPLEX
2552+ if (nvalue_img_fast(key)!=0 && luai_numeq(nvalue_fast(key),0))
2553+ return gnode(t, 0); /* 0 and -0 to give same hash */
2554+#endif
2555+ return hashnum(t, nvalue_fast(key));
2556+ case LUA_TINT:
2557+ return hashint(t, ivalue(key));
2558 case LUA_TSTRING:
2559 return hashstr(t, rawtsvalue(key));
2560 case LUA_TBOOLEAN:
2561@@ -116,16 +126,20 @@ static Node *mainposition (const Table *
2562 /*
2563 ** returns the index for `key' if `key' is an appropriate key to live in
2564 ** the array part of the table, -1 otherwise.
2565+**
2566+** Anything <=0 is taken as not being in the array part.
2567 */
2568-static int arrayindex (const TValue *key) {
2569- if (ttisnumber(key)) {
2570- lua_Number n = nvalue(key);
2571- int k;
2572- lua_number2int(k, n);
2573- if (luai_numeq(cast_num(k), n))
2574- return k;
2575+static int arrayindex (const TValue *key, int max) {
2576+ lua_Integer k;
2577+ switch( ttype(key) ) {
2578+ case LUA_TINT:
2579+ k= ivalue(key); break;
2580+ case LUA_TNUMBER:
2581+ if (tt_integer_valued(key,&k)) break;
2582+ default:
2583+ return -1; /* not to be used as array index */
2584 }
2585- return -1; /* `key' did not match some condition */
2586+ return ((k>0) && (k <= max)) ? cast_int(k) : -1;
2587 }
2588
2589
2590@@ -137,8 +151,8 @@ static int arrayindex (const TValue *key
2591 static int findindex (lua_State *L, Table *t, StkId key) {
2592 int i;
2593 if (ttisnil(key)) return -1; /* first iteration */
2594- i = arrayindex(key);
2595- if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
2596+ i = arrayindex(key, t->sizearray);
2597+ if (i>0) /* inside array part? */
2598 return i-1; /* yes; that's the index (corrected to C) */
2599 else {
2600 Node *n = mainposition(t, key);
2601@@ -163,7 +177,7 @@ int luaH_next (lua_State *L, Table *t, S
2602 int i = findindex(L, t, key); /* find original element */
2603 for (i++; i < t->sizearray; i++) { /* try first array part */
2604 if (!ttisnil(&t->array[i])) { /* a non-nil value? */
2605- setnvalue(key, cast_num(i+1));
2606+ setivalue(key, i+1);
2607 setobj2s(L, key+1, &t->array[i]);
2608 return 1;
2609 }
2610@@ -209,8 +223,8 @@ static int computesizes (int nums[], int
2611
2612
2613 static int countint (const TValue *key, int *nums) {
2614- int k = arrayindex(key);
2615- if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
2616+ int k = arrayindex(key,MAXASIZE);
2617+ if (k>0) { /* appropriate array index? */
2618 nums[ceillog2(k)]++; /* count as such */
2619 return 1;
2620 }
2621@@ -308,7 +322,7 @@ static void resize (lua_State *L, Table
2622 /* re-insert elements from vanishing slice */
2623 for (i=nasize; i<oldasize; i++) {
2624 if (!ttisnil(&t->array[i]))
2625- setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
2626+ setobjt2t(L, luaH_setint(L, t, i+1), &t->array[i]);
2627 }
2628 /* shrink array */
2629 luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
2630@@ -409,7 +423,9 @@ static TValue *newkey (lua_State *L, Tab
2631 othern = mainposition(t, key2tval(mp));
2632 if (othern != mp) { /* is colliding node out of its main position? */
2633 /* yes; move colliding node into free position */
2634- while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
2635+ while (gnext(othern) != mp) {
2636+ othern = gnext(othern); /* find previous */
2637+ }
2638 gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
2639 *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
2640 gnext(mp) = NULL; /* now `mp' is free */
2641@@ -432,17 +448,18 @@ static TValue *newkey (lua_State *L, Tab
2642 /*
2643 ** search function for integers
2644 */
2645-const TValue *luaH_getnum (Table *t, int key) {
2646+const TValue *luaH_getint (Table *t, lua_Integer key) {
2647 /* (1 <= key && key <= t->sizearray) */
2648 if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
2649 return &t->array[key-1];
2650 else {
2651- lua_Number nk = cast_num(key);
2652- Node *n = hashnum(t, nk);
2653+ Node *n = hashint(t, key);
2654 do { /* check whether `key' is somewhere in the chain */
2655- if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
2656+ if (ttisint(gkey(n)) && (ivalue(gkey(n)) == key)) {
2657 return gval(n); /* that's it */
2658- else n = gnext(n);
2659+ } else {
2660+ n = gnext(n);
2661+ }
2662 } while (n);
2663 return luaO_nilobject;
2664 }
2665@@ -470,14 +487,12 @@ const TValue *luaH_get (Table *t, const
2666 switch (ttype(key)) {
2667 case LUA_TNIL: return luaO_nilobject;
2668 case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
2669+ case LUA_TINT: return luaH_getint(t, ivalue(key));
2670 case LUA_TNUMBER: {
2671- int k;
2672- lua_Number n = nvalue(key);
2673- lua_number2int(k, n);
2674- if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
2675- return luaH_getnum(t, k); /* use specialized version */
2676- /* else go through */
2677- }
2678+ lua_Integer i;
2679+ if (tt_integer_valued(key,&i))
2680+ return luaH_getint(t,i);
2681+ } /* pass through */
2682 default: {
2683 Node *n = mainposition(t, key);
2684 do { /* check whether `key' is somewhere in the chain */
2685@@ -498,20 +513,25 @@ TValue *luaH_set (lua_State *L, Table *t
2686 return cast(TValue *, p);
2687 else {
2688 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
2689- else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
2690- luaG_runerror(L, "table index is NaN");
2691+ else if (ttype(key)==LUA_TNUMBER) {
2692+ lua_Integer k;
2693+ if (luai_numisnan(nvalue_fast(key)))
2694+ luaG_runerror(L, "table index is NaN");
2695+ if (tt_integer_valued(key,&k))
2696+ return luaH_setint(L, t, k);
2697+ }
2698 return newkey(L, t, key);
2699 }
2700 }
2701
2702
2703-TValue *luaH_setnum (lua_State *L, Table *t, int key) {
2704- const TValue *p = luaH_getnum(t, key);
2705+TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key) {
2706+ const TValue *p = luaH_getint(t, key);
2707 if (p != luaO_nilobject)
2708 return cast(TValue *, p);
2709 else {
2710 TValue k;
2711- setnvalue(&k, cast_num(key));
2712+ setivalue(&k, key);
2713 return newkey(L, t, &k);
2714 }
2715 }
2716@@ -533,20 +553,21 @@ static int unbound_search (Table *t, uns
2717 unsigned int i = j; /* i is zero or a present index */
2718 j++;
2719 /* find `i' and `j' such that i is present and j is not */
2720- while (!ttisnil(luaH_getnum(t, j))) {
2721+ while (!ttisnil(luaH_getint(t, j))) {
2722 i = j;
2723 j *= 2;
2724 if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
2725 /* table was built with bad purposes: resort to linear search */
2726- i = 1;
2727- while (!ttisnil(luaH_getnum(t, i))) i++;
2728- return i - 1;
2729+ for( i = 1; i<MAX_INT+1; i++ ) {
2730+ if (ttisnil(luaH_getint(t, i))) break;
2731+ }
2732+ return i - 1; /* up to MAX_INT */
2733 }
2734 }
2735 /* now do a binary search between them */
2736 while (j - i > 1) {
2737 unsigned int m = (i+j)/2;
2738- if (ttisnil(luaH_getnum(t, m))) j = m;
2739+ if (ttisnil(luaH_getint(t, m))) j = m;
2740 else i = m;
2741 }
2742 return i;
2743--- a/src/ltable.h
2744+++ b/src/ltable.h
2745@@ -18,8 +18,8 @@
2746 #define key2tval(n) (&(n)->i_key.tvk)
2747
2748
2749-LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
2750-LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
2751+LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
2752+LUAI_FUNC TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key);
2753 LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
2754 LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
2755 LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
2756--- a/src/ltm.c
2757+++ b/src/ltm.c
2758@@ -19,7 +19,6 @@
2759 #include "ltm.h"
2760
2761
2762-
2763 const char *const luaT_typenames[] = {
2764 "nil", "boolean", "userdata", "number",
2765 "string", "table", "function", "userdata", "thread",
2766@@ -67,6 +66,9 @@ const TValue *luaT_gettmbyobj (lua_State
2767 case LUA_TUSERDATA:
2768 mt = uvalue(o)->metatable;
2769 break;
2770+ case LUA_TINT:
2771+ mt = G(L)->mt[LUA_TNUMBER];
2772+ break;
2773 default:
2774 mt = G(L)->mt[ttype(o)];
2775 }
2776--- a/src/lua.c
2777+++ b/src/lua.c
2778@@ -16,7 +16,7 @@
2779
2780 #include "lauxlib.h"
2781 #include "lualib.h"
2782-
2783+#include "llimits.h"
2784
2785
2786 static lua_State *globalL = NULL;
2787@@ -382,6 +382,15 @@ int main (int argc, char **argv) {
2788 l_message(argv[0], "cannot create state: not enough memory");
2789 return EXIT_FAILURE;
2790 }
2791+ /* Checking 'sizeof(lua_Integer)' cannot be made in preprocessor on all compilers.
2792+ */
2793+#ifdef LNUM_INT16
2794+ lua_assert( sizeof(lua_Integer) == 2 );
2795+#elif defined(LNUM_INT32)
2796+ lua_assert( sizeof(lua_Integer) == 4 );
2797+#elif defined(LNUM_INT64)
2798+ lua_assert( sizeof(lua_Integer) == 8 );
2799+#endif
2800 s.argc = argc;
2801 s.argv = argv;
2802 status = lua_cpcall(L, &pmain, &s);
2803--- a/src/lua.h
2804+++ b/src/lua.h
2805@@ -19,7 +19,7 @@
2806 #define LUA_VERSION "Lua 5.1"
2807 #define LUA_RELEASE "Lua 5.1.5"
2808 #define LUA_VERSION_NUM 501
2809-#define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio"
2810+#define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio" " (" LUA_LNUM ")"
2811 #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
2812
2813
2814@@ -71,6 +71,16 @@ typedef void * (*lua_Alloc) (void *ud, v
2815 */
2816 #define LUA_TNONE (-1)
2817
2818+/* LUA_TINT is an internal type, not visible to applications. There are three
2819+ * potential values where it can be tweaked to (code autoadjusts to these):
2820+ *
2821+ * -2: not 'usual' type value; good since 'LUA_TINT' is not part of the API
2822+ * LUA_TNUMBER+1: shifts other type values upwards, breaking binary compatibility
2823+ * not acceptable for 5.1, maybe 5.2 onwards?
2824+ * 9: greater than existing (5.1) type values.
2825+*/
2826+#define LUA_TINT (-2)
2827+
2828 #define LUA_TNIL 0
2829 #define LUA_TBOOLEAN 1
2830 #define LUA_TLIGHTUSERDATA 2
2831@@ -139,6 +149,8 @@ LUA_API int (lua_isuserdata)
2832 LUA_API int (lua_type) (lua_State *L, int idx);
2833 LUA_API const char *(lua_typename) (lua_State *L, int tp);
2834
2835+LUA_API int (lua_isinteger) (lua_State *L, int idx);
2836+
2837 LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
2838 LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
2839 LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
2840@@ -244,6 +256,19 @@ LUA_API lua_Alloc (lua_getallocf) (lua_S
2841 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
2842
2843
2844+/*
2845+* It is unnecessary to break Lua C API 'lua_tonumber()' compatibility, just
2846+* because the Lua number type is complex. Most C modules would use scalars
2847+* only. We'll introduce new 'lua_tocomplex' and 'lua_pushcomplex' for when
2848+* the module really wants to use them.
2849+*/
2850+#ifdef LNUM_COMPLEX
2851+ #include <complex.h>
2852+ typedef LUA_NUMBER complex lua_Complex;
2853+ LUA_API lua_Complex (lua_tocomplex) (lua_State *L, int idx);
2854+ LUA_API void (lua_pushcomplex) (lua_State *L, lua_Complex v);
2855+#endif
2856+
2857
2858 /*
2859 ** ===============================================================
2860@@ -268,7 +293,12 @@ LUA_API void lua_setallocf (lua_State *L
2861 #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
2862 #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
2863 #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
2864-#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
2865+
2866+#if LUA_TINT < 0
2867+# define lua_isnoneornil(L, n) ( (lua_type(L,(n)) <= 0) && (lua_type(L,(n)) != LUA_TINT) )
2868+#else
2869+# define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
2870+#endif
2871
2872 #define lua_pushliteral(L, s) \
2873 lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
2874@@ -386,3 +416,4 @@ struct lua_Debug {
2875
2876
2877 #endif
2878+
2879--- a/src/luaconf.h
2880+++ b/src/luaconf.h
2881@@ -10,7 +10,9 @@
2882
2883 #include <limits.h>
2884 #include <stddef.h>
2885-
2886+#ifdef lua_assert
2887+# include <assert.h>
2888+#endif
2889
2890 /*
2891 ** ==================================================================
2892@@ -136,14 +138,38 @@
2893
2894
2895 /*
2896-@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
2897-** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
2898-** machines, ptrdiff_t gives a good choice between int or long.)
2899+@@ LUAI_BITSINT defines the number of bits in an int.
2900+** CHANGE here if Lua cannot automatically detect the number of bits of
2901+** your machine. Probably you do not need to change this.
2902 */
2903-#define LUA_INTEGER ptrdiff_t
2904+/* avoid overflows in comparison */
2905+#if INT_MAX-20 < 32760
2906+#define LUAI_BITSINT 16
2907+#elif INT_MAX > 2147483640L
2908+/* int has at least 32 bits */
2909+#define LUAI_BITSINT 32
2910+#else
2911+#error "you must define LUA_BITSINT with number of bits in an integer"
2912+#endif
2913
2914
2915 /*
2916+@@ LNUM_DOUBLE | LNUM_FLOAT | LNUM_LDOUBLE: Generic Lua number mode
2917+@@ LNUM_INT32 | LNUM_INT64: Integer type
2918+@@ LNUM_COMPLEX: Define for using 'a+bi' numbers
2919+@@
2920+@@ You can combine LNUM_xxx but only one of each group. I.e. '-DLNUM_FLOAT
2921+@@ -DLNUM_INT32 -DLNUM_COMPLEX' gives float range complex numbers, with
2922+@@ 32-bit scalar integer range optimized.
2923+**
2924+** These are kept in a separate configuration file mainly for ease of patching
2925+** (can be changed if integerated to Lua proper).
2926+*/
2927+/*#define LNUM_DOUBLE*/
2928+/*#define LNUM_INT32*/
2929+#include "lnum_config.h"
2930+
2931+/*
2932 @@ LUA_API is a mark for all core API functions.
2933 @@ LUALIB_API is a mark for all standard library functions.
2934 ** CHANGE them if you need to define those functions in some special way.
2935@@ -383,22 +409,6 @@
2936
2937
2938 /*
2939-@@ LUAI_BITSINT defines the number of bits in an int.
2940-** CHANGE here if Lua cannot automatically detect the number of bits of
2941-** your machine. Probably you do not need to change this.
2942-*/
2943-/* avoid overflows in comparison */
2944-#if INT_MAX-20 < 32760
2945-#define LUAI_BITSINT 16
2946-#elif INT_MAX > 2147483640L
2947-/* int has at least 32 bits */
2948-#define LUAI_BITSINT 32
2949-#else
2950-#error "you must define LUA_BITSINT with number of bits in an integer"
2951-#endif
2952-
2953-
2954-/*
2955 @@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
2956 @@ LUAI_INT32 is an signed integer with at least 32 bits.
2957 @@ LUAI_UMEM is an unsigned integer big enough to count the total
2958@@ -425,6 +435,15 @@
2959 #define LUAI_MEM long
2960 #endif
2961
2962+/*
2963+@@ LUAI_BOOL carries 0 and nonzero (normally 1). It may be defined as 'char'
2964+** (to save memory), 'int' (for speed), 'bool' (for C++) or '_Bool' (C99)
2965+*/
2966+#ifdef __cplusplus
2967+# define LUAI_BOOL bool
2968+#else
2969+# define LUAI_BOOL int
2970+#endif
2971
2972 /*
2973 @@ LUAI_MAXCALLS limits the number of nested calls.
2974@@ -490,101 +509,6 @@
2975 /* }================================================================== */
2976
2977
2978-
2979-
2980-/*
2981-** {==================================================================
2982-@@ LUA_NUMBER is the type of numbers in Lua.
2983-** CHANGE the following definitions only if you want to build Lua
2984-** with a number type different from double. You may also need to
2985-** change lua_number2int & lua_number2integer.
2986-** ===================================================================
2987-*/
2988-
2989-#define LUA_NUMBER_DOUBLE
2990-#define LUA_NUMBER double
2991-
2992-/*
2993-@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
2994-@* over a number.
2995-*/
2996-#define LUAI_UACNUMBER double
2997-
2998-
2999-/*
3000-@@ LUA_NUMBER_SCAN is the format for reading numbers.
3001-@@ LUA_NUMBER_FMT is the format for writing numbers.
3002-@@ lua_number2str converts a number to a string.
3003-@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
3004-@@ lua_str2number converts a string to a number.
3005-*/
3006-#define LUA_NUMBER_SCAN "%lf"
3007-#define LUA_NUMBER_FMT "%.14g"
3008-#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
3009-#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
3010-#define lua_str2number(s,p) strtod((s), (p))
3011-
3012-
3013-/*
3014-@@ The luai_num* macros define the primitive operations over numbers.
3015-*/
3016-#if defined(LUA_CORE)
3017-#include <math.h>
3018-#define luai_numadd(a,b) ((a)+(b))
3019-#define luai_numsub(a,b) ((a)-(b))
3020-#define luai_nummul(a,b) ((a)*(b))
3021-#define luai_numdiv(a,b) ((a)/(b))
3022-#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
3023-#define luai_numpow(a,b) (pow(a,b))
3024-#define luai_numunm(a) (-(a))
3025-#define luai_numeq(a,b) ((a)==(b))
3026-#define luai_numlt(a,b) ((a)<(b))
3027-#define luai_numle(a,b) ((a)<=(b))
3028-#define luai_numisnan(a) (!luai_numeq((a), (a)))
3029-#endif
3030-
3031-
3032-/*
3033-@@ lua_number2int is a macro to convert lua_Number to int.
3034-@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
3035-** CHANGE them if you know a faster way to convert a lua_Number to
3036-** int (with any rounding method and without throwing errors) in your
3037-** system. In Pentium machines, a naive typecast from double to int
3038-** in C is extremely slow, so any alternative is worth trying.
3039-*/
3040-
3041-/* On a Pentium, resort to a trick */
3042-#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
3043- (defined(__i386) || defined (_M_IX86) || defined(__i386__))
3044-
3045-/* On a Microsoft compiler, use assembler */
3046-#if defined(_MSC_VER)
3047-
3048-#define lua_number2int(i,d) __asm fld d __asm fistp i
3049-#define lua_number2integer(i,n) lua_number2int(i, n)
3050-
3051-/* the next trick should work on any Pentium, but sometimes clashes
3052- with a DirectX idiosyncrasy */
3053-#else
3054-
3055-union luai_Cast { double l_d; long l_l; };
3056-#define lua_number2int(i,d) \
3057- { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
3058-#define lua_number2integer(i,n) lua_number2int(i, n)
3059-
3060-#endif
3061-
3062-
3063-/* this option always works, but may be slow */
3064-#else
3065-#define lua_number2int(i,d) ((i)=(int)(d))
3066-#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
3067-
3068-#endif
3069-
3070-/* }================================================================== */
3071-
3072-
3073 /*
3074 @@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
3075 ** CHANGE it if your system requires alignments larger than double. (For
3076@@ -728,28 +652,6 @@ union luai_Cast { double l_d; long l_l;
3077 #define luai_userstateyield(L,n) ((void)L)
3078
3079
3080-/*
3081-@@ LUA_INTFRMLEN is the length modifier for integer conversions
3082-@* in 'string.format'.
3083-@@ LUA_INTFRM_T is the integer type correspoding to the previous length
3084-@* modifier.
3085-** CHANGE them if your system supports long long or does not support long.
3086-*/
3087-
3088-#if defined(LUA_USELONGLONG)
3089-
3090-#define LUA_INTFRMLEN "ll"
3091-#define LUA_INTFRM_T long long
3092-
3093-#else
3094-
3095-#define LUA_INTFRMLEN "l"
3096-#define LUA_INTFRM_T long
3097-
3098-#endif
3099-
3100-
3101-
3102 /* =================================================================== */
3103
3104 /*
3105--- a/src/lundump.c
3106+++ b/src/lundump.c
3107@@ -73,6 +73,13 @@ static lua_Number LoadNumber(LoadState*
3108 return x;
3109 }
3110
3111+static lua_Integer LoadInteger(LoadState* S)
3112+{
3113+ lua_Integer x;
3114+ LoadVar(S,x);
3115+ return x;
3116+}
3117+
3118 static TString* LoadString(LoadState* S)
3119 {
3120 size_t size;
3121@@ -119,6 +126,9 @@ static void LoadConstants(LoadState* S,
3122 case LUA_TNUMBER:
3123 setnvalue(o,LoadNumber(S));
3124 break;
3125+ case LUA_TINT: /* Integer type saved in bytecode (see lcode.c) */
3126+ setivalue(o,LoadInteger(S));
3127+ break;
3128 case LUA_TSTRING:
3129 setsvalue2n(S->L,o,LoadString(S));
3130 break;
3131@@ -223,5 +233,22 @@ void luaU_header (char* h)
3132 *h++=(char)sizeof(size_t);
3133 *h++=(char)sizeof(Instruction);
3134 *h++=(char)sizeof(lua_Number);
3135- *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
3136+
3137+ /*
3138+ * Last byte of header (0/1 in unpatched Lua 5.1.3):
3139+ *
3140+ * 0: lua_Number is float or double, lua_Integer not used. (nonpatched only)
3141+ * 1: lua_Number is integer (nonpatched only)
3142+ *
3143+ * +2: LNUM_INT16: sizeof(lua_Integer)
3144+ * +4: LNUM_INT32: sizeof(lua_Integer)
3145+ * +8: LNUM_INT64: sizeof(lua_Integer)
3146+ *
3147+ * +0x80: LNUM_COMPLEX
3148+ */
3149+ *h++ = (char)(sizeof(lua_Integer)
3150+#ifdef LNUM_COMPLEX
3151+ | 0x80
3152+#endif
3153+ );
3154 }
3155--- a/src/lvm.c
3156+++ b/src/lvm.c
3157@@ -25,22 +25,35 @@
3158 #include "ltable.h"
3159 #include "ltm.h"
3160 #include "lvm.h"
3161-
3162-
3163+#include "llex.h"
3164+#include "lnum.h"
3165
3166 /* limit for table tag-method chains (to avoid loops) */
3167 #define MAXTAGLOOP 100
3168
3169
3170-const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
3171- lua_Number num;
3172+/*
3173+ * If 'obj' is a string, it is tried to be interpreted as a number.
3174+ */
3175+const TValue *luaV_tonumber ( const TValue *obj, TValue *n) {
3176+ lua_Number d;
3177+ lua_Integer i;
3178+
3179 if (ttisnumber(obj)) return obj;
3180- if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
3181- setnvalue(n, num);
3182- return n;
3183- }
3184- else
3185- return NULL;
3186+
3187+ if (ttisstring(obj)) {
3188+ switch( luaO_str2d( svalue(obj), &d, &i ) ) {
3189+ case TK_INT:
3190+ setivalue(n,i); return n;
3191+ case TK_NUMBER:
3192+ setnvalue(n,d); return n;
3193+#ifdef LNUM_COMPLEX
3194+ case TK_NUMBER2: /* "N.NNNi", != 0 */
3195+ setnvalue_complex_fast(n, d*I); return n;
3196+#endif
3197+ }
3198+ }
3199+ return NULL;
3200 }
3201
3202
3203@@ -49,8 +62,7 @@ int luaV_tostring (lua_State *L, StkId o
3204 return 0;
3205 else {
3206 char s[LUAI_MAXNUMBER2STR];
3207- lua_Number n = nvalue(obj);
3208- lua_number2str(s, n);
3209+ luaO_num2buf(s,obj);
3210 setsvalue2s(L, obj, luaS_new(L, s));
3211 return 1;
3212 }
3213@@ -222,59 +234,127 @@ static int l_strcmp (const TString *ls,
3214 }
3215
3216
3217+#ifdef LNUM_COMPLEX
3218+void error_complex( lua_State *L, const TValue *l, const TValue *r )
3219+{
3220+ char buf1[ LUAI_MAXNUMBER2STR ];
3221+ char buf2[ LUAI_MAXNUMBER2STR ];
3222+ luaO_num2buf( buf1, l );
3223+ luaO_num2buf( buf2, r );
3224+ luaG_runerror( L, "unable to compare: %s with %s", buf1, buf2 );
3225+ /* no return */
3226+}
3227+#endif
3228+
3229+
3230 int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
3231 int res;
3232- if (ttype(l) != ttype(r))
3233+ int tl,tr;
3234+ lua_Integer tmp;
3235+
3236+ if (!ttype_ext_same(l,r))
3237 return luaG_ordererror(L, l, r);
3238- else if (ttisnumber(l))
3239- return luai_numlt(nvalue(l), nvalue(r));
3240- else if (ttisstring(l))
3241- return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
3242- else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
3243+#ifdef LNUM_COMPLEX
3244+ if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) )
3245+ error_complex( L, l, r );
3246+#endif
3247+ tl= ttype(l); tr= ttype(r);
3248+ if (tl==tr) { /* clear arithmetics */
3249+ switch(tl) {
3250+ case LUA_TINT: return ivalue(l) < ivalue(r);
3251+ case LUA_TNUMBER: return luai_numlt(nvalue_fast(l), nvalue_fast(r));
3252+ case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
3253+ }
3254+ } else if (tl==LUA_TINT) { /* l:int, r:num */
3255+ /* Avoid accuracy losing casts: if 'r' is integer by value, do comparisons
3256+ * in integer realm. Only otherwise cast 'l' to FP (which might change its
3257+ * value).
3258+ */
3259+ if (tt_integer_valued(r,&tmp))
3260+ return ivalue(l) < tmp;
3261+ else
3262+ return luai_numlt( cast_num(ivalue(l)), nvalue_fast(r) );
3263+
3264+ } else if (tl==LUA_TNUMBER) { /* l:num, r:int */
3265+ if (tt_integer_valued(l,&tmp))
3266+ return tmp < ivalue(r);
3267+ else
3268+ return luai_numlt( nvalue_fast(l), cast_num(ivalue(r)) );
3269+
3270+ } else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
3271 return res;
3272+
3273 return luaG_ordererror(L, l, r);
3274 }
3275
3276
3277 static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
3278 int res;
3279- if (ttype(l) != ttype(r))
3280+ int tl, tr;
3281+ lua_Integer tmp;
3282+
3283+ if (!ttype_ext_same(l,r))
3284 return luaG_ordererror(L, l, r);
3285- else if (ttisnumber(l))
3286- return luai_numle(nvalue(l), nvalue(r));
3287- else if (ttisstring(l))
3288- return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
3289- else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
3290+#ifdef LNUM_COMPLEX
3291+ if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) )
3292+ error_complex( L, l, r );
3293+#endif
3294+ tl= ttype(l); tr= ttype(r);
3295+ if (tl==tr) { /* clear arithmetics */
3296+ switch(tl) {
3297+ case LUA_TINT: return ivalue(l) <= ivalue(r);
3298+ case LUA_TNUMBER: return luai_numle(nvalue_fast(l), nvalue_fast(r));
3299+ case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
3300+ }
3301+ }
3302+ if (tl==LUA_TINT) { /* l:int, r:num */
3303+ if (tt_integer_valued(r,&tmp))
3304+ return ivalue(l) <= tmp;
3305+ else
3306+ return luai_numle( cast_num(ivalue(l)), nvalue_fast(r) );
3307+
3308+ } else if (tl==LUA_TNUMBER) { /* l:num, r:int */
3309+ if (tt_integer_valued(l,&tmp))
3310+ return tmp <= ivalue(r);
3311+ else
3312+ return luai_numle( nvalue_fast(l), cast_num(ivalue(r)) );
3313+
3314+ } else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
3315 return res;
3316 else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
3317 return !res;
3318+
3319 return luaG_ordererror(L, l, r);
3320 }
3321
3322
3323-int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
3324+/* Note: 'luaV_equalval()' and 'luaO_rawequalObj()' have largely overlapping
3325+ * implementation. LUA_TNIL..LUA_TLIGHTUSERDATA cases could be handled
3326+ * simply by the 'default' case here.
3327+ */
3328+int luaV_equalval (lua_State *L, const TValue *l, const TValue *r) {
3329 const TValue *tm;
3330- lua_assert(ttype(t1) == ttype(t2));
3331- switch (ttype(t1)) {
3332+ lua_assert(ttype_ext_same(l,r));
3333+ switch (ttype(l)) {
3334 case LUA_TNIL: return 1;
3335- case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
3336- case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
3337- case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
3338+ case LUA_TINT:
3339+ case LUA_TNUMBER: return luaO_rawequalObj(l,r);
3340+ case LUA_TBOOLEAN: return bvalue(l) == bvalue(r); /* true must be 1 !! */
3341+ case LUA_TLIGHTUSERDATA: return pvalue(l) == pvalue(r);
3342 case LUA_TUSERDATA: {
3343- if (uvalue(t1) == uvalue(t2)) return 1;
3344- tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
3345- TM_EQ);
3346+ if (uvalue(l) == uvalue(r)) return 1;
3347+ tm = get_compTM(L, uvalue(l)->metatable, uvalue(r)->metatable, TM_EQ);
3348 break; /* will try TM */
3349 }
3350 case LUA_TTABLE: {
3351- if (hvalue(t1) == hvalue(t2)) return 1;
3352- tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
3353+ if (hvalue(l) == hvalue(r)) return 1;
3354+ tm = get_compTM(L, hvalue(l)->metatable, hvalue(r)->metatable, TM_EQ);
3355 break; /* will try TM */
3356 }
3357- default: return gcvalue(t1) == gcvalue(t2);
3358+ default: return gcvalue(l) == gcvalue(r);
3359 }
3360 if (tm == NULL) return 0; /* no TM? */
3361- callTMres(L, L->top, tm, t1, t2); /* call TM */
3362+ callTMres(L, L->top, tm, l, r); /* call TM */
3363 return !l_isfalse(L->top);
3364 }
3365
3366@@ -314,30 +394,6 @@ void luaV_concat (lua_State *L, int tota
3367 }
3368
3369
3370-static void Arith (lua_State *L, StkId ra, const TValue *rb,
3371- const TValue *rc, TMS op) {
3372- TValue tempb, tempc;
3373- const TValue *b, *c;
3374- if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
3375- (c = luaV_tonumber(rc, &tempc)) != NULL) {
3376- lua_Number nb = nvalue(b), nc = nvalue(c);
3377- switch (op) {
3378- case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
3379- case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
3380- case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
3381- case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
3382- case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
3383- case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
3384- case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
3385- default: lua_assert(0); break;
3386- }
3387- }
3388- else if (!call_binTM(L, rb, rc, ra, op))
3389- luaG_aritherror(L, rb, rc);
3390-}
3391-
3392-
3393-
3394 /*
3395 ** some macros for common tasks in `luaV_execute'
3396 */
3397@@ -361,17 +417,154 @@ static void Arith (lua_State *L, StkId r
3398 #define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
3399
3400
3401-#define arith_op(op,tm) { \
3402- TValue *rb = RKB(i); \
3403- TValue *rc = RKC(i); \
3404- if (ttisnumber(rb) && ttisnumber(rc)) { \
3405- lua_Number nb = nvalue(rb), nc = nvalue(rc); \
3406- setnvalue(ra, op(nb, nc)); \
3407- } \
3408- else \
3409- Protect(Arith(L, ra, rb, rc, tm)); \
3410+/* Note: if called for unary operations, 'rc'=='rb'.
3411+ */
3412+static void Arith (lua_State *L, StkId ra, const TValue *rb,
3413+ const TValue *rc, TMS op) {
3414+ TValue tempb, tempc;
3415+ const TValue *b, *c;
3416+ lua_Number nb,nc;
3417+
3418+ if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
3419+ (c = luaV_tonumber(rc, &tempc)) != NULL) {
3420+
3421+ /* Keep integer arithmetics in the integer realm, if possible.
3422+ */
3423+ if (ttisint(b) && ttisint(c)) {
3424+ lua_Integer ib = ivalue(b), ic = ivalue(c);
3425+ lua_Integer *ri = &ra->value.i;
3426+ ra->tt= LUA_TINT; /* part of 'setivalue(ra)' */
3427+ switch (op) {
3428+ case TM_ADD: if (try_addint( ri, ib, ic)) return; break;
3429+ case TM_SUB: if (try_subint( ri, ib, ic)) return; break;
3430+ case TM_MUL: if (try_mulint( ri, ib, ic)) return; break;
3431+ case TM_DIV: if (try_divint( ri, ib, ic)) return; break;
3432+ case TM_MOD: if (try_modint( ri, ib, ic)) return; break;
3433+ case TM_POW: if (try_powint( ri, ib, ic)) return; break;
3434+ case TM_UNM: if (try_unmint( ri, ib)) return; break;
3435+ default: lua_assert(0);
3436 }
3437+ }
3438+ /* Fallback to floating point, when leaving range. */
3439
3440+#ifdef LNUM_COMPLEX
3441+ if ((nvalue_img(b)!=0) || (nvalue_img(c)!=0)) {
3442+ lua_Complex r;
3443+ if (op==TM_UNM) {
3444+ r= -nvalue_complex_fast(b); /* never an integer (or scalar) */
3445+ setnvalue_complex_fast( ra, r );
3446+ } else {
3447+ lua_Complex bb= nvalue_complex(b), cc= nvalue_complex(c);
3448+ switch (op) {
3449+ case TM_ADD: r= bb + cc; break;
3450+ case TM_SUB: r= bb - cc; break;
3451+ case TM_MUL: r= bb * cc; break;
3452+ case TM_DIV: r= bb / cc; break;
3453+ case TM_MOD:
3454+ luaG_runerror(L, "attempt to use %% on complex numbers"); /* no return */
3455+ case TM_POW: r= luai_vectpow( bb, cc ); break;
3456+ default: lua_assert(0); r=0;
3457+ }
3458+ setnvalue_complex( ra, r );
3459+ }
3460+ return;
3461+ }
3462+#endif
3463+ nb = nvalue(b); nc = nvalue(c);
3464+ switch (op) {
3465+ case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); return;
3466+ case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); return;
3467+ case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); return;
3468+ case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); return;
3469+ case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); return;
3470+ case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); return;
3471+ case TM_UNM: setnvalue(ra, luai_numunm(nb)); return;
3472+ default: lua_assert(0);
3473+ }
3474+ }
3475+
3476+ /* Either operand not a number */
3477+ if (!call_binTM(L, rb, rc, ra, op))
3478+ luaG_aritherror(L, rb, rc);
3479+}
3480+
3481+/* Helper macro to sort arithmetic operations into four categories:
3482+ * TK_INT: integer - integer operands
3483+ * TK_NUMBER: number - number (non complex, either may be integer)
3484+ * TK_NUMBER2: complex numbers (at least the other)
3485+ * 0: non-numeric (at least the other)
3486+*/
3487+#ifdef LNUM_COMPLEX
3488+static inline int arith_mode( const TValue *rb, const TValue *rc ) {
3489+ if (ttisint(rb) && ttisint(rc)) return TK_INT;
3490+ if (ttiscomplex(rb) || ttiscomplex(rc)) return TK_NUMBER2;
3491+ if (ttisnumber(rb) && ttisnumber(rc)) return TK_NUMBER;
3492+ return 0;
3493+}
3494+#else
3495+# define arith_mode(rb,rc) \
3496+ ( (ttisint(rb) && ttisint(rc)) ? TK_INT : \
3497+ (ttisnumber(rb) && ttisnumber(rc)) ? TK_NUMBER : 0 )
3498+#endif
3499+
3500+/* arith_op macro for two operators:
3501+ * automatically chooses, which function (number, integer, complex) to use
3502+ */
3503+#define ARITH_OP2_START( op_num, op_int ) \
3504+ int failed= 0; \
3505+ switch( arith_mode(rb,rc) ) { \
3506+ case TK_INT: \
3507+ if (op_int ( &(ra)->value.i, ivalue(rb), ivalue(rc) )) \
3508+ { ra->tt= LUA_TINT; break; } /* else flow through */ \
3509+ case TK_NUMBER: \
3510+ setnvalue(ra, op_num ( nvalue(rb), nvalue(rc) )); break;
3511+
3512+#define ARITH_OP2_END \
3513+ default: \
3514+ failed= 1; break; \
3515+ } if (!failed) continue;
3516+
3517+#define arith_op_continue_scalar( op_num, op_int ) \
3518+ ARITH_OP2_START( op_num, op_int ) \
3519+ ARITH_OP2_END
3520+
3521+#ifdef LNUM_COMPLEX
3522+# define arith_op_continue( op_num, op_int, op_complex ) \
3523+ ARITH_OP2_START( op_num, op_int ) \
3524+ case TK_NUMBER2: \
3525+ setnvalue_complex( ra, op_complex ( nvalue_complex(rb), nvalue_complex(rc) ) ); break; \
3526+ ARITH_OP2_END
3527+#else
3528+# define arith_op_continue(op_num,op_int,_) arith_op_continue_scalar(op_num,op_int)
3529+#endif
3530+
3531+/* arith_op macro for one operator:
3532+ */
3533+#define ARITH_OP1_START( op_num, op_int ) \
3534+ int failed= 0; \
3535+ switch( arith_mode(rb,rb) ) { \
3536+ case TK_INT: \
3537+ if (op_int ( &(ra)->value.i, ivalue(rb) )) \
3538+ { ra->tt= LUA_TINT; break; } /* else flow through */ \
3539+ case TK_NUMBER: \
3540+ setnvalue(ra, op_num (nvalue(rb))); break; \
3541+
3542+#define ARITH_OP1_END \
3543+ default: \
3544+ failed= 1; break; \
3545+ } if (!failed) continue;
3546+
3547+#ifdef LNUM_COMPLEX
3548+# define arith_op1_continue( op_num, op_int, op_complex ) \
3549+ ARITH_OP1_START( op_num, op_int ) \
3550+ case TK_NUMBER2: \
3551+ setnvalue_complex( ra, op_complex ( nvalue_complex_fast(rb) )); break; \
3552+ ARITH_OP1_END
3553+#else
3554+# define arith_op1_continue( op_num, op_int, _ ) \
3555+ ARITH_OP1_START( op_num, op_int ) \
3556+ ARITH_OP1_END
3557+#endif
3558
3559
3560 void luaV_execute (lua_State *L, int nexeccalls) {
3561@@ -472,38 +665,45 @@ void luaV_execute (lua_State *L, int nex
3562 continue;
3563 }
3564 case OP_ADD: {
3565- arith_op(luai_numadd, TM_ADD);
3566+ TValue *rb = RKB(i), *rc= RKC(i);
3567+ arith_op_continue( luai_numadd, try_addint, luai_vectadd );
3568+ Protect(Arith(L, ra, rb, rc, TM_ADD)); \
3569 continue;
3570 }
3571 case OP_SUB: {
3572- arith_op(luai_numsub, TM_SUB);
3573+ TValue *rb = RKB(i), *rc= RKC(i);
3574+ arith_op_continue( luai_numsub, try_subint, luai_vectsub );
3575+ Protect(Arith(L, ra, rb, rc, TM_SUB));
3576 continue;
3577 }
3578 case OP_MUL: {
3579- arith_op(luai_nummul, TM_MUL);
3580+ TValue *rb = RKB(i), *rc= RKC(i);
3581+ arith_op_continue(luai_nummul, try_mulint, luai_vectmul);
3582+ Protect(Arith(L, ra, rb, rc, TM_MUL));
3583 continue;
3584 }
3585 case OP_DIV: {
3586- arith_op(luai_numdiv, TM_DIV);
3587+ TValue *rb = RKB(i), *rc= RKC(i);
3588+ arith_op_continue(luai_numdiv, try_divint, luai_vectdiv);
3589+ Protect(Arith(L, ra, rb, rc, TM_DIV));
3590 continue;
3591 }
3592 case OP_MOD: {
3593- arith_op(luai_nummod, TM_MOD);
3594+ TValue *rb = RKB(i), *rc= RKC(i);
3595+ arith_op_continue_scalar(luai_nummod, try_modint); /* scalars only */
3596+ Protect(Arith(L, ra, rb, rc, TM_MOD));
3597 continue;
3598 }
3599 case OP_POW: {
3600- arith_op(luai_numpow, TM_POW);
3601+ TValue *rb = RKB(i), *rc= RKC(i);
3602+ arith_op_continue(luai_numpow, try_powint, luai_vectpow);
3603+ Protect(Arith(L, ra, rb, rc, TM_POW));
3604 continue;
3605 }
3606 case OP_UNM: {
3607 TValue *rb = RB(i);
3608- if (ttisnumber(rb)) {
3609- lua_Number nb = nvalue(rb);
3610- setnvalue(ra, luai_numunm(nb));
3611- }
3612- else {
3613- Protect(Arith(L, ra, rb, rb, TM_UNM));
3614- }
3615+ arith_op1_continue(luai_numunm, try_unmint, luai_vectunm);
3616+ Protect(Arith(L, ra, rb, rb, TM_UNM));
3617 continue;
3618 }
3619 case OP_NOT: {
3620@@ -515,11 +715,11 @@ void luaV_execute (lua_State *L, int nex
3621 const TValue *rb = RB(i);
3622 switch (ttype(rb)) {
3623 case LUA_TTABLE: {
3624- setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
3625+ setivalue(ra, luaH_getn(hvalue(rb)));
3626 break;
3627 }
3628 case LUA_TSTRING: {
3629- setnvalue(ra, cast_num(tsvalue(rb)->len));
3630+ setivalue(ra, tsvalue(rb)->len);
3631 break;
3632 }
3633 default: { /* try metamethod */
3634@@ -652,14 +852,30 @@ void luaV_execute (lua_State *L, int nex
3635 }
3636 }
3637 case OP_FORLOOP: {
3638- lua_Number step = nvalue(ra+2);
3639- lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
3640- lua_Number limit = nvalue(ra+1);
3641- if (luai_numlt(0, step) ? luai_numle(idx, limit)
3642- : luai_numle(limit, idx)) {
3643- dojump(L, pc, GETARG_sBx(i)); /* jump back */
3644- setnvalue(ra, idx); /* update internal index... */
3645- setnvalue(ra+3, idx); /* ...and external index */
3646+ /* If start,step and limit are all integers, we don't need to check
3647+ * against overflow in the looping.
3648+ */
3649+ if (ttisint(ra) && ttisint(ra+1) && ttisint(ra+2)) {
3650+ lua_Integer step = ivalue(ra+2);
3651+ lua_Integer idx = ivalue(ra) + step; /* increment index */
3652+ lua_Integer limit = ivalue(ra+1);
3653+ if (step > 0 ? (idx <= limit) : (limit <= idx)) {
3654+ dojump(L, pc, GETARG_sBx(i)); /* jump back */
3655+ setivalue(ra, idx); /* update internal index... */
3656+ setivalue(ra+3, idx); /* ...and external index */
3657+ }
3658+ } else {
3659+ /* non-integer looping (don't use 'nvalue_fast', some may be integer!)
3660+ */
3661+ lua_Number step = nvalue(ra+2);
3662+ lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
3663+ lua_Number limit = nvalue(ra+1);
3664+ if (luai_numlt(0, step) ? luai_numle(idx, limit)
3665+ : luai_numle(limit, idx)) {
3666+ dojump(L, pc, GETARG_sBx(i)); /* jump back */
3667+ setnvalue(ra, idx); /* update internal index... */
3668+ setnvalue(ra+3, idx); /* ...and external index */
3669+ }
3670 }
3671 continue;
3672 }
3673@@ -668,13 +884,21 @@ void luaV_execute (lua_State *L, int nex
3674 const TValue *plimit = ra+1;
3675 const TValue *pstep = ra+2;
3676 L->savedpc = pc; /* next steps may throw errors */
3677+ /* Using same location for tonumber's both arguments, effectively does
3678+ * in-place modification (string->number). */
3679 if (!tonumber(init, ra))
3680 luaG_runerror(L, LUA_QL("for") " initial value must be a number");
3681 else if (!tonumber(plimit, ra+1))
3682 luaG_runerror(L, LUA_QL("for") " limit must be a number");
3683 else if (!tonumber(pstep, ra+2))
3684 luaG_runerror(L, LUA_QL("for") " step must be a number");
3685- setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
3686+ /* Step back one value (keep within integers if we can)
3687+ */
3688+ if (!( ttisint(ra) && ttisint(pstep) &&
3689+ try_subint( &ra->value.i, ivalue(ra), ivalue(pstep) ) )) {
3690+ /* don't use 'nvalue_fast()', values may be integer */
3691+ setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
3692+ }
3693 dojump(L, pc, GETARG_sBx(i));
3694 continue;
3695 }
3696@@ -711,7 +935,7 @@ void luaV_execute (lua_State *L, int nex
3697 luaH_resizearray(L, h, last); /* pre-alloc it at once */
3698 for (; n > 0; n--) {
3699 TValue *val = ra+n;
3700- setobj2t(L, luaH_setnum(L, h, last--), val);
3701+ setobj2t(L, luaH_setint(L, h, last--), val);
3702 luaC_barriert(L, h, val);
3703 }
3704 continue;
3705--- a/src/lvm.h
3706+++ b/src/lvm.h
3707@@ -15,11 +15,9 @@
3708
3709 #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
3710
3711-#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
3712- (((o) = luaV_tonumber(o,n)) != NULL))
3713+#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL))
3714
3715-#define equalobj(L,o1,o2) \
3716- (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
3717+#define equalobj(L,o1,o2) (ttype_ext_same(o1,o2) && luaV_equalval(L, o1, o2))
3718
3719
3720 LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
3721--- a/src/print.c
3722+++ b/src/print.c
3723@@ -14,6 +14,7 @@
3724 #include "lobject.h"
3725 #include "lopcodes.h"
3726 #include "lundump.h"
3727+#include "lnum.h"
3728
3729 #define PrintFunction luaU_print
3730
3731@@ -59,8 +60,16 @@ static void PrintConstant(const Proto* f
3732 case LUA_TBOOLEAN:
3733 printf(bvalue(o) ? "true" : "false");
3734 break;
3735+ case LUA_TINT:
3736+ printf(LUA_INTEGER_FMT,ivalue(o));
3737+ break;
3738 case LUA_TNUMBER:
3739- printf(LUA_NUMBER_FMT,nvalue(o));
3740+#ifdef LNUM_COMPLEX
3741+ // TBD: Do we get complex values here?
3742+ { lua_Number b= nvalue_img_fast(o);
3743+ printf( LUA_NUMBER_FMT "%s" LUA_NUMBER_FMT "i", nvalue_fast(o), b>=0 ? "+":"", b ); }
3744+#endif
3745+ printf(LUA_NUMBER_FMT,nvalue_fast(o));
3746 break;
3747 case LUA_TSTRING:
3748 PrintString(rawtsvalue(o));