lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 8e1e61860643baeb443efcdbf51bc25b0c006a88
parent af4721f7a37834e5b5469f342caed0629932a4aa
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Tue,  9 Apr 2002 17:18:44 -0300

`baselib' splited in `baselib' and `tablib'

Diffstat:
Mlbaselib.c | 296+------------------------------------------------------------------------------
Mlua.c | 3++-
Mlualib.h | 3++-
3 files changed, 5 insertions(+), 297 deletions(-)

diff --git a/lbaselib.c b/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.64 2002/04/05 18:54:31 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.65 2002/04/09 19:46:56 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -432,302 +432,8 @@ static void base_open (lua_State *L) { } -/* -** {====================================================== -** Coroutine library -** ======================================================= -*/ - - -static int luaB_resume (lua_State *L) { - lua_State *co = (lua_State *)lua_getfrombox(L, lua_upvalueindex(1)); - lua_settop(L, 0); - if (lua_resume(L, co) != 0) - lua_error(L, "error running co-routine"); - return lua_gettop(L); -} - - - -static int gc_coroutine (lua_State *L) { - lua_State *co = (lua_State *)lua_getfrombox(L, 1); - lua_closethread(L, co); - return 0; -} - - -static int luaB_coroutine (lua_State *L) { - lua_State *NL; - int ref; - int i; - int n = lua_gettop(L); - luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, - "Lua function expected"); - NL = lua_newthread(L); - if (NL == NULL) lua_error(L, "unable to create new thread"); - /* move function and arguments from L to NL */ - for (i=0; i<n; i++) { - ref = lua_ref(L, 1); - lua_getref(NL, ref); - lua_insert(NL, 1); - lua_unref(L, ref); - } - lua_cobegin(NL, n-1); - lua_newpointerbox(L, NL); - lua_pushliteral(L, "Coroutine"); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_setmetatable(L, -2); - lua_pushcclosure(L, luaB_resume, 1); - return 1; -} - - -static int luaB_yield (lua_State *L) { - return lua_yield(L, lua_gettop(L)); -} - -static const luaL_reg co_funcs[] = { - {"create", luaB_coroutine}, - {"yield", luaB_yield}, - {NULL, NULL} -}; - - -static void co_open (lua_State *L) { - luaL_opennamedlib(L, "co", co_funcs, 0); - /* create metatable for coroutines */ - lua_pushliteral(L, "Coroutine"); - lua_newtable(L); - lua_pushliteral(L, "__gc"); - lua_pushcfunction(L, gc_coroutine); - lua_rawset(L, -3); - lua_rawset(L, LUA_REGISTRYINDEX); -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Auxiliar table-related functions -*/ - -static int luaB_foreachi (lua_State *L) { - int n, i; - luaL_check_type(L, 1, LUA_TTABLE); - luaL_check_type(L, 2, LUA_TFUNCTION); - n = lua_getn(L, 1); - for (i=1; i<=n; i++) { - lua_pushvalue(L, 2); /* function */ - lua_pushnumber(L, i); /* 1st argument */ - lua_rawgeti(L, 1, i); /* 2nd argument */ - lua_rawcall(L, 2, 1); - if (!lua_isnil(L, -1)) - return 1; - lua_pop(L, 1); /* remove nil result */ - } - return 0; -} - - -static int luaB_foreach (lua_State *L) { - luaL_check_type(L, 1, LUA_TTABLE); - luaL_check_type(L, 2, LUA_TFUNCTION); - lua_pushnil(L); /* first key */ - for (;;) { - if (lua_next(L, 1) == 0) - return 0; - lua_pushvalue(L, 2); /* function */ - lua_pushvalue(L, -3); /* key */ - lua_pushvalue(L, -3); /* value */ - lua_rawcall(L, 2, 1); - if (!lua_isnil(L, -1)) - return 1; - lua_pop(L, 2); /* remove value and result */ - } -} - - -static void aux_setn (lua_State *L, int t, int n) { - lua_pushliteral(L, "n"); - lua_pushnumber(L, n); - lua_rawset(L, t); -} - - -static int luaB_getn (lua_State *L) { - luaL_check_type(L, 1, LUA_TTABLE); - lua_pushnumber(L, lua_getn(L, 1)); - return 1; -} - - -static int luaB_tinsert (lua_State *L) { - int v = lua_gettop(L); /* number of arguments */ - int n, pos; - luaL_check_type(L, 1, LUA_TTABLE); - n = lua_getn(L, 1); - if (v == 2) /* called with only 2 arguments */ - pos = n+1; - else { - v = 3; /* function may be called with more than 3 args */ - pos = luaL_check_int(L, 2); /* 2nd argument is the position */ - } - if (pos > n+1) n = pos-1; - aux_setn(L, 1, n+1); /* t.n = n+1 */ - for (; n>=pos; n--) { - lua_rawgeti(L, 1, n); - lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ - } - lua_pushvalue(L, v); - lua_rawseti(L, 1, pos); /* t[pos] = v */ - return 0; -} - - -static int luaB_tremove (lua_State *L) { - int pos, n; - luaL_check_type(L, 1, LUA_TTABLE); - n = lua_getn(L, 1); - pos = luaL_opt_int(L, 2, n); - if (n <= 0) return 0; /* table is `empty' */ - aux_setn(L, 1, n-1); /* t.n = n-1 */ - lua_rawgeti(L, 1, pos); /* result = t[pos] */ - for ( ;pos<n; pos++) { - lua_rawgeti(L, 1, pos+1); - lua_rawseti(L, 1, pos); /* a[pos] = a[pos+1] */ - } - lua_pushnil(L); - lua_rawseti(L, 1, n); /* t[n] = nil */ - return 1; -} - - - -/* -** {====================================================== -** Quicksort -** (based on `Algorithms in MODULA-3', Robert Sedgewick; -** Addison-Wesley, 1993.) -*/ - - -static void set2 (lua_State *L, int i, int j) { - lua_rawseti(L, 1, i); - lua_rawseti(L, 1, j); -} - -static int sort_comp (lua_State *L, int a, int b) { - /* WARNING: the caller (auxsort) must ensure stack space */ - if (!lua_isnoneornil(L, 2)) { /* function? */ - int res; - lua_pushvalue(L, 2); - lua_pushvalue(L, a-1); /* -1 to compensate function */ - lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ - lua_rawcall(L, 2, 1); - res = lua_toboolean(L, -1); - lua_pop(L, 1); - return res; - } - else /* a < b? */ - return lua_lessthan(L, a, b); -} - -static void auxsort (lua_State *L, int l, int u) { - while (l < u) { /* for tail recursion */ - int i, j; - /* sort elements a[l], a[(l+u)/2] and a[u] */ - lua_rawgeti(L, 1, l); - lua_rawgeti(L, 1, u); - if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ - set2(L, l, u); /* swap a[l] - a[u] */ - else - lua_pop(L, 2); - if (u-l == 1) break; /* only 2 elements */ - i = (l+u)/2; - lua_rawgeti(L, 1, i); - lua_rawgeti(L, 1, l); - if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */ - set2(L, i, l); - else { - lua_pop(L, 1); /* remove a[l] */ - lua_rawgeti(L, 1, u); - if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */ - set2(L, i, u); - else - lua_pop(L, 2); - } - if (u-l == 2) break; /* only 3 elements */ - lua_rawgeti(L, 1, i); /* Pivot */ - lua_pushvalue(L, -1); - lua_rawgeti(L, 1, u-1); - set2(L, i, u-1); - /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */ - i = l; j = u-1; - for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ - /* repeat ++i until a[i] >= P */ - while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { - if (i>u) lua_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[i] */ - } - /* repeat --j until a[j] <= P */ - while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { - if (j<l) lua_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[j] */ - } - if (j<i) { - lua_pop(L, 3); /* pop pivot, a[i], a[j] */ - break; - } - set2(L, i, j); - } - lua_rawgeti(L, 1, u-1); - lua_rawgeti(L, 1, i); - set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */ - /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ - /* adjust so that smaller half is in [j..i] and larger one in [l..u] */ - if (i-l < u-i) { - j=l; i=i-1; l=i+2; - } - else { - j=i+1; i=u; u=j-2; - } - auxsort(L, j, i); /* call recursively the smaller one */ - } /* repeat the routine for the larger one */ -} - -static int luaB_sort (lua_State *L) { - int n; - luaL_check_type(L, 1, LUA_TTABLE); - n = lua_getn(L, 1); - if (!lua_isnone(L, 2)) /* is there a 2nd argument? */ - luaL_check_type(L, 2, LUA_TFUNCTION); - lua_settop(L, 2); /* make sure there is two arguments */ - auxsort(L, 1, n); - return 0; -} - -/* }====================================================== */ - - -static const luaL_reg array_funcs[] = { - {"foreach", luaB_foreach}, - {"foreachi", luaB_foreachi}, - {"getn", luaB_getn}, - {"sort", luaB_sort}, - {"insert", luaB_tinsert}, - {"remove", luaB_tremove}, - {NULL, NULL} -}; - -/* }====================================================== */ - - - LUALIB_API int lua_baselibopen (lua_State *L) { base_open(L); - co_open(L); - luaL_opennamedlib(L, "tab", array_funcs, 0); /* `require' needs an empty table as upvalue */ lua_newtable(L); lua_pushcclosure(L, luaB_require, 1); diff --git a/lua.c b/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.80 2002/04/01 14:42:33 roberto Exp roberto $ +** $Id: lua.c,v 1.81 2002/04/05 18:54:31 roberto Exp roberto $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -342,6 +342,7 @@ static void register_getargs (char *argv[]) { static void openstdlibs (lua_State *l) { lua_baselibopen(l); + lua_tablibopen(l); lua_iolibopen(l); lua_strlibopen(l); lua_mathlibopen(l); diff --git a/lualib.h b/lualib.h @@ -1,5 +1,5 @@ /* -** $Id: lualib.h,v 1.20 2001/03/06 20:09:38 roberto Exp roberto $ +** $Id: lualib.h,v 1.21 2001/03/26 14:31:49 roberto Exp roberto $ ** Lua standard libraries ** See Copyright Notice in lua.h */ @@ -19,6 +19,7 @@ #define LUA_ALERT "_ALERT" LUALIB_API int lua_baselibopen (lua_State *L); +LUALIB_API int lua_tablibopen (lua_State *L); LUALIB_API int lua_iolibopen (lua_State *L); LUALIB_API int lua_strlibopen (lua_State *L); LUALIB_API int lua_mathlibopen (lua_State *L);