From 07f861385eaa0073af98261ae2919ad9bbce813c Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 15 Apr 2013 12:44:46 -0300 Subject: first steps in the support of integers: basic representation + table indexing + basic API ops (tointeger/pushinteger) + equality + a few extra stuff --- ltable.c | 63 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 24 deletions(-) (limited to 'ltable.c') diff --git a/ltable.c b/ltable.c index 8c971b27..7147f6fe 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.71 2012/05/23 15:37:09 roberto Exp roberto $ +** $Id: ltable.c,v 2.71 2012/05/23 15:37:09 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -52,6 +52,7 @@ #define hashstr(t,str) hashpow2(t, (str)->tsv.hash) #define hashboolean(t,p) hashpow2(t, p) +#define hashint(t,i) hashpow2(t, i) /* @@ -96,8 +97,12 @@ static Node *hashnum (const Table *t, lua_Number n) { */ static Node *mainposition (const Table *t, const TValue *key) { switch (ttype(key)) { - case LUA_TNUMBER: - return hashnum(t, nvalue(key)); + case LUA_TNUMINT: + return hashint(t, ivalue(key)); + case LUA_TNUMFLT: + return hashnum(t, fltvalue(key)); + case LUA_TSHRSTR: + return hashstr(t, rawtsvalue(key)); case LUA_TLNGSTR: { TString *s = rawtsvalue(key); if (s->tsv.extra == 0) { /* no hash? */ @@ -106,8 +111,6 @@ static Node *mainposition (const Table *t, const TValue *key) { } return hashstr(t, rawtsvalue(key)); } - case LUA_TSHRSTR: - return hashstr(t, rawtsvalue(key)); case LUA_TBOOLEAN: return hashboolean(t, bvalue(key)); case LUA_TLIGHTUSERDATA: @@ -120,19 +123,24 @@ static Node *mainposition (const Table *t, const TValue *key) { } +static int numisint (lua_Number n, int *p) { + int k; + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) { /* 'k' is int? */ + *p = k; + return 1; + } + return 0; +} + + /* ** returns the index for `key' if `key' is an appropriate key to live in ** the array part of the table, -1 otherwise. */ static int arrayindex (const TValue *key) { - if (ttisnumber(key)) { - lua_Number n = nvalue(key); - int k; - lua_number2int(k, n); - if (luai_numeq(cast_num(k), n)) - return k; - } - return -1; /* `key' did not match some condition */ + if (ttisinteger(key)) return ivalue(key); + else return -1; /* `key' did not match some condition */ } @@ -170,7 +178,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) { int i = findindex(L, t, key); /* find original element */ for (i++; i < t->sizearray; i++) { /* try first array part */ if (!ttisnil(&t->array[i])) { /* a non-nil value? */ - setnvalue(key, cast_num(i+1)); + setivalue(key, i + 1); setobj2s(L, key+1, &t->array[i]); return 1; } @@ -404,9 +412,18 @@ static Node *getfreepos (Table *t) { */ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { Node *mp; + TValue aux; if (ttisnil(key)) luaG_runerror(L, "table index is nil"); - else if (ttisnumber(key) && luai_numisnan(L, nvalue(key))) - luaG_runerror(L, "table index is NaN"); + else if (ttisfloat(key)) { + lua_Number n = fltvalue(key); + int k; + if (luai_numisnan(L, n)) + luaG_runerror(L, "table index is NaN"); + if (numisint(n, &k)) { /* index is int? */ + setivalue(&aux, k); + key = &aux; /* insert it as an integer */ + } + } mp = mainposition(t, key); if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ Node *othern; @@ -448,10 +465,9 @@ const TValue *luaH_getint (Table *t, int key) { if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) return &t->array[key-1]; else { - lua_Number nk = cast_num(key); - Node *n = hashnum(t, nk); + Node *n = hashint(t, key); do { /* check whether `key' is somewhere in the chain */ - if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) return gval(n); /* that's it */ else n = gnext(n); } while (n); @@ -481,12 +497,11 @@ const TValue *luaH_getstr (Table *t, TString *key) { const TValue *luaH_get (Table *t, const TValue *key) { switch (ttype(key)) { case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key)); + case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); case LUA_TNIL: return luaO_nilobject; - case LUA_TNUMBER: { + case LUA_TNUMFLT: { int k; - lua_Number n = nvalue(key); - lua_number2int(k, n); - if (luai_numeq(cast_num(k), n)) /* index is int? */ + if (numisint(fltvalue(key), &k)) /* index is int? */ return luaH_getint(t, k); /* use specialized version */ /* else go through */ } @@ -522,7 +537,7 @@ void luaH_setint (lua_State *L, Table *t, int key, TValue *value) { cell = cast(TValue *, p); else { TValue k; - setnvalue(&k, cast_num(key)); + setivalue(&k, key); cell = luaH_newkey(L, t, &k); } setobj2t(L, cell, value); -- cgit v1.2.3-55-g6feb