Skip to content

Commit

Permalink
Add table.chunk
Browse files Browse the repository at this point in the history
  • Loading branch information
well-in-that-case authored and Sainan committed Oct 20, 2024
1 parent 31fc0f1 commit e93e6ba
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/ltablib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,11 +880,54 @@ static int tslice (lua_State *L) {
return 1;
}

static int tchunk (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);

const lua_Integer size = luaL_checkinteger(L, 2);

if (size <= 0) {
luaL_error(L, "argument 'size' to table.chunk must be greater than zero (got %d)", size);
}

lua_pop(L, 1);

lua_Integer chunk_idx = 0;
lua_Integer subtable_len = 0;

lua_newtable(L);
lua_pushnil(L);
while (lua_next(L, 1)) {
if (!lua_isnoneornil(L, 4)) { /* stack: og, result, key, value */
/* push our table to the stack. either by creating a new one, or fetching the latest subtable */
if (subtable_len % size == 0) { /* if we've reached chunk size or should start creating a new chunk */
lua_newtable(L); /* create a new table */
lua_pushinteger(L, ++chunk_idx); /* create its index */
lua_pushvalue(L, -2); /* copy reference to table */
lua_settable(L, 2); /* result[chunk_idx] = subtable */
subtable_len = 0;
}
else { /* we should already have a subtable at result[chunk_idx] */
lua_pushinteger(L, chunk_idx);
lua_gettable(L, 2); /* push result[chunk_idx] */
}

lua_pushinteger(L, ++subtable_len); /* push key for use in chunk */
lua_pushvalue(L, 4); /* push value from lua_next */
lua_settable(L, 5); /* chunk[subtable_len] = value */
}

lua_settop(L, 3); /* reset stack: og, result, key */
}

return 1;
}


/* }====================================================== */


static const luaL_Reg tab_funcs[] = {
{"chunk", tchunk},
{"slice", tslice},
{"countvalues", tcountvalues},
{"keys", tkeys},
Expand Down
23 changes: 23 additions & 0 deletions testes/pluto/basic.pluto
Original file line number Diff line number Diff line change
Expand Up @@ -2023,6 +2023,29 @@ do
assert(#table.slice(t, 2, 10) == 4)
assert(#table.slice(t, 0, 10) == #t)
end
do
local t = {1, 2, 3, 4, 5}
local chunk
chunk = t:chunk(3)
assert(chunk[1][1] == 1)
assert(chunk[1][2] == 2)
assert(chunk[1][3] == 3)
assert(chunk[2][1] == 4)
assert(chunk[2][2] == 5)
assert(chunk[2][3] == nil)
chunk = t:chunk(1)
assert(chunk[1][1] == 1)
assert(chunk[1][2] == nil)
assert(chunk[2][1] == 2)
assert(chunk[2][2] == nil)
assert(chunk[3][1] == 3)
assert(chunk[3][2] == nil)
assert(chunk[4][1] == 4)
assert(chunk[4][2] == nil)
assert(chunk[5][1] == 5)
assert(chunk[5][2] == nil)
assert(#{}:chunk(5) == 0)
end
do
assert(compareversions("0.1.0", "0.1.0") == 0)
assert(compareversions("0.1.0", "0.2.0") ~= 0)
Expand Down

0 comments on commit e93e6ba

Please sign in to comment.