diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-27 14:48:28 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-27 14:48:28 -0300 |
| commit | b7edf5d2d89ed2ce1e9087de496bcb451e39d131 (patch) | |
| tree | 88d94c159ee2034fffd9195a60e306c9565bf361 | |
| parent | ef8263f81fdde2310ebb15c9a3fe5e954d57cab5 (diff) | |
| download | lua-b7edf5d2d89ed2ce1e9087de496bcb451e39d131.tar.gz lua-b7edf5d2d89ed2ce1e9087de496bcb451e39d131.tar.bz2 lua-b7edf5d2d89ed2ce1e9087de496bcb451e39d131.zip | |
metamethods for 'removekey'/'keyin'
| -rw-r--r-- | lapi.c | 19 | ||||
| -rw-r--r-- | lbaselib.c | 8 | ||||
| -rw-r--r-- | ltm.c | 31 | ||||
| -rw-r--r-- | ltm.h | 6 |
4 files changed, 46 insertions, 18 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 2.287 2018/02/25 12:48:16 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.288 2018/02/26 14:16:05 roberto Exp roberto $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -679,6 +679,7 @@ LUA_API int lua_rawget (lua_State *L, int idx) { | |||
| 679 | Table *t; | 679 | Table *t; |
| 680 | const TValue *val; | 680 | const TValue *val; |
| 681 | lua_lock(L); | 681 | lua_lock(L); |
| 682 | api_checknelems(L, 1); | ||
| 682 | t = gettable(L, idx); | 683 | t = gettable(L, idx); |
| 683 | val = luaH_get(t, s2v(L->top - 1)); | 684 | val = luaH_get(t, s2v(L->top - 1)); |
| 684 | L->top--; /* remove key */ | 685 | L->top--; /* remove key */ |
| @@ -704,29 +705,24 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { | |||
| 704 | } | 705 | } |
| 705 | 706 | ||
| 706 | 707 | ||
| 707 | static int auxkeyman (lua_State *L, int idx, int remove) { | 708 | static int auxkeydef (lua_State *L, int idx, int remove) { |
| 708 | Table *t; | ||
| 709 | const TValue *val; | ||
| 710 | int res; | 709 | int res; |
| 711 | lua_lock(L); | 710 | lua_lock(L); |
| 712 | t = gettable(L, idx); | 711 | api_checknelems(L, 1); |
| 713 | val = luaH_get(t, s2v(L->top - 1)); | 712 | res = luaT_keydef(L, index2value(L, idx), s2v(L->top - 1), remove); |
| 714 | L->top--; /* remove key */ | 713 | L->top--; /* remove key */ |
| 715 | res = !isempty(val); | ||
| 716 | if (remove && res) /* key is present and should be removed? */ | ||
| 717 | setempty(cast(TValue*, val)); | ||
| 718 | lua_unlock(L); | 714 | lua_unlock(L); |
| 719 | return res; | 715 | return res; |
| 720 | } | 716 | } |
| 721 | 717 | ||
| 722 | 718 | ||
| 723 | LUA_API void lua_removekey (lua_State *L, int idx) { | 719 | LUA_API void lua_removekey (lua_State *L, int idx) { |
| 724 | auxkeyman(L, idx, 1); | 720 | auxkeydef(L, idx, 1); |
| 725 | } | 721 | } |
| 726 | 722 | ||
| 727 | 723 | ||
| 728 | LUA_API int lua_keyin (lua_State *L, int idx) { | 724 | LUA_API int lua_keyin (lua_State *L, int idx) { |
| 729 | return auxkeyman(L, idx, 0); | 725 | return auxkeydef(L, idx, 0); |
| 730 | } | 726 | } |
| 731 | 727 | ||
| 732 | 728 | ||
| @@ -1223,6 +1219,7 @@ LUA_API int lua_next (lua_State *L, int idx) { | |||
| 1223 | Table *t; | 1219 | Table *t; |
| 1224 | int more; | 1220 | int more; |
| 1225 | lua_lock(L); | 1221 | lua_lock(L); |
| 1222 | api_checknelems(L, 1); | ||
| 1226 | t = gettable(L, idx); | 1223 | t = gettable(L, idx); |
| 1227 | more = luaH_next(L, t, L->top - 1); | 1224 | more = luaH_next(L, t, L->top - 1); |
| 1228 | if (more) { | 1225 | if (more) { |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.319 2018/02/05 17:10:52 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.320 2018/02/25 12:48:16 roberto Exp roberto $ |
| 3 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -171,8 +171,7 @@ static int luaB_rawset (lua_State *L) { | |||
| 171 | 171 | ||
| 172 | 172 | ||
| 173 | static int luaB_keyin (lua_State *L) { | 173 | static int luaB_keyin (lua_State *L) { |
| 174 | luaL_checktype(L, 1, LUA_TTABLE); | 174 | luaL_checkany(L, 2); /* ensures a first argument too */ |
| 175 | luaL_checkany(L, 2); | ||
| 176 | lua_settop(L, 2); | 175 | lua_settop(L, 2); |
| 177 | lua_pushboolean(L, lua_keyin(L, 1)); | 176 | lua_pushboolean(L, lua_keyin(L, 1)); |
| 178 | return 1; | 177 | return 1; |
| @@ -180,8 +179,7 @@ static int luaB_keyin (lua_State *L) { | |||
| 180 | 179 | ||
| 181 | 180 | ||
| 182 | static int luaB_removekey (lua_State *L) { | 181 | static int luaB_removekey (lua_State *L) { |
| 183 | luaL_checktype(L, 1, LUA_TTABLE); | 182 | luaL_checkany(L, 2); /* ensures a first argument too */ |
| 184 | luaL_checkany(L, 2); | ||
| 185 | lua_settop(L, 2); | 183 | lua_settop(L, 2); |
| 186 | lua_removekey(L, 1); | 184 | lua_removekey(L, 1); |
| 187 | return 0; | 185 | return 0; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 2.64 2018/02/23 13:13:31 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 2.65 2018/02/26 14:16:05 roberto Exp roberto $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -38,6 +38,7 @@ LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { | |||
| 38 | void luaT_init (lua_State *L) { | 38 | void luaT_init (lua_State *L) { |
| 39 | static const char *const luaT_eventname[] = { /* ORDER TM */ | 39 | static const char *const luaT_eventname[] = { /* ORDER TM */ |
| 40 | "__index", "__newindex", | 40 | "__index", "__newindex", |
| 41 | "__undef", "__isdef", | ||
| 41 | "__gc", "__mode", "__len", "__eq", | 42 | "__gc", "__mode", "__len", "__eq", |
| 42 | "__add", "__sub", "__mul", "__mod", "__pow", | 43 | "__add", "__sub", "__mul", "__mod", "__pow", |
| 43 | "__div", "__idiv", | 44 | "__div", "__idiv", |
| @@ -248,3 +249,31 @@ void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { | |||
| 248 | for (; i < wanted; i++) /* complete required results with nil */ | 249 | for (; i < wanted; i++) /* complete required results with nil */ |
| 249 | setnilvalue(s2v(where + i)); | 250 | setnilvalue(s2v(where + i)); |
| 250 | } | 251 | } |
| 252 | |||
| 253 | |||
| 254 | int luaT_keydef (lua_State *L, TValue *obj, TValue *key, int remove) { | ||
| 255 | const TValue *tm; | ||
| 256 | TMS event = remove ? TM_UNDEF : TM_ISDEF; | ||
| 257 | if (!ttistable(obj)) { /* not a table? */ | ||
| 258 | tm = luaT_gettmbyobj(L, obj, event); /* get its metamethod */ | ||
| 259 | if (notm(tm)) { /* no metamethod? */ | ||
| 260 | const char *msg = remove ? "remove key from" : "check key from"; | ||
| 261 | luaG_typeerror(L, obj, msg); /* error */ | ||
| 262 | } | ||
| 263 | /* else will call metamethod 'tm' */ | ||
| 264 | } | ||
| 265 | else { /* 'obj' is a table */ | ||
| 266 | Table *t = hvalue(obj); | ||
| 267 | tm = fasttm(L, t->metatable, event); | ||
| 268 | if (tm == NULL) { /* no metamethod? */ | ||
| 269 | const TValue *val = luaH_get(t, key); /* get entry */ | ||
| 270 | int res = !isempty(val); /* true if entry is not empty */ | ||
| 271 | if (remove && res) /* key is present and should be removed? */ | ||
| 272 | setempty(cast(TValue*, val)); /* remove it */ | ||
| 273 | return res; | ||
| 274 | } | ||
| 275 | /* else will call metamethod 'tm' */ | ||
| 276 | } | ||
| 277 | luaT_callTMres(L, tm, obj, key, L->top); | ||
| 278 | return !l_isfalse(s2v(L->top)); | ||
| 279 | } | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.h,v 2.32 2018/02/17 19:20:00 roberto Exp roberto $ | 2 | ** $Id: ltm.h,v 2.33 2018/02/23 13:13:31 roberto Exp roberto $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -19,6 +19,8 @@ | |||
| 19 | typedef enum { | 19 | typedef enum { |
| 20 | TM_INDEX, | 20 | TM_INDEX, |
| 21 | TM_NEWINDEX, | 21 | TM_NEWINDEX, |
| 22 | TM_UNDEF, | ||
| 23 | TM_ISDEF, | ||
| 22 | TM_GC, | 24 | TM_GC, |
| 23 | TM_MODE, | 25 | TM_MODE, |
| 24 | TM_LEN, | 26 | TM_LEN, |
| @@ -89,5 +91,7 @@ LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, | |||
| 89 | LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, | 91 | LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, |
| 90 | StkId where, int wanted); | 92 | StkId where, int wanted); |
| 91 | 93 | ||
| 94 | LUAI_FUNC int luaT_keydef (lua_State *L, TValue *obj, TValue *key, int remove); | ||
| 95 | |||
| 92 | 96 | ||
| 93 | #endif | 97 | #endif |
