lua-users home
lua-l archive

Tuple

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


Hi,
I decided to put together a simple tuple implementation based on previous
discussions in the list (check attachment). It contains a constructor, tuple,
and an iterator, ituple. Some usage examples:
$ lua
Lua 5.1.1 Copyright (C) 1994-2006 Lua.org, PUC-Rio
> require"tuple"
> t = tuple(10,math.pi,nil,{},nil,"foo",math.sin)
> print(t())
10 3.1415926535898 nil table: 0x80828f8 nil foo function: 0x806e928
> print(t(5))
nil foo function: 0x806e928
> print(t(2,4))
3.1415926535898 nil table: 0x80828f8
> print(t(0), #t, t[2])
7 7 3.1415926535898
> f = function(arg) for i,v in ituple(arg) do print(i,v) end return tuple(arg()) end
> x = f(t)
1 10
2 3.1415926535898
3 nil
4 table: 0x80828f8
5 nil
6 foo
7 function: 0x806e928
> print(x())
10 3.1415926535898 nil table: 0x80828f8 nil foo function: 0x806e928
I've also got a list implementation with some functional facilities based on
tuples, but that's offtopic. :)
Cheers,
Luis.
-- 
A mathematician is a device for turning coffee into theorems.
 -- P. Erdos 
-- 
Luis Carvalho
Applied Math PhD Student - Brown University
PGP Key: E820854A <carvalho@dam.brown.edu>
/*
 * tuple.c v0.1
 * Simple functional tuple implementation with metatables:
 * This is similar to Roberto Ierusalimschy's tuples in PiL, but draws
 * inspiration from Rici Lake's suggestions in lua-l.
 *
 * This code is in public domain.
*/
#include <lua.h>
#include <lauxlib.h>
#define istuple(n) (lua_tocfunction(L, (n)) == tupleF)
#define tuple_validindex(n) lua_type(L, lua_upvalueindex((n))) != LUA_TNONE
#define tuple_getindex(n) lua_pushinteger(L, (n)); lua_call(L, 1, 1);
#define tuple_getlength() tuple_getindex(0)
/* functional tuple */
static int tupleF (lua_State *L) {
 int i, j, n;
 i = luaL_opt(L, lua_tointeger, 1, 1);
 if (i == 0) { /* length? */
 for (n = 1; tuple_validindex(n); n++) ;
 lua_pushinteger(L, n - 1);
 return 1;
 }
 /* tuple slicing */
 j = luaL_opt(L, lua_tointeger, 2, 0);
 if (j == 0) {
 for (n = i; tuple_validindex(n); n++)
 lua_pushvalue(L, lua_upvalueindex(n));
 }
 else {
 for (n = i; tuple_validindex(n) && n <= j; n++)
 lua_pushvalue(L, lua_upvalueindex(n));
 }
 return n - i;
}
/* methods */
static int tuple_index (lua_State *L) {
 if (istuple(1)) {
 lua_call(L, 1, 1);
 return 1;
 }
 return 0;
}
static int tuple_len (lua_State *L) {
 if (istuple(1)) {
 lua_settop(L, 1);
 tuple_getlength();
 return 1;
 }
 return 0;
}
static int newtuple (lua_State *L) {
 int n = lua_gettop(L);
 luaL_argcheck(L, n <= LUA_MINSTACK, n, "too many elements");
 lua_pushcclosure(L, tupleF, n);
 return 1;
}
static int itupleaux (lua_State *L) {
 int n, i = lua_tointeger(L, 2) + 1;
 lua_pop(L, 1);
 lua_pushvalue(L, 1); /* tuple */
 tuple_getlength();
 n = lua_tointeger(L, -1);
 lua_pop(L, 1);
 if (i <= n) {
 lua_pushinteger(L, i);
 lua_pushvalue(L, 1); /* tuple */
 tuple_getindex(i);
 return 2;
 }
 return 0;
}
static int ituple (lua_State *L) {
 lua_settop(L, 1);
 if (!istuple(1)) luaL_typerror(L, 1, "tuple");
 lua_pushcfunction(L, itupleaux);
 lua_insert(L, -2);
 lua_pushinteger(L, 0);
 return 3;
}
static const luaL_reg tuple_mt[] = {
 {"__index", tuple_index},
 {"__len", tuple_len},
 {NULL, NULL}
};
int luaopen_tuple (lua_State *L) {
 lua_pushcfunction(L, newtuple);
 lua_newtable(L); /* metatable */
 luaL_register(L, NULL, tuple_mt);
 lua_setmetatable(L, -2);
 lua_pushvalue(L, -1);
 lua_setglobal(L, "tuple");
 lua_pushcfunction(L, ituple);
 lua_setglobal(L, "ituple");
 return 1;
}

AltStyle によって変換されたページ (->オリジナル) /