# HG changeset patch # User jbe # Date 1409091047 -7200 # Node ID 92ce3958aca7cbf64882a0bb6747086baaf53798 # Parent 664736a8fcbf6600a491474b9cc0faede020df8e Reverted last two commits diff -r 664736a8fcbf -r 92ce3958aca7 README --- a/README Tue Aug 26 23:53:29 2014 +0200 +++ b/README Wed Aug 27 00:10:47 2014 +0200 @@ -1,15 +1,11 @@ seqlua: Extension for handling sequential data in Lua ===================================================== -This package is an experimental extension for the Lua programming language -(version 5.2) which: +This package is an extension for the Lua programming language (version 5.2) +which: -* makes ``ipairs(tbl)`` respect both metamethods ``__index`` and ``__ipairs`` - (where ``__ipairs`` has precedence over ``__index``), -* allows ``ipairs(seq, "call")`` to accept either tables or functions as first - argument where a function is used as iterator, -* allows ``ipairs(seq, "generator")`` to accept either tables or functions as - first argument where a function is used as generator for an iterator, +* allows ``ipairs(seq)`` to accept either tables or functions (i.e function + iterators) as an argument, * adds a new function ``string.concat(separator, seq)`` that concats either table entries or function return values, * provides auxiliary C functions and macros to simplify iterating over both @@ -98,15 +94,8 @@ This extension, however, modifies Lua's ``ipairs`` statement in such way that it automatically accepts either a table or an iterator function as argument. -Thus, the function below will accept both (table) sequences and (function) -iterators: - - function write_lines(lines) - for i, line in ipairs(lines, "call") do - io.stdout:write(line) - io.stdout:write("\n") - end - end +Thus, the first of the three ``write_lines`` functions above will accept both +(table) sequences and (function) iterators. In addition to the modification of ``ipairs``, it also provides C functions and macros to iterate over values in the same manner as a generic loop statement @@ -178,7 +167,7 @@ t = {"a", "b", "c"} - for i, v in ipairs(t, "call") do + for i, v in ipairs(t) do print(i, v) end -- prints: @@ -203,18 +192,7 @@ end end - for i, v in ipairs(alphabet(), "call") do - print(i, v) - end - -- prints: - -- 1 a - -- 2 b - -- 3 c - -- ... - -- 25 y - -- 26 z - - for i, v in ipairs(alphabet, "generator") do + for i, v in ipairs(alphabet()) do print(i, v) end -- prints: @@ -231,7 +209,7 @@ function filter(f) return function(seq) return coroutine.wrap(function() - for i, v in ipairs(seq, "call") do f(v) end + for i, v in ipairs(seq) do f(v) end end) end end @@ -261,9 +239,9 @@ In ``seqlualib.h``, the following macro is defined: - #define seqlua_iterloop(L, iter, mode, idx) \ + #define seqlua_iterloop(L, iter, idx) \ for ( \ - seqlua_iterinit((L), (iter), (mode), (idx)); \ + seqlua_iterinit((L), (iter), (idx)); \ seqlua_iternext(iter); \ ) @@ -271,7 +249,7 @@ #define seqlua_iterloopauto(L, iter, idx) \ for ( \ - seqlua_iterinit((L), (iter), (mode), (idx)); \ + seqlua_iterinit((L), (iter), (idx)); \ seqlua_iternext(iter); \ lua_pop((L), 1) \ ) @@ -281,7 +259,7 @@ int printcsv(lua_State *L) { seqlua_Iterator iter; - seqlua_iterloop(L, &iter, SEQLUA_MODE_CALL, 1) { + seqlua_iterloop(L, &iter, 1) { if (seqlua_itercount(&iter) > 1) fputs(",", stdout); fputs(luaL_tolstring(L, -1, NULL), stdout); // two values need to be popped (the value pushed by diff -r 664736a8fcbf -r 92ce3958aca7 seqlua.c --- a/seqlua.c Tue Aug 26 23:53:29 2014 +0200 +++ b/seqlua.c Wed Aug 27 00:10:47 2014 +0200 @@ -35,9 +35,6 @@ } static int seqlua_ipairs(lua_State *L) { - const char *method; - int generated = 0; - seqlua_ipairs_repeat: if (luaL_getmetafield(L, 1, "__ipairs")) { lua_pushvalue(L, 1); lua_call(L, 1, 3); @@ -58,27 +55,13 @@ } else { int t = lua_type(L, 1); if (t == LUA_TFUNCTION) { - if (generated) goto seqlua_ipairs_call; - method = lua_tostring(L, 2); - if (method) { - if (!strcmp(method, "call")) { - seqlua_ipairs_call: - lua_pushcfunction(L, seqlua_ipairsaux_call); - goto seqlua_ipairs_finish; - } else if (!strcmp(method, "generator")) { - lua_settop(L, 1); - lua_call(L, 0, 1); - generated = 1; - goto seqlua_ipairs_repeat; - } - } + lua_pushcfunction(L, seqlua_ipairsaux_call); } else if (luaL_getmetafield(L, 1, "__index")) { lua_pushcfunction(L, seqlua_ipairsaux_index); - goto seqlua_ipairs_finish; + } else { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushcfunction(L, seqlua_ipairsaux_raw); } - luaL_checktype(L, 1, LUA_TTABLE); - lua_pushcfunction(L, seqlua_ipairsaux_raw); - seqlua_ipairs_finish: lua_pushvalue(L, 1); lua_pushinteger(L, 0); } @@ -94,7 +77,7 @@ luaL_checkany(L, 2); lua_settop(L, 3); luaL_buffinit(L, &buf); - seqlua_iterloop(L, &iter, SEQLUA_MODE_CALL, 2) { + seqlua_iterloop(L, &iter, 2) { lua_replace(L, 3); if (seqlua_itercount(&iter) > 1) luaL_addlstring(&buf, sep, seplen); luaL_tolstring(L, 3, NULL); diff -r 664736a8fcbf -r 92ce3958aca7 seqlua_c_example.c --- a/seqlua_c_example.c Tue Aug 26 23:53:29 2014 +0200 +++ b/seqlua_c_example.c Wed Aug 27 00:10:47 2014 +0200 @@ -5,7 +5,7 @@ int seqlua_c_example_printcsv(lua_State *L) { seqlua_Iterator iter; - seqlua_iterloop(L, &iter, SEQLUA_MODE_CALL, 1) { + seqlua_iterloop(L, &iter, 1) { if (seqlua_itercount(&iter) > 1) fputs(",", stdout); fputs(luaL_tolstring(L, -1, NULL), stdout); // two values need to be popped (the value pushed by diff -r 664736a8fcbf -r 92ce3958aca7 seqlualib.c --- a/seqlualib.c Tue Aug 26 23:53:29 2014 +0200 +++ b/seqlualib.c Wed Aug 27 00:10:47 2014 +0200 @@ -8,11 +8,9 @@ #define SEQLUA_ITERTYPE_INDEX 3 #define SEQLUA_ITERTYPE_RAW 4 -void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int mode, int idx) { - int generated = 0; - seqlua_iterinit_repeat: +void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int idx) { if (luaL_getmetafield(L, idx, "__ipairs")) { - if (!generated) lua_pushvalue(L, idx); + lua_pushvalue(L, idx); lua_call(L, 1, 3); if (lua_type(L, -3) == LUA_TSTRING) { const char *method = lua_tostring(L, -3); @@ -31,25 +29,16 @@ } } else { if (lua_type(L, idx) == LUA_TFUNCTION) { - if (generated || mode == SEQLUA_MODE_CALL) { - iter->itertype = SEQLUA_ITERTYPE_CALL; - goto seqlua_iterinit_finish; - } else if (mode == SEQLUA_MODE_GENERATOR) { - lua_pushvalue(L, idx); - lua_call(L, 0, 1); - idx = lua_gettop(L); - goto seqlua_iterinit_repeat; - } + iter->itertype = SEQLUA_ITERTYPE_CALL; } else if (luaL_getmetafield(L, idx, "__index")) { lua_pop(L, 1); iter->itertype = SEQLUA_ITERTYPE_INDEX; - goto seqlua_iterinit_finish; + } else { + luaL_checktype(L, idx, LUA_TTABLE); + iter->itertype = SEQLUA_ITERTYPE_RAW; } - luaL_checktype(L, idx, LUA_TTABLE); - iter->itertype = SEQLUA_ITERTYPE_RAW; - seqlua_iterinit_finish: // always occupy 3 stack indicies - if (!generated) lua_pushnil(L); + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); iter->idx = idx; diff -r 664736a8fcbf -r 92ce3958aca7 seqlualib.h --- a/seqlualib.h Tue Aug 26 23:53:29 2014 +0200 +++ b/seqlualib.h Wed Aug 27 00:10:47 2014 +0200 @@ -8,23 +8,19 @@ lua_Integer i; } seqlua_Iterator; -#define SEQLUA_MODE_NONE 0 -#define SEQLUA_MODE_CALL 1 -#define SEQLUA_MODE_GENERATOR 2 - -extern void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int mode, int idx); +extern void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int idx); extern int seqlua_iternext(seqlua_Iterator *iter); -#define seqlua_iterloop(L, iter, mode, idx) \ +#define seqlua_iterloop(L, iter, idx) \ for ( \ - seqlua_iterinit((L), (iter), (mode), (idx)); \ + seqlua_iterinit((L), (iter), (idx)); \ seqlua_iternext(iter); \ ) -#define seqlua_iterloopauto(L, iter, mode, idx) \ +#define seqlua_iterloopauto(L, iter, idx) \ for ( \ - seqlua_iterinit((L), (iter), (mode), (idx)); \ + seqlua_iterinit((L), (iter), (idx)); \ seqlua_iternext(iter); \ lua_pop((L), 1) \ )