static int sort(lua_State *L) { int n = aux_getn(L, 1); luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ luaL_checktype(L, 2, LUA_TFUNCTION); lua_settop(L, 2); /* make sure there is two arguments */ auxsort(L, 1, n); return 0; }
static int sort (lua_State *L) { lua_Integer n = aux_getn(L, 1, TAB_RW); if (n > 1) { /* non-trivial interval? */ luaL_argcheck(L, n < INT_MAX, 1, "array too big"); luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ lua_settop(L, 2); /* make sure there are two arguments */ auxsort(L, 1, (unsigned int)n, 0u); } return 0; }
NAMESPACE_LUA_BEGIN #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) static int foreachi (lua_State *L) { #if LUA_EXT_RESUMABLEVM int n; int i = lua_icontext(L); if (i) { n = lua_tointeger(L, 3); /* get cached n */ goto resume; } n = aux_getn(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); lua_settop(L, 2); lua_pushinteger(L, n); /* cache n because aux_getn may be expensive */ #else int i; int n = aux_getn(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); #endif /* LUA_EXT_RESUMABLEVM */ for (i=1; i <= n; i++) { lua_pushvalue(L, 2); /* function */ lua_pushinteger(L, i); /* 1st argument */ lua_rawgeti(L, 1, i); /* 2nd argument */ #if LUA_EXT_RESUMABLEVM lua_icall(L, 2, 1, i); resume: #else lua_call(L, 2, 1); #endif /* LUA_EXT_RESUMABLEVM */ if (!lua_isnil(L, -1)) return 1; lua_pop(L, 1); /* remove nil result */ } return 0; }
LUACLLIB_API void luaC_sortlist(lua_State* L, int tabix, int funcix /*=0*/) { luaL_checkstack(L, 41, ""); luaL_checktype(L, tabix, LUA_TTABLE); int t = lua_gettop(L); int ix = tabix; if (ix < 0) ix = t + (ix + 1); if (funcix == 0) lua_pushnil(L); else lua_pushvalue(L, funcix); int n = aux_getn(L, ix); auxsort(L, 1, n, ix, t + 1); lua_settop(L, t); }
static int tremove (lua_State *L) { lua_Integer size = aux_getn(L, 1, TAB_RW); lua_Integer pos = luaL_optinteger(L, 2, size); if (pos != size) /* validate 'pos' if given */ luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); lua_geti(L, 1, pos); /* result = t[pos] */ for ( ; pos < size; pos++) { lua_geti(L, 1, pos + 1); lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ } lua_pushnil(L); lua_seti(L, 1, pos); /* remove entry t[pos] */ return 1; }
static int tremove (lua_State *L) { int e = aux_getn(L, 1); int pos = luaL_optint(L, 2, e); if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ return 0; /* nothing to remove */ lua_rawgeti(L, 1, pos); /* result = t[pos] */ for ( ;pos<e; pos++) { lua_rawgeti(L, 1, pos+1); lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ } lua_pushnil(L); lua_rawseti(L, 1, e); /* t[e] = nil */ return 1; }
static int luaB_tremove (lua_State *L) { int n = aux_getn(L, 1); int pos = luaL_optint(L, 2, n); if (n <= 0) return 0; /* table is `empty' */ luaL_setn(L, 1, n-1); /* t.n = n-1 */ lua_rawgeti(L, 1, pos); /* result = t[pos] */ for ( ;pos<n; pos++) { lua_rawgeti(L, 1, pos+1); lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ } lua_pushnil(L); lua_rawseti(L, 1, n); /* t[n] = nil */ return 1; }
static int unpack (lua_State *L) { lua_Unsigned n; lua_Integer i = luaL_optinteger(L, 2, 1); lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, aux_getn(L, 1, TAB_R)); if (i > e) return 0; /* empty range */ n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) return luaL_error(L, "too many results to unpack"); for (; i < e; i++) { /* push arg[i..e - 1] (to avoid overflows) */ lua_geti(L, 1, i); } lua_geti(L, 1, e); /* push last element */ return (int)n; }
static int tremove (lua_State *L) { int e = aux_getn(L, 1); int pos = luaL_optint(L, 2, e); if (e == 0) return 0; /* table is `empty' */ luaL_setn(L, 1, e - 1); /* t.n = n-1 */ lua_rawgeti(L, 1, pos); /* result = t[pos] */ for ( ;pos<e; pos++) { lua_rawgeti(L, 1, pos+1); lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ } lua_pushnil(L); lua_rawseti(L, 1, e); /* t[e] = nil */ return 1; }
static int foreachi (lua_State *L) { int i; int n = aux_getn(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); for (i=1; i <= n; i++) { lua_pushvalue(L, 2); /* function */ lua_pushinteger(L, i); /* 1st argument */ lua_rawgeti(L, 1, i); /* 2nd argument */ lua_call(L, 2, 1); if (!lua_isnil(L, -1)) return 1; lua_pop(L, 1); /* remove nil result */ } return 0; }
static int foreachi (lv_State *L) { lv_clearFirstTableValue(L); int i; int n = aux_getn(L, 1); lvL_checktype(L, 2, LV_TFUNCTION); for (i=1; i <= n; i++) { lv_pushvalue(L, 2); /* function */ lv_pushinteger(L, i); /* 1st argument */ lv_rawgeti(L, 1, i); /* 2nd argument */ lv_call(L, 2, 1); if (!lv_isnil(L, -1)) return 1; lv_pop(L, 1); /* remove nil result */ } return 0; }
static int tremove (lv_State *L) { lv_clearFirstTableValue(L); int e = aux_getn(L, 1); int pos = lvL_optint(L, 2, e); if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ return 0; /* nothing to remove */ lvL_setn(L, 1, e - 1); /* t.n = n-1 */ lv_rawgeti(L, 1, pos); /* result = t[pos] */ for ( ; pos<e; pos++) { lv_rawgeti(L, 1, pos+1); lv_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ } lv_pushnil(L); lv_rawseti(L, 1, e); /* t[e] = nil */ return 1; }
static int tconcat (lua_State *L) { luaL_Buffer b; lua_Integer last = aux_getn(L, 1, TAB_R); size_t lsep; const char *sep = luaL_optlstring(L, 2, "", &lsep); lua_Integer i = luaL_optinteger(L, 3, 1); last = luaL_optinteger(L, 4, last); luaL_buffinit(L, &b); for (; i < last; i++) { addfield(L, &b, i); luaL_addlstring(&b, sep, lsep); } if (i == last) /* add last value (if interval was not empty) */ addfield(L, &b, i); luaL_pushresult(&b); return 1; }
static int t_values (lua_State *L) { int n = aux_getn(L, 1); int i = 1; lua_createtable(L, n, 0); for (; i <= n; i++) { lua_rawgeti(L, 1, i); lua_rawseti(L, -2, i); } if (n > 0) lua_pushinteger(L, n); else lua_pushnil(L); while (lua_next(L, 1) != 0) { lua_rawseti(L, -3, i++); } return 1; }
static int tinsert (lua_State *L) { int e = aux_getn(L, 1) + 1; /* first empty element */ int pos; /* where to insert new element */ if (lua_isnone(L, 3)) /* called with only 2 arguments */ pos = e; /* insert new element at the end */ else { int i; pos = luaL_checkint(L, 2); /* 2nd argument is the position */ if (pos > e) e = pos; /* `grow' array if necessary */ lua_settop(L, 3); /* function may be called with more than 3 args */ for (i = e; i > pos; i--) { /* move up elements */ lua_rawgeti(L, 1, i-1); lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ } } luaL_setn(L, 1, e); /* new size */ lua_rawseti(L, 1, pos); /* t[pos] = v */ return 0; }
static int t_merge (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); int nr = aux_getn(L, 2); int n = 1; for (; n <= nr; n++) { lua_rawgeti(L, 2, n); lua_rawseti(L, 1, n); } if (nr > 0) lua_pushinteger(L, nr); else lua_pushnil(L); while (lua_next(L, 2) != 0) { lua_pushvalue(L, -2); lua_insert(L, -2); lua_rawset(L, 1); } return 0; }
static int tremove (killa_State *L) { int e = aux_getn(L, 1); int pos = killaL_optint(L, 2, (e + KILLA_BASE - 1)); #if (KILLA_BASE != 1) && (KILLA_BASE_WARNING == 1) if (killa_gettop(L) > 1) { killaL_warning(L, "using table.remove with possible base-1 index"); } #endif if (!(KILLA_BASE <= pos && (pos + 1 - KILLA_BASE <= e))) /* position is outside bounds? */ return 0; /* nothing to remove */ killa_rawgeti(L, 1, pos); /* result = t[pos] */ for ( ;pos<e; pos++) { killa_rawgeti(L, 1, pos+1); killa_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ } killa_pushnull(L); killa_rawseti(L, 1, e); /* t[e] = nil */ return 1; }
static int luaB_tinsert (lua_State *L) { int v = lua_gettop(L); /* number of arguments */ int n = aux_getn(L, 1) + 1; int pos; /* where to insert new element */ if (v == 2) /* called with only 2 arguments */ pos = n; /* insert new element at the end */ else { pos = luaL_checkint(L, 2); /* 2nd argument is the position */ if (pos > n) n = pos; /* `grow' array if necessary */ v = 3; /* function may be called with more than 3 args */ } luaL_setn(L, 1, n); /* new size */ while (--n >= pos) { /* move up elements */ lua_rawgeti(L, 1, n); lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ } lua_pushvalue(L, v); lua_rawseti(L, 1, pos); /* t[pos] = v */ return 0; }
static int t_slice (lua_State *L) { int n = aux_getn(L, 1); int start = posrelat(luaL_checkint(L, 2), n); int end = posrelat(luaL_optint(L, 3, -1), n); int skip = luaL_optint(L, 4, 1); luaL_argcheck(L, skip != 0, 4, "step argument must not be zero"); if (start < 1) start = 1; if (end > n) end = n; int i, ni; if (skip > 0) ni = (end >= start) ? ((end - start) / skip) + 1 : 0; else /* skip < 0 */ ni = (start >= end) ? ((start - end) / -skip) + 1 : 0; lua_createtable(L, ni, 0); for (i = 1; i <= ni; ++i) { lua_rawgeti(L, 1, start); lua_rawseti(L, -2, i); start += skip; } return 1; }
static int t_remove (lua_State *L) { int e = aux_getn(L, 1); int pos = luaL_optint(L, 2, e); int last = luaL_optint(L, 3, pos); int i; if (last < pos) return 0; if (!(1 <= last && pos <= e)) return 0; if (pos < 1) pos = 1; if (last > e) last = e; int n = last - pos + 1; luaL_setn(L, 1, e - n); for (i=0; i<n; i++) lua_rawgeti(L, 1, pos+i); for (last++; last<=e; pos++,last++) { lua_rawgeti(L, 1, last); lua_rawseti(L, 1, pos); } for( ; pos<=e; pos++) { lua_pushnil(L); lua_rawseti(L, 1, pos); } return n; }
static int getn (lv_State *L) { lv_clearFirstTableValue(L); lv_pushinteger(L, aux_getn(L, 1)); return 1; }
static int treplace (lua_State *L) { lua_Integer len, tpos, start, end, start2, end2, i; len = aux_getn(L, 1, TAB_RW); if (lua_type(L, 2) == LUA_TNUMBER) { start = luaL_checkinteger(L, 2); luaL_argcheck(L, start >= 1 && start <= len+1, 2, "index out of bounds"); if (lua_type(L, 3) == LUA_TNUMBER) { end = luaL_checkinteger(L, 3); luaL_argcheck(L, end >= start-1 && end <= len, 3, "invalid end index"); tpos = 4; } else { end = start; if (end > len) end = len; tpos = 3; } } else { start = len+1; end = len; tpos = 2; } checktab(L, tpos, TAB_R); start2 = luaL_optinteger(L, tpos+1, 1); end2 = luaL_opt(L, luaL_checkinteger, tpos+2, check_n(L, tpos)); luaL_argcheck(L, end2 >= start2-1, tpos+2, "invalid end index"); if (end2-start2 > end-start) { /* array needs to grow */ lua_pushinteger(L, len+end2-start2-end+start); lua_setfield(L, 1, "n"); /* t.n = number of elements */ } if (start <= len) { /* replace values */ lua_Integer shift = end2-start2-end+start; if (shift < 0) { /* shift to left */ for (i = end+1; i <= len; ++i) { lua_geti(L, 1, i); lua_seti(L, 1, i+shift); } for (i = len; i > len+shift; --i) { lua_pushnil(L); lua_seti(L, 1, i); } } else if (shift != 0) { /* shift to right */ for (i = len-shift+1; i <= len; ++i) { lua_geti(L, 1, i); lua_seti(L, 1, i+shift); } for (i = len-shift; i > end; --i) { lua_geti(L, 1, i); lua_seti(L, 1, i+shift); } } } /* copy from list2 to list1 */ for (i = start2; i <= end2; ++i) { lua_geti(L, tpos, i); lua_seti(L, 1, start+i-start2); } /* array must shrink */ if (end2-start2 < end-start) { lua_pushinteger(L, len+end2-start2-end+start); lua_setfield(L, 1, "n"); /* t.n = number of elements */ } return 0; }
static int ICACHE_FLASH_ATTR getn (lua_State *L) { lua_pushinteger(L, aux_getn(L, 1)); return 1; }
static int libE_getn (lua_State *L) { lua_pushinteger(L, aux_getn(L, 1)); return 1; }
static int luaB_getn (lua_State *L) { lua_pushnumber(L, (lua_Number)aux_getn(L, 1)); return 1; }