[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Tuple
- From: Luis Carvalho <carvalho@...>
- Date: Thu, 16 Aug 2007 10:57:54 -0400
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;
}