seqlua

annotate seqlua.c @ 17:12a7a8f5a77d

Bugfix: switched raw and meta helper functions
author jbe
date Wed Aug 20 06:40:46 2014 +0200 (2014-08-20)
parents 040a0ca089c1
children 29792283522f
rev   line source
jbe@0 1 #include <lua.h>
jbe@0 2 #include <lauxlib.h>
jbe@8 3
jbe@0 4 static int seqlua_ipairsaux_raw(lua_State *L) {
jbe@0 5 lua_Integer i;
jbe@0 6 luaL_checktype(L, 1, LUA_TTABLE);
jbe@0 7 i = luaL_checkinteger(L, 2) + 1;
jbe@0 8 lua_pushinteger(L, i);
jbe@0 9 lua_rawgeti(L, 1, i); // TODO: Lua 5.3 returns type
jbe@0 10 return lua_isnil(L, -1) ? 1 : 2;
jbe@0 11 }
jbe@0 12
jbe@0 13 static int seqlua_ipairsaux_meta(lua_State *L) {
jbe@0 14 lua_Integer i;
jbe@0 15 i = luaL_checkinteger(L, 2) + 1;
jbe@0 16 lua_pushinteger(L, i);
jbe@0 17 lua_pushinteger(L, i);
jbe@0 18 lua_gettable(L, 1); // TODO: Lua 5.3 returns type
jbe@0 19 return lua_isnil(L, -1) ? 1 : 2;
jbe@0 20 }
jbe@0 21
jbe@0 22 static int seqlua_ipairsaux_func(lua_State *L) {
jbe@0 23 lua_pushinteger(L, luaL_checkinteger(L, 2) + 1);
jbe@0 24 lua_insert(L, 1);
jbe@0 25 lua_settop(L, 2);
jbe@0 26 lua_call(L, 0, LUA_MULTRET);
jbe@0 27 if (lua_isnoneornil(L, 2)) {
jbe@0 28 lua_settop(L, 0);
jbe@0 29 lua_pushnil(L);
jbe@0 30 return 1;
jbe@0 31 } else {
jbe@0 32 return lua_gettop(L);
jbe@0 33 }
jbe@0 34 }
jbe@0 35
jbe@8 36 static int seqlua_ipairsaux_triplet(lua_State *L) {
jbe@0 37 lua_Integer i = lua_tointeger(L, lua_upvalueindex(4)) + 1;
jbe@0 38 lua_settop(L, 0);
jbe@0 39 lua_pushinteger(L, i);
jbe@0 40 lua_replace(L, lua_upvalueindex(4));
jbe@0 41 lua_pushinteger(L, i);
jbe@0 42 lua_pushvalue(L, lua_upvalueindex(1));
jbe@0 43 lua_pushvalue(L, lua_upvalueindex(2));
jbe@0 44 lua_pushvalue(L, lua_upvalueindex(3));
jbe@0 45 lua_call(L, 2, LUA_MULTRET);
jbe@0 46 if (lua_isnoneornil(L, 2)) {
jbe@0 47 lua_settop(L, 0);
jbe@0 48 lua_pushnil(L);
jbe@0 49 return 1;
jbe@0 50 } else {
jbe@0 51 lua_pushvalue(L, 2);
jbe@0 52 lua_replace(L, lua_upvalueindex(3));
jbe@0 53 return lua_gettop(L);
jbe@0 54 }
jbe@0 55 }
jbe@0 56
jbe@0 57 static int seqlua_ipairs(lua_State *L) {
jbe@8 58 luaL_checkany(L, 1); // provides better error message
jbe@0 59 if (lua_type(L, 1) == LUA_TFUNCTION) {
jbe@8 60 seqlua_ipairs_function:
jbe@0 61 if (!lua_isnoneornil(L, 2) || !lua_isnoneornil(L, 3)) {
jbe@0 62 lua_settop(L, 3);
jbe@0 63 lua_pushinteger(L, 0);
jbe@8 64 lua_pushcclosure(L, seqlua_ipairsaux_triplet, 4);
jbe@0 65 return 1;
jbe@0 66 }
jbe@0 67 lua_pushcfunction(L, seqlua_ipairsaux_func);
jbe@8 68 } else if (luaL_getmetafield(L, 1, "__call")) {
jbe@15 69 lua_pop(L, 1);
jbe@8 70 goto seqlua_ipairs_function;
jbe@0 71 } else if (luaL_getmetafield(L, 1, "__index")) {
jbe@0 72 lua_pushcfunction(L, seqlua_ipairsaux_meta);
jbe@0 73 } else {
jbe@0 74 luaL_checktype(L, 1, LUA_TTABLE);
jbe@0 75 lua_pushcfunction(L, seqlua_ipairsaux_raw);
jbe@0 76 }
jbe@0 77 lua_pushvalue(L, 1);
jbe@0 78 lua_pushinteger(L, 0);
jbe@0 79 return 3;
jbe@0 80 }
jbe@0 81
jbe@8 82 static int seqlua_iteratoraux_raw(lua_State *L) {
jbe@8 83 lua_Integer i = lua_tointeger(L, lua_upvalueindex(2)) + 1;
jbe@8 84 lua_rawgeti(L, lua_upvalueindex(1), i);
jbe@8 85 if (lua_isnil(L, -1)) return 1;
jbe@8 86 lua_pushinteger(L, i);
jbe@8 87 lua_replace(L, lua_upvalueindex(2));
jbe@8 88 return 1;
jbe@8 89 }
jbe@8 90
jbe@8 91 static int seqlua_iteratoraux_meta(lua_State *L) {
jbe@8 92 lua_Integer i = lua_tointeger(L, lua_upvalueindex(2)) + 1;
jbe@8 93 lua_pushinteger(L, i);
jbe@8 94 lua_gettable(L, lua_upvalueindex(1));
jbe@8 95 if (lua_isnil(L, -1)) return 1;
jbe@8 96 lua_pushinteger(L, i);
jbe@8 97 lua_replace(L, lua_upvalueindex(2));
jbe@8 98 return 1;
jbe@8 99 }
jbe@8 100
jbe@8 101 static int seqlua_iteratoraux_triplet(lua_State *L) {
jbe@0 102 lua_settop(L, 0);
jbe@0 103 lua_pushvalue(L, lua_upvalueindex(1));
jbe@0 104 lua_pushvalue(L, lua_upvalueindex(2));
jbe@0 105 lua_pushvalue(L, lua_upvalueindex(3));
jbe@0 106 lua_call(L, 2, LUA_MULTRET);
jbe@0 107 if (lua_isnoneornil(L, 1)) {
jbe@0 108 lua_settop(L, 1);
jbe@0 109 return 1;
jbe@0 110 }
jbe@0 111 lua_pushvalue(L, 1);
jbe@0 112 lua_replace(L, lua_upvalueindex(3));
jbe@0 113 return lua_gettop(L);
jbe@0 114 }
jbe@0 115
jbe@8 116 int seqlua_iterator(lua_State *L) {
jbe@8 117 luaL_checkany(L, 1); // provides better error message
jbe@8 118 lua_settop(L, 3);
jbe@0 119 if (lua_type(L, 1) == LUA_TFUNCTION) {
jbe@8 120 seqlua_iterator_function:
jbe@8 121 if (lua_isnil(L, 2) && lua_isnil(L, 3)) {
jbe@0 122 lua_settop(L, 1);
jbe@0 123 } else {
jbe@8 124 lua_pushcclosure(L, seqlua_iteratoraux_triplet, 3);
jbe@0 125 }
jbe@8 126 } else if (luaL_getmetafield(L, 1, "__call")) {
jbe@15 127 lua_pop(L, 1);
jbe@8 128 goto seqlua_iterator_function;
jbe@8 129 } else if (luaL_getmetafield(L, 1, "__index")) {
jbe@8 130 lua_pushvalue(L, 1);
jbe@8 131 lua_pushinteger(L, 0);
jbe@17 132 lua_pushcclosure(L, seqlua_iteratoraux_meta, 2);
jbe@0 133 } else {
jbe@8 134 luaL_checktype(L, 1, LUA_TTABLE);
jbe@8 135 lua_pushvalue(L, 1);
jbe@8 136 lua_pushinteger(L, 0);
jbe@17 137 lua_pushcclosure(L, seqlua_iteratoraux_raw, 2);
jbe@0 138 }
jbe@0 139 return 1;
jbe@0 140 }
jbe@0 141
jbe@0 142 int luaopen_seqlua(lua_State *L) {
jbe@0 143 lua_pushcfunction(L, seqlua_ipairs);
jbe@0 144 lua_setglobal(L, "ipairs");
jbe@0 145 lua_pushcfunction(L, seqlua_iterator);
jbe@0 146 lua_setglobal(L, "iterator");
jbe@0 147 return 1;
jbe@0 148 }

Impressum / About Us