diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-01-27 11:46:16 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-01-27 11:46:16 -0200 |
| commit | 41ed3c47719b29dd02dc9fcf07f79dc6f2c4381d (patch) | |
| tree | 0481135889c06eded52f6573f203742ab64186c1 | |
| parent | 635b7c707d146ab56127260601b6fb84c0c140f3 (diff) | |
| download | lua-41ed3c47719b29dd02dc9fcf07f79dc6f2c4381d.tar.gz lua-41ed3c47719b29dd02dc9fcf07f79dc6f2c4381d.tar.bz2 lua-41ed3c47719b29dd02dc9fcf07f79dc6f2c4381d.zip | |
getn/setn in C moved to lauxlib
Diffstat (limited to '')
| -rw-r--r-- | lauxlib.c | 85 | ||||
| -rw-r--r-- | lauxlib.h | 5 | ||||
| -rw-r--r-- | ltablib.c | 65 |
3 files changed, 94 insertions, 61 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.91 2002/12/04 17:38:31 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.92 2003/01/23 11:34:18 roberto Exp roberto $ |
| 3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,6 +23,13 @@ | |||
| 23 | #include "lauxlib.h" | 23 | #include "lauxlib.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | /* number of prereserved references (for internal use) */ | ||
| 27 | #define RESERVED_REFS 1 | ||
| 28 | |||
| 29 | /* reserved reference for array sizes */ | ||
| 30 | #define ARRAYSIZE_REF 1 | ||
| 31 | |||
| 32 | |||
| 26 | /* | 33 | /* |
| 27 | ** {====================================================== | 34 | ** {====================================================== |
| 28 | ** Error-report functions | 35 | ** Error-report functions |
| @@ -197,6 +204,78 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, | |||
| 197 | 204 | ||
| 198 | /* | 205 | /* |
| 199 | ** {====================================================== | 206 | ** {====================================================== |
| 207 | ** getn-setn: size for arrays | ||
| 208 | ** ======================================================= | ||
| 209 | */ | ||
| 210 | |||
| 211 | static int checkint (lua_State *L, int topop) { | ||
| 212 | int n = (int)lua_tonumber(L, -1); | ||
| 213 | if (n == 0 && !lua_isnumber(L, -1)) n = -1; | ||
| 214 | lua_pop(L, topop); | ||
| 215 | return n; | ||
| 216 | } | ||
| 217 | |||
| 218 | |||
| 219 | static void getsizes (lua_State *L) { | ||
| 220 | lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); | ||
| 221 | if (lua_isnil(L, -1)) { /* no `size' table? */ | ||
| 222 | lua_newtable(L); /* create it */ | ||
| 223 | lua_pushvalue(L, -1); /* `size' will be its own metatable */ | ||
| 224 | lua_setmetatable(L, -2); | ||
| 225 | lua_pushliteral(L, "__mode"); | ||
| 226 | lua_pushliteral(L, "k"); | ||
| 227 | lua_rawset(L, -3); /* metatable(N).__mode = "k" */ | ||
| 228 | lua_pushvalue(L, -1); | ||
| 229 | lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */ | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | |||
| 234 | void luaL_setn (lua_State *L, int t, int n) { | ||
| 235 | lua_pushliteral(L, "n"); | ||
| 236 | lua_rawget(L, t); | ||
| 237 | if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ | ||
| 238 | lua_pushliteral(L, "n"); /* use it */ | ||
| 239 | lua_pushnumber(L, n); | ||
| 240 | lua_rawset(L, t); | ||
| 241 | } | ||
| 242 | else { /* use `sizes' */ | ||
| 243 | getsizes(L); | ||
| 244 | lua_pushvalue(L, t); | ||
| 245 | lua_pushnumber(L, n); | ||
| 246 | lua_rawset(L, -3); /* sizes[t] = n */ | ||
| 247 | lua_pop(L, 1); /* remove `sizes' */ | ||
| 248 | } | ||
| 249 | } | ||
| 250 | |||
| 251 | |||
| 252 | int luaL_getn (lua_State *L, int t) { | ||
| 253 | int n; | ||
| 254 | lua_pushliteral(L, "n"); /* try t.n */ | ||
| 255 | lua_rawget(L, t); | ||
| 256 | if ((n = checkint(L, 1)) >= 0) return n; | ||
| 257 | getsizes(L); /* else try sizes[t] */ | ||
| 258 | lua_pushvalue(L, t); | ||
| 259 | lua_rawget(L, -2); | ||
| 260 | if ((n = checkint(L, 2)) >= 0) return n; | ||
| 261 | else { /* must count elements */ | ||
| 262 | for (n = 1; ; n++) { | ||
| 263 | lua_rawgeti(L, t, n); | ||
| 264 | if (lua_isnil(L, -1)) break; | ||
| 265 | lua_pop(L, 1); | ||
| 266 | } | ||
| 267 | lua_pop(L, 1); | ||
| 268 | luaL_setn(L, t, n - 1); | ||
| 269 | return n - 1; | ||
| 270 | } | ||
| 271 | } | ||
| 272 | |||
| 273 | /* }====================================================== */ | ||
| 274 | |||
| 275 | |||
| 276 | |||
| 277 | /* | ||
| 278 | ** {====================================================== | ||
| 200 | ** Generic Buffer manipulation | 279 | ** Generic Buffer manipulation |
| 201 | ** ======================================================= | 280 | ** ======================================================= |
| 202 | */ | 281 | */ |
| @@ -308,8 +387,10 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { | |||
| 308 | lua_pushliteral(L, "n"); | 387 | lua_pushliteral(L, "n"); |
| 309 | lua_pushvalue(L, -1); | 388 | lua_pushvalue(L, -1); |
| 310 | lua_rawget(L, t); /* get t.n */ | 389 | lua_rawget(L, t); /* get t.n */ |
| 311 | ref = (int)lua_tonumber(L, -1) + 1; /* ref = t.n + 1 */ | 390 | ref = (int)lua_tonumber(L, -1); /* ref = t.n */ |
| 312 | lua_pop(L, 1); /* pop t.n */ | 391 | lua_pop(L, 1); /* pop t.n */ |
| 392 | if (ref == 0) ref = RESERVED_REFS; /* skip reserved references */ | ||
| 393 | ref++; /* create new reference */ | ||
| 313 | lua_pushnumber(L, ref); | 394 | lua_pushnumber(L, ref); |
| 314 | lua_rawset(L, t); /* t.n = t.n + 1 */ | 395 | lua_rawset(L, t); /* t.n = t.n + 1 */ |
| 315 | } | 396 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.h,v 1.55 2002/11/14 15:41:38 roberto Exp roberto $ | 2 | ** $Id: lauxlib.h,v 1.56 2003/01/17 15:28:09 roberto Exp roberto $ |
| 3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -51,6 +51,9 @@ LUALIB_API int luaL_findstring (const char *st, const char *const lst[]); | |||
| 51 | LUALIB_API int luaL_ref (lua_State *L, int t); | 51 | LUALIB_API int luaL_ref (lua_State *L, int t); |
| 52 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref); | 52 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref); |
| 53 | 53 | ||
| 54 | LUALIB_API int luaL_getn (lua_State *L, int t); | ||
| 55 | LUALIB_API void luaL_setn (lua_State *L, int t, int n); | ||
| 56 | |||
| 54 | LUALIB_API int luaL_loadfile (lua_State *L, const char *filename); | 57 | LUALIB_API int luaL_loadfile (lua_State *L, const char *filename); |
| 55 | LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz, | 58 | LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz, |
| 56 | const char *name); | 59 | const char *name); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltablib.c,v 1.17 2002/12/04 17:38:31 roberto Exp roberto $ | 2 | ** $Id: ltablib.c,v 1.18 2002/12/20 10:26:33 roberto Exp roberto $ |
| 3 | ** Library for Table Manipulation | 3 | ** Library for Table Manipulation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -15,52 +15,7 @@ | |||
| 15 | #include "lualib.h" | 15 | #include "lualib.h" |
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) | |
| 19 | static int checkint (lua_State *L) { | ||
| 20 | int n = (int)lua_tonumber(L, -1); | ||
| 21 | if (n == 0 && !lua_isnumber(L, -1)) n = -1; | ||
| 22 | lua_pop(L, 1); | ||
| 23 | return n; | ||
| 24 | } | ||
| 25 | |||
| 26 | |||
| 27 | static void aux_setn (lua_State *L, int t, int n) { | ||
| 28 | lua_pushliteral(L, "n"); | ||
| 29 | lua_rawget(L, t); | ||
| 30 | if (checkint(L) >= 0) { | ||
| 31 | lua_pushliteral(L, "n"); /* use it */ | ||
| 32 | lua_pushnumber(L, n); | ||
| 33 | lua_rawset(L, t); | ||
| 34 | } | ||
| 35 | else { /* use N */ | ||
| 36 | lua_pushvalue(L, t); | ||
| 37 | lua_pushnumber(L, n); | ||
| 38 | lua_rawset(L, lua_upvalueindex(1)); /* N[t] = n */ | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | |||
| 43 | static int aux_getn (lua_State *L, int t) { | ||
| 44 | int n; | ||
| 45 | luaL_checktype(L, t, LUA_TTABLE); | ||
| 46 | lua_pushliteral(L, "n"); /* try t.n */ | ||
| 47 | lua_rawget(L, t); | ||
| 48 | if ((n = checkint(L)) >= 0) return n; | ||
| 49 | lua_pushvalue(L, t); /* try N[t] */ | ||
| 50 | lua_rawget(L, lua_upvalueindex(1)); | ||
| 51 | if ((n = checkint(L)) >= 0) return n; | ||
| 52 | else { /* must count elements */ | ||
| 53 | n = 0; | ||
| 54 | for (;;) { | ||
| 55 | lua_rawgeti(L, t, ++n); | ||
| 56 | if (lua_isnil(L, -1)) break; | ||
| 57 | lua_pop(L, 1); | ||
| 58 | } | ||
| 59 | lua_pop(L, 1); | ||
| 60 | aux_setn(L, t, n - 1); | ||
| 61 | return n - 1; | ||
| 62 | } | ||
| 63 | } | ||
| 64 | 19 | ||
| 65 | 20 | ||
| 66 | static int luaB_foreachi (lua_State *L) { | 21 | static int luaB_foreachi (lua_State *L) { |
| @@ -106,7 +61,7 @@ static int luaB_getn (lua_State *L) { | |||
| 106 | 61 | ||
| 107 | static int luaB_setn (lua_State *L) { | 62 | static int luaB_setn (lua_State *L) { |
| 108 | luaL_checktype(L, 1, LUA_TTABLE); | 63 | luaL_checktype(L, 1, LUA_TTABLE); |
| 109 | aux_setn(L, 1, luaL_checkint(L, 2)); | 64 | luaL_setn(L, 1, luaL_checkint(L, 2)); |
| 110 | return 0; | 65 | return 0; |
| 111 | } | 66 | } |
| 112 | 67 | ||
| @@ -122,7 +77,7 @@ static int luaB_tinsert (lua_State *L) { | |||
| 122 | if (pos > n) n = pos; /* `grow' array if necessary */ | 77 | if (pos > n) n = pos; /* `grow' array if necessary */ |
| 123 | v = 3; /* function may be called with more than 3 args */ | 78 | v = 3; /* function may be called with more than 3 args */ |
| 124 | } | 79 | } |
| 125 | aux_setn(L, 1, n); /* new size */ | 80 | luaL_setn(L, 1, n); /* new size */ |
| 126 | while (--n >= pos) { /* move up elements */ | 81 | while (--n >= pos) { /* move up elements */ |
| 127 | lua_rawgeti(L, 1, n); | 82 | lua_rawgeti(L, 1, n); |
| 128 | lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ | 83 | lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ |
| @@ -137,7 +92,7 @@ static int luaB_tremove (lua_State *L) { | |||
| 137 | int n = aux_getn(L, 1); | 92 | int n = aux_getn(L, 1); |
| 138 | int pos = luaL_optint(L, 2, n); | 93 | int pos = luaL_optint(L, 2, n); |
| 139 | if (n <= 0) return 0; /* table is `empty' */ | 94 | if (n <= 0) return 0; /* table is `empty' */ |
| 140 | aux_setn(L, 1, n-1); /* t.n = n-1 */ | 95 | luaL_setn(L, 1, n-1); /* t.n = n-1 */ |
| 141 | lua_rawgeti(L, 1, pos); /* result = t[pos] */ | 96 | lua_rawgeti(L, 1, pos); /* result = t[pos] */ |
| 142 | for ( ;pos<n; pos++) { | 97 | for ( ;pos<n; pos++) { |
| 143 | lua_rawgeti(L, 1, pos+1); | 98 | lua_rawgeti(L, 1, pos+1); |
| @@ -156,7 +111,7 @@ static int str_concat (lua_State *L) { | |||
| 156 | int i = luaL_optint(L, 3, 1); | 111 | int i = luaL_optint(L, 3, 1); |
| 157 | int n = luaL_optint(L, 4, 0); | 112 | int n = luaL_optint(L, 4, 0); |
| 158 | luaL_checktype(L, 1, LUA_TTABLE); | 113 | luaL_checktype(L, 1, LUA_TTABLE); |
| 159 | if (n == 0) n = aux_getn(L, 1); | 114 | if (n == 0) n = luaL_getn(L, 1); |
| 160 | luaL_buffinit(L, &b); | 115 | luaL_buffinit(L, &b); |
| 161 | for (; i <= n; i++) { | 116 | for (; i <= n; i++) { |
| 162 | lua_rawgeti(L, 1, i); | 117 | lua_rawgeti(L, 1, i); |
| @@ -289,13 +244,7 @@ static const luaL_reg tab_funcs[] = { | |||
| 289 | 244 | ||
| 290 | 245 | ||
| 291 | LUALIB_API int lua_tablibopen (lua_State *L) { | 246 | LUALIB_API int lua_tablibopen (lua_State *L) { |
| 292 | lua_newtable(L); /* create N (table to store num. elements in tables) */ | 247 | luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0); |
| 293 | lua_pushvalue(L, -1); /* `N' will be its own metatable */ | ||
| 294 | lua_setmetatable(L, -2); | ||
| 295 | lua_pushliteral(L, "__mode"); | ||
| 296 | lua_pushliteral(L, "k"); | ||
| 297 | lua_rawset(L, -3); /* metatable(N).__mode = "k" */ | ||
| 298 | luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 1); | ||
| 299 | return 1; | 248 | return 1; |
| 300 | } | 249 | } |
| 301 | 250 | ||
