From 29f7c22f9c32dfd9d082aaab3273e3aa293e2802 Mon Sep 17 00:00:00 2001 From: Dibyendu Majumdar Date: Tue, 14 Apr 2015 00:45:23 +0100 Subject: [PATCH] implement pairs() for ravi arrays --- include/ltable.h | 1 - ravi-tests/ravi_tests1.ravi | 18 +++++++++++ src/lapi.c | 6 +++- src/ltable.c | 62 ++++++++++++++++++++++++++++--------- 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/include/ltable.h b/include/ltable.h index 9617e8f7..4ae3f9b5 100644 --- a/include/ltable.h +++ b/include/ltable.h @@ -45,7 +45,6 @@ LUAI_FUNC int luaH_getn (Table *t); LUAI_FUNC Table *raviH_new(lua_State *L, ravitype_t tt); /* RAVI array specialization */ LUAI_FUNC int raviH_getn(Table *t); /* RAVI array specialization */ - LUAI_FUNC void raviH_set_int(lua_State *L, Table *t, lua_Unsigned key, lua_Integer value); /* RAVI array specialization */ LUAI_FUNC void raviH_set_float(lua_State *L, Table *t, lua_Unsigned key, lua_Number value); /* RAVI array specialization */ diff --git a/ravi-tests/ravi_tests1.ravi b/ravi-tests/ravi_tests1.ravi index 4176f13e..4fefb615 100644 --- a/ravi-tests/ravi_tests1.ravi +++ b/ravi-tests/ravi_tests1.ravi @@ -578,3 +578,21 @@ end assert(ravi.compile(x)) assert(x() == 28) print("test 41 OK") + +-- test 42 +-- Ravi arrays support for pairs() +-- Plus special slot at [0] +x = function() + local nums: integer[] = {1, 2, 3, 4, 5, 6, 7} + local t = 0 + assert(#nums == 7) + nums[0] = 558 + for k,v in pairs(nums) do + t = t + v + end + assert(nums[0] == 558) + return t +end +assert(ravi.compile(x)) +assert(x() == 28) +print("test 42 OK") diff --git a/src/lapi.c b/src/lapi.c index f0b40d8b..d1a81f62 100644 --- a/src/lapi.c +++ b/src/lapi.c @@ -710,11 +710,14 @@ LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { StkId t; TValue k; + Table *h; lua_lock(L); t = index2addr(L, idx); api_check(ttistable(t), "table expected"); + h = hvalue(t); + api_check(h->ravi_array.type == RAVI_TTABLE, "Lua table expected"); setpvalue(&k, cast(void *, p)); - setobj2s(L, L->top, luaH_get(hvalue(t), &k)); + setobj2s(L, L->top, luaH_get(h, &k)); api_incr_top(L); lua_unlock(L); return ttnov(L->top - 1); @@ -932,6 +935,7 @@ LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { o = index2addr(L, idx); api_check(ttistable(o), "table expected"); t = hvalue(o); + api_check(t->ravi_array.type == RAVI_TTABLE, "Lua table expected"); setpvalue(&k, cast(void *, p)); setobj2t(L, luaH_set(L, t, &k), L->top - 1); luaC_barrierback(L, t, L->top - 1); diff --git a/src/ltable.c b/src/ltable.c index e92b11e7..3b265135 100644 --- a/src/ltable.c +++ b/src/ltable.c @@ -189,27 +189,61 @@ static unsigned int findindex (lua_State *L, Table *t, StkId key) { } } +/* RAVI's implementation of luaH_next() equivalent + * if no more keys return 0 + * else return 1 + * If key is nil then start the iterator + * set value to key+1 + * increment *key + */ +int raviH_next(lua_State *L, Table *t, StkId key) { + lua_Integer i; + if (ttisnil(key)) + /* Lua keys start at 1 so this is just before that + * (although 0 is valid Ravi index it cannot be + * accessed using this method) + */ + i = 0; + else if (!tointeger(key, &i)) { + return 0; + } + i = i + 1; + if (i >= t->ravi_array.len) + /* no more keys */ + return 0; + setivalue(key, i); + if (t->ravi_array.type == RAVI_TARRAYFLT) { + raviH_get_float_inline(L, t, i, (key + 1)); + } + else { + raviH_get_int_inline(L, t, i, (key + 1)); + } + return 1; +} int luaH_next (lua_State *L, Table *t, StkId key) { - unsigned int i = findindex(L, t, key); /* find original element */ - for (; i < t->sizearray; i++) { /* try first array part */ - if (!ttisnil(&t->array[i])) { /* a non-nil value? */ - setivalue(key, i + 1); - setobj2s(L, key+1, &t->array[i]); - return 1; + if (t->ravi_array.type != RAVI_TTABLE) + return raviH_next(L, t, key); + else { + unsigned int i = findindex(L, t, key); /* find original element */ + for (; i < t->sizearray; i++) { /* try first array part */ + if (!ttisnil(&t->array[i])) { /* a non-nil value? */ + setivalue(key, i + 1); + setobj2s(L, key + 1, &t->array[i]); + return 1; + } } - } - for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */ - if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ - setobj2s(L, key, gkey(gnode(t, i))); - setobj2s(L, key+1, gval(gnode(t, i))); - return 1; + for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */ + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ + setobj2s(L, key, gkey(gnode(t, i))); + setobj2s(L, key + 1, gval(gnode(t, i))); + return 1; + } } + return 0; /* no more elements */ } - return 0; /* no more elements */ } - /* ** {============================================================= ** Rehash