-
Notifications
You must be signed in to change notification settings - Fork 9
/
ex34.c
66 lines (60 loc) · 2.48 KB
/
ex34.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Example 34. Call a function for each table key-value pair
//8<----------------------------------------------------------------------------
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
//8<----------------------------------------------------------------------------
// Thread body continuation function for iterating over
// a table's key-value pairs and calling a function
// with each pair as that function's arguments.
static int iterator(lua_State *thread, int status,
lua_KContext ctx) {
if (status == LUA_OK)
lua_pushnil(thread); // start iteration
else
lua_pop(thread, 1); // previous value
while (lua_next(thread, 1) != 0) {
lua_pushvalue(thread, lua_upvalueindex(1));
lua_pushvalue(thread, -3); // key
lua_pushvalue(thread, -3); // value
lua_callk(thread, 2, 0, 0, iterator);
lua_pop(thread, 1); // value
}
return 0;
}
// Initial thread body function.
static int iterate(lua_State *thread) {
return iterator(thread, LUA_OK, 0);
}
//8<----------------------------------------------------------------------------
int main(int argc, char **argv) {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
//8<----------------------------------------------------------------------------
lua_State *thread = lua_newthread(L);
/* push function to be called each iteration */
//8<--------------------------------------------------------------------------
lua_getglobal(thread, "coroutine");
lua_getfield(thread, -1, "yield");
lua_replace(thread, -2);
//8<--------------------------------------------------------------------------
lua_pushcclosure(thread, iterate, 1);
/* push table to be iterated over */
//8<--------------------------------------------------------------------------
lua_pushglobaltable(thread);
//8<--------------------------------------------------------------------------
int nresults;
while (lua_resume(thread, L, 1, &nresults) == LUA_YIELD) {
/* work to do in-between yields */
//8<--------------------------------------------------------------------------
printf("%s\t%s\n", lua_tostring(thread, -2), luaL_typename(thread, -1));
//8<--------------------------------------------------------------------------
lua_pop(thread, nresults);
}
lua_pop(L, 1); // dead thread
//8<----------------------------------------------------------------------------
if (lua_gettop(L) > 0) printf("stack size != 0\n");
lua_close(L);
return 0;
}
//8<----------------------------------------------------------------------------