mirror of https://github.com/rusefi/lua.git
metamethods for 'removekey'/'keyin'
This commit is contained in:
parent
ef8263f81f
commit
b7edf5d2d8
19
lapi.c
19
lapi.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lapi.c,v 2.287 2018/02/25 12:48:16 roberto Exp roberto $
|
||||
** $Id: lapi.c,v 2.288 2018/02/26 14:16:05 roberto Exp roberto $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -679,6 +679,7 @@ LUA_API int lua_rawget (lua_State *L, int idx) {
|
|||
Table *t;
|
||||
const TValue *val;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
t = gettable(L, idx);
|
||||
val = luaH_get(t, s2v(L->top - 1));
|
||||
L->top--; /* remove key */
|
||||
|
@ -704,29 +705,24 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
|
|||
}
|
||||
|
||||
|
||||
static int auxkeyman (lua_State *L, int idx, int remove) {
|
||||
Table *t;
|
||||
const TValue *val;
|
||||
static int auxkeydef (lua_State *L, int idx, int remove) {
|
||||
int res;
|
||||
lua_lock(L);
|
||||
t = gettable(L, idx);
|
||||
val = luaH_get(t, s2v(L->top - 1));
|
||||
api_checknelems(L, 1);
|
||||
res = luaT_keydef(L, index2value(L, idx), s2v(L->top - 1), remove);
|
||||
L->top--; /* remove key */
|
||||
res = !isempty(val);
|
||||
if (remove && res) /* key is present and should be removed? */
|
||||
setempty(cast(TValue*, val));
|
||||
lua_unlock(L);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_removekey (lua_State *L, int idx) {
|
||||
auxkeyman(L, idx, 1);
|
||||
auxkeydef(L, idx, 1);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_keyin (lua_State *L, int idx) {
|
||||
return auxkeyman(L, idx, 0);
|
||||
return auxkeydef(L, idx, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1223,6 +1219,7 @@ LUA_API int lua_next (lua_State *L, int idx) {
|
|||
Table *t;
|
||||
int more;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
t = gettable(L, idx);
|
||||
more = luaH_next(L, t, L->top - 1);
|
||||
if (more) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lbaselib.c,v 1.319 2018/02/05 17:10:52 roberto Exp roberto $
|
||||
** $Id: lbaselib.c,v 1.320 2018/02/25 12:48:16 roberto Exp roberto $
|
||||
** Basic library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -171,8 +171,7 @@ static int luaB_rawset (lua_State *L) {
|
|||
|
||||
|
||||
static int luaB_keyin (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
luaL_checkany(L, 2);
|
||||
luaL_checkany(L, 2); /* ensures a first argument too */
|
||||
lua_settop(L, 2);
|
||||
lua_pushboolean(L, lua_keyin(L, 1));
|
||||
return 1;
|
||||
|
@ -180,8 +179,7 @@ static int luaB_keyin (lua_State *L) {
|
|||
|
||||
|
||||
static int luaB_removekey (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
luaL_checkany(L, 2);
|
||||
luaL_checkany(L, 2); /* ensures a first argument too */
|
||||
lua_settop(L, 2);
|
||||
lua_removekey(L, 1);
|
||||
return 0;
|
||||
|
|
31
ltm.c
31
ltm.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltm.c,v 2.64 2018/02/23 13:13:31 roberto Exp roberto $
|
||||
** $Id: ltm.c,v 2.65 2018/02/26 14:16:05 roberto Exp roberto $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -38,6 +38,7 @@ LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
|
|||
void luaT_init (lua_State *L) {
|
||||
static const char *const luaT_eventname[] = { /* ORDER TM */
|
||||
"__index", "__newindex",
|
||||
"__undef", "__isdef",
|
||||
"__gc", "__mode", "__len", "__eq",
|
||||
"__add", "__sub", "__mul", "__mod", "__pow",
|
||||
"__div", "__idiv",
|
||||
|
@ -248,3 +249,31 @@ void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) {
|
|||
for (; i < wanted; i++) /* complete required results with nil */
|
||||
setnilvalue(s2v(where + i));
|
||||
}
|
||||
|
||||
|
||||
int luaT_keydef (lua_State *L, TValue *obj, TValue *key, int remove) {
|
||||
const TValue *tm;
|
||||
TMS event = remove ? TM_UNDEF : TM_ISDEF;
|
||||
if (!ttistable(obj)) { /* not a table? */
|
||||
tm = luaT_gettmbyobj(L, obj, event); /* get its metamethod */
|
||||
if (notm(tm)) { /* no metamethod? */
|
||||
const char *msg = remove ? "remove key from" : "check key from";
|
||||
luaG_typeerror(L, obj, msg); /* error */
|
||||
}
|
||||
/* else will call metamethod 'tm' */
|
||||
}
|
||||
else { /* 'obj' is a table */
|
||||
Table *t = hvalue(obj);
|
||||
tm = fasttm(L, t->metatable, event);
|
||||
if (tm == NULL) { /* no metamethod? */
|
||||
const TValue *val = luaH_get(t, key); /* get entry */
|
||||
int res = !isempty(val); /* true if entry is not empty */
|
||||
if (remove && res) /* key is present and should be removed? */
|
||||
setempty(cast(TValue*, val)); /* remove it */
|
||||
return res;
|
||||
}
|
||||
/* else will call metamethod 'tm' */
|
||||
}
|
||||
luaT_callTMres(L, tm, obj, key, L->top);
|
||||
return !l_isfalse(s2v(L->top));
|
||||
}
|
||||
|
|
6
ltm.h
6
ltm.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltm.h,v 2.32 2018/02/17 19:20:00 roberto Exp roberto $
|
||||
** $Id: ltm.h,v 2.33 2018/02/23 13:13:31 roberto Exp roberto $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -19,6 +19,8 @@
|
|||
typedef enum {
|
||||
TM_INDEX,
|
||||
TM_NEWINDEX,
|
||||
TM_UNDEF,
|
||||
TM_ISDEF,
|
||||
TM_GC,
|
||||
TM_MODE,
|
||||
TM_LEN,
|
||||
|
@ -89,5 +91,7 @@ LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams,
|
|||
LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci,
|
||||
StkId where, int wanted);
|
||||
|
||||
LUAI_FUNC int luaT_keydef (lua_State *L, TValue *obj, TValue *key, int remove);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue