first steps in the support of integers: basic representation + table indexing + basic API ops (tointeger/pushinteger) + equality + a few extra stuff

This commit is contained in:
Roberto Ierusalimschy
2013-04-15 12:44:46 -03:00
parent 7a543cfae6
commit 07f861385e
4 changed files with 87 additions and 158 deletions

View File

@@ -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);