Skip to content

Instantly share code, notes, and snippets.

@airstruck
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save airstruck/a3344a67830962a92a80 to your computer and use it in GitHub Desktop.
Save airstruck/a3344a67830962a92a80 to your computer and use it in GitHub Desktop.
#include <lua.h>
#include <lauxlib.h>
int tuple (lua_State *L) {
/* first upvalue is number of tuple values */
int argc = luaL_checkint(L, lua_upvalueindex(1));
/* if arg is "#", return number of tuple values */
const char *count = luaL_optstring(L, 1, "");
if (count[0] == '#') {
lua_pushnumber(L, argc);
return 1;
}
int index = luaL_optint(L, 1, 0);
/* if arg is nothing or 0, return all values */
if (index == 0) {
int i;
for (i = 2; i <= argc + 1; i++) {
lua_pushvalue(L, lua_upvalueindex(i));
}
return argc;
}
/* if arg is invalid index, return nothing */
if (index < 0 || index > argc) {
return 0;
}
/* else arg is valid index, return value at index */
lua_pushvalue(L, lua_upvalueindex(index + 1));
return 1;
}
int tuple_new (lua_State *L) {
/* push number of args onto bottom of stack */
int argc = lua_gettop(L);
lua_pushnumber(L, argc);
lua_insert(L, 1);
/* return tuple function */
lua_pushcclosure(L, tuple, argc + 1);
return 1;
}
int luaopen_tuple (lua_State *L) {
lua_pushcclosure(L, tuple_new, 0);
return 1;
}
local tuple = require 'tuple'
local t = tuple(123, 'x', {})
print(t()) -- prints 123, x, table[...]
print(t(2)) -- prints x
print(t('#')) -- prints 3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment