seqlua

annotate seqlua.c @ 15:a95fbd16473f

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

Impressum / About Us