[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Iterate over vararg
- From: Gabriel Bertilson <arboreous.philologist@...>
- Date: Thu, 20 Dec 2018 06:47:34 -0600
Thank you, that simplifies the code. I've also added a nil argument to
the script to make sure it works.
#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
// from lfunc.h
#define MAXUPVAL 255
static int iter_varargs (lua_State * L) {
lua_Integer i = luaL_checkinteger(L, 2) + 1;
if (!lua_isnone(L, lua_upvalueindex(i))) {
lua_pushinteger(L, i);
// Return the i-th argument to gen_iter_varargs.
lua_pushvalue(L, lua_upvalueindex(i));
return 2;
}
lua_pushnil(L);
return 1;
}
static int gen_iter_varargs (lua_State * L) {
int n = lua_gettop(L);
if (n > MAXUPVAL) { // impossible?
return luaL_error(L, "too many arguments");
}
// Set all arguments as upvalues to iter_varargs.
lua_pushcclosure(L, iter_varargs, n);
lua_pushnil(L);
lua_pushinteger(L, 0);
return 3;
}
int main (int argc, char * * argv) {
lua_State * L = luaL_newstate();
luaL_openlibs(L);
lua_register(L, "args", gen_iter_varargs);
if (luaL_dostring(L, "for i, val in args(1, 2, 3, nil, 4) do
print(val and val * val) end"))
printf("failed to execute script\n");
lua_close(L);
return 0;
}
— Gabriel
On Thu, Dec 20, 2018 at 5:38 AM Roberto Ierusalimschy
<roberto@inf.puc-rio.br> wrote:
>
> > [...] (Is there a way to avoid that first upvalue?) [...]
>
> Yes:
>
> Any access to lua_upvalueindex(n), where n is greater than the number
> of upvalues of the current function (but not greater than 256, which
> is one plus the maximum number of upvalues in a closure), produces an
> acceptable but invalid index.
>
> https://www.lua.org/manual/5.3/manual.html#4.4
>
> Plus:
>
> For functions that can be called with acceptable indices, any
> non-valid index is treated as if it contains a value of a virtual type
> LUA_TNONE, [...]
>
> https://www.lua.org/manual/5.3/manual.html#4.3
>
> -- Roberto
>