/* ** Does the partition: Pivot P is at the top of the stack. ** precondition: a[lo] <= P == a[up-1] <= a[up], ** so it only needs to do the partition from lo + 1 to up - 2. ** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] ** returns 'i'. */ static IdxT partition (lua_State *L, IdxT lo, IdxT up) { IdxT i = lo; /* will be incremented before first use */ IdxT j = up - 1; /* will be decremented before first use */ /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ for (;;) { /* next loop: repeat ++i while a[i] < P */ while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ luaL_error(L, "invalid order function for sorting"); lua_pop(L, 1); /* remove a[i] */ } /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ /* next loop: repeat --j while P < a[j] */ while (lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { if (j < i) /* j < i but a[j] > P ?? */ luaL_error(L, "invalid order function for sorting"); lua_pop(L, 1); /* remove a[j] */ } /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ if (j < i) { /* no elements out of place? */ /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ lua_pop(L, 1); /* pop a[j] */ /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ set2(L, up - 1, i); return i; } /* otherwise, swap a[i] - a[j] to restore invariant and repeat */ set2(L, i, j); } }
/* ** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever ** possible, copy in increasing order, which is better for rehashing. ** "possible" means destination after original range, or smaller ** than origin, or copying to another table. */ static int tmove (lua_State *L) { lua_Integer f = luaL_checkinteger(L, 2); lua_Integer e = luaL_checkinteger(L, 3); lua_Integer t = luaL_checkinteger(L, 4); int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ checktab(L, 1, TAB_R); checktab(L, tt, TAB_W); if (e >= f) { /* otherwise, nothing to move */ lua_Integer n, i; luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, "too many elements to move"); n = e - f + 1; /* number of elements to move */ luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, "destination wrap around"); if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { for (i = 0; i < n; i++) { lua_geti(L, 1, f + i); lua_seti(L, tt, t + i); } } else { for (i = n - 1; i >= 0; i--) { lua_geti(L, 1, f + i); lua_seti(L, tt, t + i); } } } lua_pushvalue(L, tt); /* return destination table */ return 1; }
// 支持{x=1,y=2}格式,也支持{x,y}格式 Gdiplus::PointF winbox::get_point(lua_State* L, int idx) { lua_guard g(L); float x= 0, y = 0; if (luaL_len(L, idx) == 2) { lua_geti(L, idx, 1); x = (float)lua_tonumber(L, -1); lua_pop(L, 1); lua_geti(L, idx, 2); y = (float)lua_tonumber(L, -1); lua_pop(L, 1); } else { lua_getfield(L, idx, "x"); x = (float)lua_tonumber(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "y"); y = (float)lua_tonumber(L, -1); lua_pop(L, 1); } logic_to_window(x, y); return Gdiplus::PointF(x, y); }
static void reverse (lua_State *L, lua_Integer a, lua_Integer b) { for (; a < b; ++a, --b) { lua_geti(L, -1, a); lua_geti(L, -2, b); lua_seti(L, -3, a); lua_seti(L, -2, b); } }
static int tunpack (lua_State *L) { lua_Unsigned n; lua_Integer i = luaL_optinteger(L, 2, 1); lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); 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) { 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 tshuffle (lua_State *L) { lua_Integer begin, end; checktab(L, 1, TAB_RW); begin = luaL_optinteger(L, 2, 1); end = luaL_opt(L, luaL_checkinteger, 3, check_n(L, 1)); while (end >= begin) { double f = l_rand() * (1.0/(L_RANDMAX+1.0)); lua_Integer j = begin + (lua_Integer)(f * (end-begin+1)); lua_geti(L, 1, end); lua_geti(L, 1, j); lua_seti(L, 1, end); lua_seti(L, 1, j); --end; } return 0; }
static int tinsert (lua_State *L) { lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ lua_Integer pos; /* where to insert new element */ switch (lua_gettop(L)) { case 2: { /* called with only 2 arguments */ pos = e; /* insert new element at the end */ break; } case 3: { lua_Integer i; pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); for (i = e; i > pos; i--) { /* move up elements */ lua_geti(L, 1, i - 1); lua_seti(L, 1, i); /* t[i] = t[i - 1] */ } break; } default: { return luaL_error(L, "wrong number of arguments to 'insert'"); } } lua_seti(L, 1, pos); /* t[pos] = v */ return 0; }
// register void Script::Register() { // push clone function first lua_getglobal(vm, "clone"); // load and put template table on top of the stack int ret = scriptingsystem->LoadFile(File); // get gameobject _ENV for sandboxing lua_getglobal(vm, "objects"); lua_geti(vm, -1, ObjectId); lua_remove(vm, -2); // set _ENV lua_pushvalue(vm, -1); lua_setfield(vm, -2, "gameobject"); // set global env to "engine" lua_pushglobaltable(vm); lua_setfield(vm, -2, "engine"); // set event table lua_newtable(vm); lua_setfield(vm, -2, "event"); // set upvalue _ENV , copy data to gameobject's table ret = lua_pcall(vm, 2, 0, 0); if (ret) { printf("eror pcall: %s %d\n", lua_tostring(vm, -1), __LINE__); } scriptingsystem->RegisterScript(this); }
static int Solver_addDIMACSSeqence(struct lua_State *state) { LGL* lgl = get_lgl(state); int n = lua_gettop (state); int success; for (int i = 2; i <= n; i++) { int type = lua_type (state, i); if (type == LUA_TTABLE) { // Iterate over the entries of the table lua_len(state, i); lua_Integer len = lua_tointeger(state, -1); lua_pop(state, 1); for (int j = 1; j <= len; j++) { lua_geti(state, i, j); lua_Integer c = lua_tointegerx (state, -1, &success); if (!success) { lua_pushliteral(state, "Illegal argument in DIMACS sequence"); lua_error(state); } lgladd (lgl, c); lua_pop(state, 1); } } else { lua_Integer c = lua_tointegerx (state, i, &success); if (!success) { lua_pushliteral(state, "Illegal argument in DIMACS sequence"); lua_error(state); } lgladd (lgl, c); } } return 0; }
static int Solver_query(struct lua_State *state) { LGL* lgl = get_lgl(state); if (lua_gettop(state) != 2) { lua_pushliteral(state, "Query must be called with arguments self and a table"); lua_error(state); } int type = lua_type(state, 2); if (type != LUA_TTABLE) { lua_pushliteral(state, "Query must be called with a table argument"); lua_error(state); } lua_newtable (state); // Stack pos 3 lua_len(state, 2); lua_Integer len = lua_tointeger(state, -1); lua_pop(state, 1); for (int j = 1; j <= len; j++) { lua_geti(state, 2, j); lua_Integer c = lua_tointeger (state, -1); if (!c) { lua_pushliteral(state, "Array may contain only non-zero integers"); lua_error(state); } lua_pop(state,1); lua_pushinteger(state, lglderef(lgl, c)); lua_seti(state, 3, j); } return 1; }
static void magnet_get_global_table(lua_State *L) { /* (-0, +1, e) */ #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502 lua_geti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); #else lua_pushvalue(L, LUA_GLOBALSINDEX); #endif }
int Script::OnDestroy(GameObject * GameObj) { // this will completelly remove the reference to gameobject in scripting space // so scripts can no longer use this gameobjects // gameobject maynot be removed immediatly after this call // because of how lua's garbage collection works if (ObjectId == -1) { return 1; } // get gameobject table lua_getglobal(vm, "entities"); lua_geti(vm, -1, ObjectId); // todo:: set obj's metatable to a default special table to disable operations on this object // can't do this now because it will ruin the __gc meta method //lua_getglobal(vm, "destroyed_mt"); //lua_setmetatable(vm, -2); lua_pop(vm, 1); // set entitis[id] to nil lua_pushnil(vm); lua_seti(vm, -2, ObjectId); // balance the stack lua_pop(vm, 1); // reset objectid ObjectId = -1; Component::OnDestroy(GameObj); return 0; }
static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { lua_geti(L, 1, i); if (!lua_isstring(L, -1)) luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", luaL_typename(L, -1), i); luaL_addvalue(b); }
// 计算lua table的长度 static size_t count_size(lua_State *L, int index) { size_t tlen = 0; int i; for (i=1;lua_geti(L, index, i) != LUA_TNIL; ++i) { size_t len; luaL_checklstring(L, -1, &len); tlen += len; lua_pop(L,1); } lua_pop(L,1); return tlen; }
static int hook_call(lua_State* L) { luaL_testudata(L, 1, "hook"); if (LUA_TTABLE != lua_getuservalue(L, 1)) { return 0; } if (LUA_TUSERDATA != lua_geti(L, -1, 1)) { return 0; } lua_remove(L, -2); lua_replace(L, 1); lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); return lua_gettop(L); }
/* ** QuickSort algorithm (recursive function) */ static void auxsort (lua_State *L, IdxT lo, IdxT up, unsigned int rnd) { while (lo < up) { /* loop for tail recursion */ IdxT p; /* Pivot index */ IdxT n; /* to be used later */ /* sort elements 'lo', 'p', and 'up' */ lua_geti(L, 1, lo); lua_geti(L, 1, up); if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */ set2(L, lo, up); /* swap a[lo] - a[up] */ else lua_pop(L, 2); /* remove both values */ if (up - lo == 1) /* only 2 elements? */ return; /* already sorted */ if (up - lo < RANLIMIT || rnd == 0) /* small interval or no randomize? */ p = (lo + up)/2; /* middle element is a good pivot */ else /* for larger intervals, it is worth a random pivot */ p = choosePivot(lo, up, rnd); lua_geti(L, 1, p); lua_geti(L, 1, lo); if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */ set2(L, p, lo); /* swap a[p] - a[lo] */ else { lua_pop(L, 1); /* remove a[lo] */ lua_geti(L, 1, up); if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */ set2(L, p, up); /* swap a[up] - a[p] */ else lua_pop(L, 2); } if (up - lo == 2) /* only 3 elements? */ return; /* already sorted */ lua_geti(L, 1, p); /* get middle element (Pivot) */ lua_pushvalue(L, -1); /* push Pivot */ lua_geti(L, 1, up - 1); /* push a[up - 1] */ set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */ p = partition(L, lo, up); /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */ if (p - lo < up - p) { /* lower interval is smaller? */ auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */ n = p - lo; /* size of smaller interval */ lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */ } else { auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */ n = up - p; /* size of smaller interval */ up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */ } if ((up - lo) / 128 > n) /* partition too imbalanced? */ rnd = l_randomizePivot(); /* try a new randomization */ } /* tail call auxsort(L, lo, up, rnd) */ }
static int l_setzoom( lua_State* L ) { gwlua_t* state = get_state( L ); if ( lua_type( L, 1 ) == LUA_TTABLE ) { lua_geti( L, 1, 1 ); int x0 = luaL_checkinteger( L, -1 ); lua_geti( L, 1, 2 ); int y0 = luaL_checkinteger( L, -1 ); lua_geti( L, 1, 3 ); int width = luaL_checkinteger( L, -1 ); lua_geti( L, 1, 4 ); int height = luaL_checkinteger( L, -1 ); gwlua_zoom( state, x0, y0, width, height ); } else { gwlua_zoom( state, -1, -1, -1, -1 ); } return 0; }
//handle event int Script::HandleEvent(Event * Evt) { if (ObjectId == -1) { return 1; } // user event is larger than USER_EVENT if (Evt->EventId > USER_EVENT) { // this is event sent from scripts // get evnet table lua_getglobal(vm, "objects"); lua_geti(vm, -1, ObjectId); lua_getfield(vm, -1, "event"); // call callback within _ENV lua_geti(vm, -1, Evt->EventId); lua_pushvalue(vm, -3); lua_setupvalue(vm, -2, 1); int ret = lua_pcall(vm, 0, LUA_MULTRET, 0); if (ret) { printf("eror pcall: %s %d\n", lua_tostring(vm, -1), __LINE__); } // balance the stack lua_pop(vm, 3); } return 0; }
STATIC int Script_Buffer_drawPopup(lua_State* L) { Buffer* buffer = (Buffer*) ((Proxy*)luaL_checkudata(L, 1, "Buffer"))->ptr; luaL_checktype(L, 2, LUA_TTABLE); int len = lua_rawlen(L, 2); buffer->popup = calloc(sizeof(char*), len+1); for(int i = 1; ; i++) { int typ = lua_geti(L, 2, i); if (typ != LUA_TSTRING) break; buffer->popup[i-1] = strdup(lua_tostring(L, -1)); lua_pop(L, 1); } buffer->panel->needsRedraw = true; return 0; }
static int Init(lua_State *L) { int table_index; int argc, i; char **argv; const char *arg; if(lua_isnoneornil(L, 1)) argc = 1; else { if(!lua_istable(L,1)) return luaL_argerror(L, 1, "table expected"); table_index = 1; argc = luaL_len(L, table_index) + 1; } argv = (char**)malloc(sizeof(char*) * argc); if(argv == NULL) return luaL_error(L, "cannot allocate memory"); //argv[0] = "moonglut"; argv[0] = strdup("moonglut"); if(argc > 1) { for(i = 1; i < argc; i++) { lua_geti(L, table_index, i); arg = luaL_checkstring(L, -1); argv[i] = strdup(arg); if(argv[i] == NULL) return luaL_error(L, "cannot allocate memory"); lua_pop(L, 1); } } glutInit(&argc, argv); /* return the modified arg table */ lua_newtable(L); table_index = lua_gettop(L); for(i = 1; i < argc; i++) { lua_pushstring(L, argv[i]); lua_seti(L, table_index, i); } return 1; }
int Script::Subscribe(int Event, String& Callback) { if (ObjectId == -1) { return 1; } Component::Subscribe(Event, Callback); // set event to function mapping in gameobject's event_table // get gameobhect lua_getglobal(vm, "objects"); lua_geti(vm, -1, ObjectId); lua_getfield(vm, -1, "event"); // get callback functions lua_getfield(vm, -2, Callback.ToStr()); lua_seti(vm, -2, Event); // done. clear the stack lua_pop(vm, 3); return 0; }
void Script::Start() { // run on_start in gameobject's _ENV if (ObjectId == -1) { return; } lua_getglobal(vm, "objects"); lua_geti(vm, -1, ObjectId); lua_getfield(vm, -1, "on_start"); // push ms lua_pushvalue(vm, -2); lua_setupvalue(vm, -2, 1); int ret = lua_pcall(vm, 0, LUA_MULTRET, 0); if (ret) { printf("eror pcall: %s\n", lua_tostring(vm, -1)); } lua_pop(vm, 2); }
/** * Loads a WML file into a config * - Arg 1: WML file path * - Arg 2: (optional) Array of preprocessor defines, or false to skip preprocessing (true is also valid) * - Arg 3: (optional) Path to a schema file for validation (omit for no validation) * - Ret: config */ static int intf_load_wml(lua_State* L) { std::string file = luaL_checkstring(L, 1); bool preprocess = true; preproc_map defines_map; if(lua_type(L, 2) == LUA_TBOOLEAN) { preprocess = luaW_toboolean(L, 2); } else if(lua_type(L, 2) == LUA_TTABLE || lua_type(L, 2) == LUA_TUSERDATA) { lua_len(L, 2); int n = lua_tonumber(L, -1); lua_pop(L, 1); for(int i = 0; i < n; i++) { lua_geti(L, 2, i); if(!lua_isstring(L, -1)) { return luaL_argerror(L, 2, "expected bool or array of strings"); } std::string define = lua_tostring(L, -1); lua_pop(L, 1); if(!define.empty()) { defines_map.emplace(define, preproc_define(define)); } } } else if(!lua_isnoneornil(L, 2)) { return luaL_argerror(L, 2, "expected bool or array of strings"); } std::string schema_path = luaL_optstring(L, 3, ""); std::shared_ptr<schema_validation::schema_validator> validator; if(!schema_path.empty()) { validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location(schema_path))); validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway } std::string wml_file = filesystem::get_wml_location(file); filesystem::scoped_istream stream; config result; if(preprocess) { stream = preprocess_file(wml_file, &defines_map); } else { stream.reset(new std::ifstream(wml_file)); } read(result, *stream, validator.get()); luaW_pushconfig(L, result); return 1; }
int testquat(lua_State *L, int arg, quat_t q) /* Tests if the element at arg is a quaternion and sets q accordingly * (unless it is passed as 0). */ { size_t i; if(!testmetatable(L, arg, QUAT_MT)) return 0; if(q != NULL) { for(i=0; i < 4; i++) { lua_geti(L, arg, i+1); q[i] = luaL_checknumber(L, -1); lua_pop(L, 1); } } return 1; }
int Script::Update(int ms) { // run update in gameobject's _ENV if (ObjectId == -1) { return 1; } lua_getglobal(vm, "objects"); lua_geti(vm, -1, ObjectId); lua_getfield(vm, -1, "update"); // push ms lua_pushinteger(vm, ms); lua_pushvalue(vm, -3); lua_setupvalue(vm, -3, 1); int ret = lua_pcall(vm, 1, LUA_MULTRET, 0); if (ret) { printf("eror pcall: %s\n", lua_tostring(vm, -1)); } lua_pop(vm, 2); // printf("%d\n", lua_gettop(vm)); return 0; }
// 把lua table连接成字符串 static void concat_table(lua_State *L, int index, void *buffer, size_t tlen) { char *ptr = buffer; int i; for (i=1;lua_geti(L, index, i) != LUA_TNIL; ++i) { size_t len; const char * str = lua_tolstring(L, -1, &len); if (str == NULL || tlen < len) { break; } memcpy(ptr, str, len); ptr += len; tlen -= len; lua_pop(L,1); } if (tlen != 0) { skynet_free(buffer); luaL_error(L, "Invalid strings table"); } lua_pop(L,1); }
GLuint init_shader_str(const char *ray_v_src, const char *ray_f_src, const char *ray_g_src, lua_State *L) { int i; const char *ray_v_src_alias = ray_v_src; const char *ray_g_src_alias = ray_g_src; const char *ray_f_src_alias = ray_f_src; GLuint ray_v = glCreateShader(GL_VERTEX_SHADER); GLuint ray_g = (ray_g_src == NULL ? 0 : glCreateShader(GL_GEOMETRY_SHADER)); GLuint ray_f = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(ray_v, 1, &ray_v_src_alias, NULL); if(ray_g_src != NULL) glShaderSource(ray_g, 1, &ray_g_src_alias, NULL); glShaderSource(ray_f, 1, &ray_f_src_alias, NULL); glCompileShader(ray_v); printf("=== VERTEX SHADER ===\n"); print_shader_log(ray_v); if(ray_g_src != NULL) { glCompileShader(ray_g); printf("=== GEOMETRY SHADER ===\n"); print_shader_log(ray_g); } glCompileShader(ray_f); printf("=== FRAGMENT SHADER ===\n"); print_shader_log(ray_f); GLuint out_shader = glCreateProgram(); printf("Attaching shaders\n"); glAttachShader(out_shader, ray_v); if(ray_g_src != NULL) glAttachShader(out_shader, ray_g); glAttachShader(out_shader, ray_f); // TODO: outsource this to a function glGetError(); printf("Binding inputs\n"); lua_len(L, 2); int len_input = lua_tointeger(L, -1); lua_pop(L, 1); for(i = 0; i < len_input; i++) { lua_geti(L, 2, i+1); glBindAttribLocation(out_shader, i, lua_tostring(L, -1)); lua_pop(L, 1); } if(!context_is_compat) { printf("Binding outputs\n"); lua_len(L, 3); int len_output = lua_tointeger(L, -1); lua_pop(L, 1); for(i = 0; i < len_output; i++) { lua_geti(L, 3, i+1); glBindFragDataLocation(out_shader, i, lua_tostring(L, -1)); lua_pop(L, 1); } } printf("%i\n", glGetError()); printf("Linking! This is the part where your computer dies\n"); glLinkProgram(out_shader); printf("Getting results\n"); printf("=== OVERALL PROGRAM ===\n"); print_program_log(out_shader); GLint link_status; glGetProgramiv(out_shader, GL_LINK_STATUS, &link_status); printf("Link status: %i\n", link_status); if(link_status == GL_TRUE) { return out_shader; } else { glDeleteProgram(out_shader); glDeleteShader(ray_v); if(ray_g_src != NULL) glDeleteShader(ray_g); glDeleteShader(ray_f); return 0; } }
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; }
/* ** Traversal function for 'ipairs' for tables with metamethods */ static int ipairsaux (lua_State *L) { lua_Integer i = luaL_checkinteger(L, 2) + 1; lua_pushinteger(L, i); return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2; }