seqlua

annotate seqlua.c @ 0:47f9b323d68c

Initial commit
author jbe
date Wed Aug 20 00:39:10 2014 +0200 (2014-08-20)
parents
children 144f0bddee2b
rev   line source
jbe@0 1 #include <lua.h>
jbe@0 2 #include <lauxlib.h>
jbe@0 3 #include "seqlualib.h"
jbe@0 4
jbe@0 5 static int seqlua_ipairsaux_raw(lua_State *L) {
jbe@0 6 lua_Integer i;
jbe@0 7 luaL_checktype(L, 1, LUA_TTABLE);
jbe@0 8 i = luaL_checkinteger(L, 2) + 1;
jbe@0 9 lua_pushinteger(L, i);
jbe@0 10 lua_rawgeti(L, 1, i); // TODO: Lua 5.3 returns type
jbe@0 11 return lua_isnil(L, -1) ? 1 : 2;
jbe@0 12 }
jbe@0 13
jbe@0 14 static int seqlua_ipairsaux_meta(lua_State *L) {
jbe@0 15 lua_Integer i;
jbe@0 16 i = luaL_checkinteger(L, 2) + 1;
jbe@0 17 lua_pushinteger(L, i);
jbe@0 18 lua_pushinteger(L, i);
jbe@0 19 lua_gettable(L, 1); // TODO: Lua 5.3 returns type
jbe@0 20 return lua_isnil(L, -1) ? 1 : 2;
jbe@0 21 }
jbe@0 22
jbe@0 23 static int seqlua_ipairsaux_func(lua_State *L) {
jbe@0 24 luaL_checktype(L, 1, LUA_TFUNCTION);
jbe@0 25 lua_pushinteger(L, luaL_checkinteger(L, 2) + 1);
jbe@0 26 lua_insert(L, 1);
jbe@0 27 lua_settop(L, 2);
jbe@0 28 lua_call(L, 0, LUA_MULTRET);
jbe@0 29 if (lua_isnoneornil(L, 2)) {
jbe@0 30 lua_settop(L, 0);
jbe@0 31 lua_pushnil(L);
jbe@0 32 return 1;
jbe@0 33 } else {
jbe@0 34 return lua_gettop(L);
jbe@0 35 }
jbe@0 36 }
jbe@0 37
jbe@0 38 static int seqlua_ipairsaux_funcclosure(lua_State *L) {
jbe@0 39 lua_Integer i = lua_tointeger(L, lua_upvalueindex(4)) + 1;
jbe@0 40 lua_settop(L, 0);
jbe@0 41 lua_pushinteger(L, i);
jbe@0 42 lua_replace(L, lua_upvalueindex(4));
jbe@0 43 lua_pushinteger(L, i);
jbe@0 44 lua_pushvalue(L, lua_upvalueindex(1));
jbe@0 45 lua_pushvalue(L, lua_upvalueindex(2));
jbe@0 46 lua_pushvalue(L, lua_upvalueindex(3));
jbe@0 47 lua_call(L, 2, LUA_MULTRET);
jbe@0 48 if (lua_isnoneornil(L, 2)) {
jbe@0 49 lua_settop(L, 0);
jbe@0 50 lua_pushnil(L);
jbe@0 51 return 1;
jbe@0 52 } else {
jbe@0 53 lua_pushvalue(L, 2);
jbe@0 54 lua_replace(L, lua_upvalueindex(3));
jbe@0 55 return lua_gettop(L);
jbe@0 56 }
jbe@0 57 }
jbe@0 58
jbe@0 59 static int seqlua_ipairs(lua_State *L) {
jbe@0 60 if (luaL_getmetafield(L, 1, "__call")) {
jbe@0 61 if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function");
jbe@0 62 lua_replace(L, 1);
jbe@0 63 }
jbe@0 64 if (lua_type(L, 1) == LUA_TFUNCTION) {
jbe@0 65 if (!lua_isnoneornil(L, 2) || !lua_isnoneornil(L, 3)) {
jbe@0 66 lua_settop(L, 3);
jbe@0 67 lua_pushinteger(L, 0);
jbe@0 68 lua_pushcclosure(L, seqlua_ipairsaux_funcclosure, 4);
jbe@0 69 return 1;
jbe@0 70 }
jbe@0 71 lua_pushcfunction(L, seqlua_ipairsaux_func);
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@0 83 static int seqlua_iteratoraux(lua_State *L) {
jbe@0 84 lua_settop(L, 0);
jbe@0 85 lua_pushvalue(L, lua_upvalueindex(1));
jbe@0 86 lua_pushvalue(L, lua_upvalueindex(2));
jbe@0 87 lua_pushvalue(L, lua_upvalueindex(3));
jbe@0 88 lua_call(L, 2, LUA_MULTRET);
jbe@0 89 if (lua_isnoneornil(L, 1)) {
jbe@0 90 lua_settop(L, 1);
jbe@0 91 return 1;
jbe@0 92 }
jbe@0 93 lua_pushvalue(L, 1);
jbe@0 94 lua_replace(L, lua_upvalueindex(3));
jbe@0 95 return lua_gettop(L);
jbe@0 96 }
jbe@0 97
jbe@0 98 static int seqlua_iterator(lua_State *L) {
jbe@0 99 if (luaL_getmetafield(L, 1, "__call")) {
jbe@0 100 if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function");
jbe@0 101 lua_replace(L, 1);
jbe@0 102 }
jbe@0 103 if (lua_type(L, 1) == LUA_TFUNCTION) {
jbe@0 104 if (lua_isnoneornil(L, 2) && lua_isnoneornil(L, 3)) {
jbe@0 105 lua_settop(L, 1);
jbe@0 106 } else {
jbe@0 107 lua_settop(L, 3);
jbe@0 108 lua_pushcclosure(L, seqlua_iteratoraux, 3);
jbe@0 109 }
jbe@0 110 } else {
jbe@0 111 seqlua_iterclosure(L, 1);
jbe@0 112 lua_settop(L, 1);
jbe@0 113 }
jbe@0 114 return 1;
jbe@0 115 }
jbe@0 116
jbe@0 117 int luaopen_seqlua(lua_State *L) {
jbe@0 118 lua_pushcfunction(L, seqlua_ipairs);
jbe@0 119 lua_setglobal(L, "ipairs");
jbe@0 120 lua_pushcfunction(L, seqlua_iterator);
jbe@0 121 lua_setglobal(L, "iterator");
jbe@0 122 return 1;
jbe@0 123 }

Impressum / About Us