/* ** Join the ktables from p1 and p2 the ktable for the new pattern at the ** top of the stack, reusing them when possible. */ static void joinktables (lua_State *L, int p1, TTree *t2, int p2) { int n1, n2; lua_getfenv(L, p1); /* get ktables */ lua_getfenv(L, p2); n1 = ktablelen(L, -2); n2 = ktablelen(L, -1); if (n1 == 0 && n2 == 0) /* are both tables empty? */ lua_pop(L, 2); /* nothing to be done; pop tables */ else if (n2 == 0 || lua_equal(L, -2, -1)) { /* 2nd table empty or equal? */ lua_pop(L, 1); /* pop 2nd table */ lua_setfenv(L, -2); /* set 1st ktable into new pattern */ } else if (n1 == 0) { /* first table is empty? */ lua_setfenv(L, -3); /* set 2nd table into new pattern */ lua_pop(L, 1); /* pop 1st table */ } else { lua_createtable(L, n1 + n2, 0); /* create ktable for new pattern */ /* stack: new p; ktable p1; ktable p2; new ktable */ concattable(L, -3, -1); /* from p1 into new ktable */ concattable(L, -2, -1); /* from p2 into new ktable */ lua_setfenv(L, -4); /* new ktable becomes 'p' environment */ lua_pop(L, 2); /* pop other ktables */ correctkeys(t2, n1); /* correction for indices from p2 */ } }
/* ** Concatentate the contents of table 'idx1' into table 'idx2'. ** (Assume that both indices are negative.) ** Return the original length of table 'idx2' */ static int concattable (lua_State *L, int idx1, int idx2) { int i; int n1 = ktablelen(L, idx1); int n2 = ktablelen(L, idx2); if (n1 == 0) return 0; /* nothing to correct */ for (i = 1; i <= n1; i++) { lua_rawgeti(L, idx1, i); lua_rawseti(L, idx2 - 1, n2 + i); /* correct 'idx2' */ } return n2; }
/* ** Concatentate the contents of table 'idx1' into table 'idx2'. ** (Assume that both indices are negative.) ** Return the original length of table 'idx2' (or 0, if no ** element was added, as there is no need to correct any index). */ static int concattable (lua_State *L, int idx1, int idx2) { int i; int n1 = ktablelen(L, idx1); int n2 = ktablelen(L, idx2); if (n1 + n2 > USHRT_MAX) luaL_error(L, "too many Lua values in pattern"); if (n1 == 0) return 0; /* nothing to correct */ for (i = 1; i <= n1; i++) { lua_rawgeti(L, idx1, i); lua_rawseti(L, idx2 - 1, n2 + i); /* correct 'idx2' */ } return n2; }