1
4
5# include "luametatex.h"
6
7static int tablib_keys(lua_State *L)
8{
9 int category = 0;
10 lua_settop(L, 1);
11 lua_createtable(L, 0, 0);
12 if (lua_type(L, 1) == LUA_TTABLE) {
13 int index = 0;
14 lua_pushnil(L);
15 while (lua_next(L, -3)) {
16 int tkey = lua_type(L, -2);
17 if (category != 3) {
18 if (category == 1) {
19 if (tkey != LUA_TSTRING) {
20 category = 3;
21 }
22 } else if (category == 2) {
23 if (tkey != LUA_TNUMBER) {
24 category = 3;
25 }
26 } else {
27 if (tkey == LUA_TSTRING) {
28 category = 1;
29 } else if (tkey == LUA_TNUMBER) {
30 category = 2;
31 } else {
32 category = 3;
33 }
34 }
35 }
36 lua_pushvalue(L, -2);
37 lua_rawseti(L, 2, ++index);
38 lua_pop(L, 1);
39 }
40 }
41 lua_pushinteger(L, category);
42 return 2;
43}
44
45
64
65static int tablib_binsearch(lua_State *L)
66{
67 if (lua_type(L, 1) == LUA_TTABLE) {
68 lua_Integer val = lua_tointeger(L, 2);
69 lua_Unsigned min = 1;
70 lua_Unsigned max = lua_rawlen(L, 1);
71 while (min <= max) {
72 lua_Unsigned mid = min + (max - min) / 2;
73 if (lua_rawgeti(L, 1, mid) == LUA_TNUMBER) {
74 lua_Integer tmp = lua_tointeger(L, -1);
75 lua_pop(L, 1);
76 if (tmp == val) {
77 lua_pushinteger(L, mid);
78 return 1;
79 } else if (tmp < val) {
80 min = mid + 1;
81 } else {
82 max = mid - 1;
83 }
84 }
85 }
86 }
87 lua_pushnil(L);
88 return 1;
89}
90
91static const luaL_Reg tablib_function_list[] = {
92 { "getkeys", tablib_keys },
93 { "binsearch", tablib_binsearch },
94 { NULL, NULL },
95};
96
97int luaextend_table(lua_State * L)
98{
99 lua_getglobal(L, "table");
100 for (const luaL_Reg *lib = tablib_function_list; lib->name; lib++) {
101 lua_pushcfunction(L, lib->func);
102 lua_setfield(L, -2, lib->name);
103 }
104 lua_pop(L, 1);
105 return 1;
106}
107 |