lua-users home
lua-l archive

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


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
>