seqlua
changeset 25:44880bcfc323
Macro seqlua_iterloop doesn't automatically pop the value anymore (use seqlua_iterloopauto instead); New function string.concat(sep, seq) introduced
author | jbe |
---|---|
date | Thu Aug 21 21:32:01 2014 +0200 (2014-08-21) |
parents | 28d472cc7a9b |
children | 8ff86106e2fe |
files | Makefile README seqlua.c seqlua_c_example.c seqlualib.h |
line diff
1.1 --- a/Makefile Thu Aug 21 20:20:20 2014 +0200 1.2 +++ b/Makefile Thu Aug 21 21:32:01 2014 +0200 1.3 @@ -8,8 +8,8 @@ 1.4 seqlualib.o: seqlualib.c seqlualib.h 1.5 cc -O2 -c -fpic -I $(LUA_INCLUDE) -o seqlualib.o seqlualib.c 1.6 1.7 -seqlua.so: seqlua.o 1.8 - ld -shared -o seqlua.so seqlua.o 1.9 +seqlua.so: seqlua.o seqlualib.o 1.10 + ld -shared -o seqlua.so seqlua.o seqlualib.o 1.11 1.12 seqlua.o: seqlua.c seqlualib.h 1.13 cc -O2 -c -fpic -I $(LUA_INCLUDE) -o seqlua.o seqlua.c
2.1 --- a/README Thu Aug 21 20:20:20 2014 +0200 2.2 +++ b/README Thu Aug 21 21:32:01 2014 +0200 2.3 @@ -3,10 +3,18 @@ 2.4 2.5 This is an experimental package to extend Lua in the following manner: 2.6 2.7 -* allow ipairs(...) to accept tables as well as functions 2.8 +* allow ``ipairs(seq)`` to accept tables as well as functions, 2.9 +* add a new function ``string.concat(separator, seq)`` to concat either table 2.10 + entries or function return values, 2.11 * provide auxiliary C functions and macros to simplify iterating over both 2.12 tables and iterator functions with the same statement. 2.13 2.14 +In other words: 2.15 +When calling ``ipairs(seq)`` or ``string.concat(separator, seq)``, 2.16 +then ``seq`` may either be a (table) sequence or a (function) iterator. 2.17 +Auxiliary C functions and macros are provided to simplify extending your own 2.18 +C functions in the same manner. 2.19 + 2.20 This library completely ignores the ``__ipairs`` metamethod (as it is 2.21 deprecated since Lua 5.3.0-alpha). It respects, however, any ``__index`` and 2.22 ``__call`` metamethods (this may cause unexpected behavior when passing 2.23 @@ -18,7 +26,8 @@ 2.24 Lua part of the library 2.25 ----------------------- 2.26 2.27 -The new ``ipairs(...)`` function works as follows: 2.28 +The modified ``ipairs(seq)`` function and the new ``string.concat`` function 2.29 +work as demonstrated in the following examples: 2.30 2.31 require "seqlua" 2.32 2.33 @@ -32,6 +41,9 @@ 2.34 -- 2 b 2.35 -- 3 c 2.36 2.37 + print(string.concat(",", t)) 2.38 + -- prints: a,b,c 2.39 + 2.40 function alphabet() 2.41 local letter = nil 2.42 return function() 2.43 @@ -57,6 +69,9 @@ 2.44 -- 25 y 2.45 -- 26 z 2.46 2.47 + print(string.concat(",", alphabet())) 2.48 + -- prints: a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z 2.49 + 2.50 function filter(f, seq) 2.51 return coroutine.wrap(function() 2.52 for i, v in ipairs(seq) do f(v) end 2.53 @@ -85,6 +100,9 @@ 2.54 -- true 2.55 -- c 2.56 2.57 + print((","):concat(filter(filterfunc, {"a", "b", 3, "c"}))) 2.58 + -- prints: a,b,true,true,true,c 2.59 + 2.60 2.61 C part of the library 2.62 --------------------- 2.63 @@ -95,6 +113,14 @@ 2.64 for ( \ 2.65 seqlua_iterinit((L), (iter), (idx)); \ 2.66 seqlua_iternext(iter); \ 2.67 + ) 2.68 + 2.69 +and 2.70 + 2.71 + #define seqlua_iterloopauto(L, iter, idx) \ 2.72 + for ( \ 2.73 + seqlua_iterinit((L), (iter), (idx)); \ 2.74 + seqlua_iternext(iter); \ 2.75 lua_pop((L), 1) \ 2.76 ) 2.77 2.78 @@ -106,7 +132,9 @@ 2.79 seqlua_iterloop(L, &iter, 1) { 2.80 if (seqlua_itercount(&iter) > 1) fputs(",", stdout); 2.81 fputs(luaL_tolstring(L, -1, NULL), stdout); 2.82 - lua_pop(L, 1); // pops value that luaL_tolstring pushed onto stack 2.83 + // two values need to be popped (the value pushed by 2.84 + // seqlua_iternext and the value pushed by luaL_tolstring) 2.85 + lua_pop(L, 2); 2.86 } 2.87 fputs("\n", stdout); 2.88 return 0;
3.1 --- a/seqlua.c Thu Aug 21 20:20:20 2014 +0200 3.2 +++ b/seqlua.c Thu Aug 21 21:32:01 2014 +0200 3.3 @@ -1,5 +1,6 @@ 3.4 #include <lua.h> 3.5 #include <lauxlib.h> 3.6 +#include "seqlualib.h" 3.7 3.8 static int seqlua_ipairsaux_raw(lua_State *L) { 3.9 lua_Integer i; 3.10 @@ -51,8 +52,30 @@ 3.11 return 3; 3.12 } 3.13 3.14 +static int seqlua_concat(lua_State *L) { 3.15 + const char *sep; 3.16 + size_t seplen; 3.17 + luaL_Buffer buf; 3.18 + seqlua_Iterator iter; 3.19 + sep = luaL_checklstring(L, 1, &seplen); 3.20 + luaL_checkany(L, 2); 3.21 + lua_settop(L, 3); 3.22 + luaL_buffinit(L, &buf); 3.23 + seqlua_iterloop(L, &iter, 2) { 3.24 + lua_replace(L, 3); 3.25 + if (seqlua_itercount(&iter) > 1) luaL_addlstring(&buf, sep, seplen); 3.26 + luaL_tolstring(L, 3, NULL); 3.27 + luaL_addvalue(&buf); 3.28 + } 3.29 + luaL_pushresult(&buf); 3.30 + return 1; 3.31 +} 3.32 + 3.33 int luaopen_seqlua(lua_State *L) { 3.34 lua_pushcfunction(L, seqlua_ipairs); 3.35 lua_setglobal(L, "ipairs"); 3.36 - return 1; 3.37 + lua_getglobal(L, "string"); 3.38 + lua_pushcfunction(L, seqlua_concat); 3.39 + lua_setfield(L, -2, "concat"); 3.40 + return 0; 3.41 }
4.1 --- a/seqlua_c_example.c Thu Aug 21 20:20:20 2014 +0200 4.2 +++ b/seqlua_c_example.c Thu Aug 21 21:32:01 2014 +0200 4.3 @@ -3,12 +3,14 @@ 4.4 #include "seqlualib.h" 4.5 #include <stdio.h> 4.6 4.7 -static int seqlua_c_example_printcsv(lua_State *L) { 4.8 +int seqlua_c_example_printcsv(lua_State *L) { 4.9 seqlua_Iterator iter; 4.10 seqlua_iterloop(L, &iter, 1) { 4.11 if (seqlua_itercount(&iter) > 1) fputs(",", stdout); 4.12 fputs(luaL_tolstring(L, -1, NULL), stdout); 4.13 - lua_pop(L, 1); // pop value that luaL_tolstring pushed onto stack 4.14 + // two values need to be popped (the value pushed by 4.15 + // seqlua_iternext and the value pushed by luaL_tolstring) 4.16 + lua_pop(L, 2); 4.17 } 4.18 fputs("\n", stdout); 4.19 return 0;
5.1 --- a/seqlualib.h Thu Aug 21 20:20:20 2014 +0200 5.2 +++ b/seqlualib.h Thu Aug 21 21:32:01 2014 +0200 5.3 @@ -16,6 +16,12 @@ 5.4 for ( \ 5.5 seqlua_iterinit((L), (iter), (idx)); \ 5.6 seqlua_iternext(iter); \ 5.7 + ) 5.8 + 5.9 +#define seqlua_iterloopauto(L, iter, idx) \ 5.10 + for ( \ 5.11 + seqlua_iterinit((L), (iter), (idx)); \ 5.12 + seqlua_iternext(iter); \ 5.13 lua_pop((L), 1) \ 5.14 ) 5.15