lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 31 August 2015 at 10:56, Soni L. <fakedme@gmail.com> wrote:
> Third: Stacks.
>
> There are 2 ways to do a stack object in Lua: Either you use tables (PITA),
> or you use coroutines: (code may or may not be correct - other examples
> available online)
>
> local function stackinternals(op, x, ...)
>   if op == "push" then
>     local a, b = coroutine.yield()
>     return stackinternals(a, b, x, ...)
>   elseif op == "pop" then
>     local a, b = coroutine.yield(...)
>     return stackinternals(a, b, select(2, ...))
>   elseif op == "peek" then
>     local a, b = coroutine.yield(...)
>     return stackinternals(a, b, ...)
>   end
> end
> function newstack(...)
>   local co = coroutine.wrap(function(...)
>     local a, b = coroutine.yield()
>     return stackinternals(a, b, ...)
>   end)
>   co(...)
>   return co
> end
>
> (It's also A LOT faster than a table-based implementation, and if done
> in-thread instead of using coroutines it's even faster!)

This is an interesting one.
I was playing around creating different things using this style, and
discovered a real need for a 'settop' like function from lua.
That is, a function that removes trailing vararg values.
I was surprised to find that it's hard/slow to implement in lua alone
for arbitrary `n`,
It's very simple to write from C:

```C
#include <lua.h>
#include <lauxlib.h>

static int settop(lua_State *L) {
        int n = luaL_checkinteger(L, 1);
        luaL_argcheck(L, n >= 0, 1, NULL);
        luaL_checkstack(L, n+1, NULL);
        lua_settop(L, n+1);
        return n;
}

int luaopen_settop(lua_State *L) {
        lua_pushcfunction(L, settop);
        return 1;
}
```

It wouldn't be a bad addition to the lua base library.

A few interesting uses of it:
  - acts like parenthesis (...) discarding unwanted arguments without
temporaries in a call: `foo("bar", settop(1, somestring:gsub(".",
qux))))`
      - but with the benefit of working with any number of arguments
instead of just 1
  - getting a list of nils for preallocating a table: `{settop(100)}`
(see http://lua-users.org/lists/lua-l/2009-06/msg00438.html)