seqlua

annotate seqlualib.c @ 53:664736a8fcbf

Included mode argument for seqlua_iterloop in README
author jbe
date Tue Aug 26 23:53:29 2014 +0200 (2014-08-26)
parents 3362ec36cb09
children 92ce3958aca7
rev   line source
jbe@0 1 #include <lua.h>
jbe@0 2 #include <lauxlib.h>
jbe@0 3 #include "seqlualib.h"
jbe@35 4 #include <string.h>
jbe@0 5
jbe@30 6 #define SEQLUA_ITERTYPE_IPAIRS 1
jbe@30 7 #define SEQLUA_ITERTYPE_CALL 2
jbe@30 8 #define SEQLUA_ITERTYPE_INDEX 3
jbe@30 9 #define SEQLUA_ITERTYPE_RAW 4
jbe@0 10
jbe@52 11 void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int mode, int idx) {
jbe@52 12 int generated = 0;
jbe@52 13 seqlua_iterinit_repeat:
jbe@30 14 if (luaL_getmetafield(L, idx, "__ipairs")) {
jbe@52 15 if (!generated) lua_pushvalue(L, idx);
jbe@30 16 lua_call(L, 1, 3);
jbe@35 17 if (lua_type(L, -3) == LUA_TSTRING) {
jbe@35 18 const char *method = lua_tostring(L, -3);
jbe@35 19 if (!strcmp(method, "raw")) {
jbe@35 20 iter->itertype = SEQLUA_ITERTYPE_RAW;
jbe@35 21 } else if (!strcmp(method, "index")) {
jbe@35 22 iter->itertype = SEQLUA_ITERTYPE_INDEX;
jbe@35 23 } else if (!strcmp(method, "call")) {
jbe@35 24 iter->itertype = SEQLUA_ITERTYPE_CALL;
jbe@35 25 } else {
jbe@35 26 luaL_error(L, "Unexpected string returned by __ipairs metamethod");
jbe@35 27 }
jbe@35 28 iter->idx = lua_gettop(L) - 1;
jbe@35 29 } else {
jbe@35 30 iter->itertype = SEQLUA_ITERTYPE_IPAIRS;
jbe@35 31 }
jbe@30 32 } else {
jbe@30 33 if (lua_type(L, idx) == LUA_TFUNCTION) {
jbe@52 34 if (generated || mode == SEQLUA_MODE_CALL) {
jbe@52 35 iter->itertype = SEQLUA_ITERTYPE_CALL;
jbe@52 36 goto seqlua_iterinit_finish;
jbe@52 37 } else if (mode == SEQLUA_MODE_GENERATOR) {
jbe@52 38 lua_pushvalue(L, idx);
jbe@52 39 lua_call(L, 0, 1);
jbe@52 40 idx = lua_gettop(L);
jbe@52 41 goto seqlua_iterinit_repeat;
jbe@52 42 }
jbe@32 43 } else if (luaL_getmetafield(L, idx, "__index")) {
jbe@30 44 lua_pop(L, 1);
jbe@30 45 iter->itertype = SEQLUA_ITERTYPE_INDEX;
jbe@52 46 goto seqlua_iterinit_finish;
jbe@30 47 }
jbe@52 48 luaL_checktype(L, idx, LUA_TTABLE);
jbe@52 49 iter->itertype = SEQLUA_ITERTYPE_RAW;
jbe@52 50 seqlua_iterinit_finish:
jbe@30 51 // always occupy 3 stack indicies
jbe@52 52 if (!generated) lua_pushnil(L);
jbe@30 53 lua_pushnil(L);
jbe@30 54 lua_pushnil(L);
jbe@30 55 iter->idx = idx;
jbe@30 56 }
jbe@0 57 iter->L = L;
jbe@0 58 iter->i = 0;
jbe@0 59 }
jbe@0 60
jbe@0 61 int seqlua_iternext(seqlua_Iterator *iter) {
jbe@0 62 lua_State *L = iter->L;
jbe@0 63 lua_Integer i = ++iter->i;
jbe@0 64 switch (iter->itertype) {
jbe@30 65 case SEQLUA_ITERTYPE_IPAIRS:
jbe@30 66 lua_pushvalue(L, -3);
jbe@30 67 lua_pushvalue(L, -3);
jbe@30 68 lua_pushvalue(L, -3);
jbe@30 69 lua_call(L, 2, 2);
jbe@30 70 if (lua_isnil(L, -2)) {
jbe@30 71 lua_pop(L, 5);
jbe@30 72 return 0;
jbe@30 73 }
jbe@30 74 lua_remove(L, -3);
jbe@30 75 return 1;
jbe@30 76 case SEQLUA_ITERTYPE_CALL:
jbe@8 77 lua_pushvalue(L, iter->idx);
jbe@0 78 lua_call(L, 0, 1);
jbe@0 79 break;
jbe@30 80 case SEQLUA_ITERTYPE_INDEX:
jbe@0 81 lua_pushinteger(L, i);
jbe@8 82 lua_gettable(L, iter->idx);
jbe@32 83 break;
jbe@0 84 case SEQLUA_ITERTYPE_RAW:
jbe@8 85 lua_rawgeti(L, iter->idx, i);
jbe@8 86 break;
jbe@0 87 }
jbe@0 88 if (lua_isnil(L, -1)) {
jbe@30 89 lua_pop(L, 4);
jbe@0 90 return 0;
jbe@0 91 }
jbe@0 92 return 1;
jbe@0 93 }
jbe@0 94

Impressum / About Us