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  

Impressum / About Us