God knows what's modified

This commit is contained in:
2021-01-02 13:31:18 -05:00
parent c751678179
commit b03aada315
22 changed files with 1577 additions and 294 deletions

View File

@@ -1,13 +1,131 @@
#include "table.hpp"
#include "source.hpp"
// Clear the table. Removes metatable and all key-value pairs.
LuaDefineGlobalMethod(table_clear) {
LuaDefine(table_equal, "c") {
LuaArg t1, t2;
LuaRet eql;
LuaStack LS(L, t1, t2, eql);
LS.checktable(t1);
LS.checktable(t2);
lua_pushnil(L);
int total1 = 0;
while (lua_next(L, t1.index()) != 0) {
lua_pushvalue(L, -2); // k v1 k
lua_rawget(L, t2.index()); // k v1 v2
if (!lua_equal(L, -1, -2)) {
LS.set(eql, false);
return LS.result();
}
lua_pop(L, 2);
total1 += 1;
}
int total2 = 0;
lua_pushnil(L);
while (lua_next(L, t2.index()) != 0) {
lua_pop(L, 1);
total2 += 1;
}
LS.set(eql, total1 == total2);
return LS.result();
}
LuaDefine(table_append, "c") {
luaL_checktype(L, -2, LUA_TTABLE);
int len = lua_objlen(L, -2);
lua_pushinteger(L, len+1);
lua_pushvalue(L, -2);
lua_rawset(L, -4);
lua_pop(L, 2);
return 0;
}
LuaDefine(table_findremove, "c") {
luaL_checktype(L, -2, LUA_TTABLE);
int src = 1;
int dst = 1;
while (true) {
lua_pushinteger(L, src);
lua_rawget(L, -3);
if (lua_equal(L, -1, -2)) {
src++;
lua_pop(L, 1);
} else if (lua_isnil(L, -1)) {
lua_pop(L, 1);
int removed = src - dst;
while (src > dst) {
lua_pushinteger(L, dst);
lua_pushnil(L);
lua_rawset(L, -4);
dst++;
}
lua_pop(L, 2);
lua_pushinteger(L, removed);
return 1;
} else {
if (src > dst) {
lua_pushinteger(L, dst);
lua_insert(L, lua_gettop(L) - 1);
lua_rawset(L, -4);
} else {
lua_pop(L, 1);
}
src++;
dst++;
}
}
}
LuaDefine(table_find, "c") {
luaL_checktype(L, -2, LUA_TTABLE);
for (int i = 1; ; i++) {
lua_pushinteger(L, i);
lua_rawget(L, -3);
if (lua_equal(L, -1, -2)) {
lua_pop(L, 3);
lua_pushinteger(L, i);
return 1;
} else if (lua_isnil(L, -1)) {
lua_pop(L, 3);
lua_pushnil(L);
return 1;
} else {
lua_pop(L, 1);
}
}
}
LuaDefine(table_empty, "c") {
luaL_checktype(L, -1, LUA_TTABLE);
lua_pushnil(L);
if (lua_next(L, -2) != 0) {
lua_pop(L, 3);
lua_pushboolean(L, 0);
return 1;
} else {
lua_pop(L, 1);
lua_pushboolean(L, 1);
return 1;
}
}
LuaDefine(table_count, "c") {
luaL_checktype(L, -1, LUA_TTABLE);
lua_pushnil(L);
lua_Integer total = 0;
while (lua_next(L, -2) != 0) {
total += 1;
lua_pop(L, 1);
}
lua_pop(L, 1);
lua_pushinteger(L, total);
return 1;
}
LuaDefine(table_clear, "c") {
LuaArg tab;
LuaStack LS(L, tab);
LS.checktype(tab, LUA_TTABLE);
LS.checktable(tab);
LS.clearmetatable(tab);
lua_pushnil(L);
@@ -21,7 +139,7 @@ LuaDefineGlobalMethod(table_clear) {
return LS.result();
}
LuaDefineGlobalMethod(table_coerce) {
LuaDefine(table_coerce, "c") {
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
lua_newtable(L);
@@ -29,3 +147,77 @@ LuaDefineGlobalMethod(table_coerce) {
return 1;
}
LuaDefine(queue_create, "c") {
LuaRet queue;
LuaStack LS(L, queue);
LS.newtable(queue);
LS.setfield(queue, "head", 1000000);
LS.setfield(queue, "tail", 1000000);
return LS.result();
}
LuaDefine(queue_push, "c") {
LuaArg queue, elt;
lua_Integer head;
LuaStack LS(L, queue, elt);
LS.getfield(head, queue, "head");
LS.rawset(queue, head, elt);
LS.setfield(queue, "head", head+1);
return LS.result();
}
LuaDefine(queue_pop, "c") {
LuaArg queue;
LuaRet elt;
lua_Integer head, tail;
LuaStack LS(L, queue, elt);
LS.getfield(tail, queue, "tail");
LS.getfield(head, queue, "head");
if (head == tail) {
LS.set(elt, LuaNil);
} else {
LS.rawget(elt, queue, tail);
LS.rawset(queue, tail, LuaNil);
LS.setfield(queue, "tail", tail + 1);
}
return LS.result();
}
LuaDefine(queue_size, "c") {
LuaArg queue;
LuaRet size;
lua_Number head, tail;
LuaStack LS(L, queue, size);
LS.getfield(head, queue, "head");
LS.getfield(tail, queue, "tail");
LS.set(size, head - tail);
return LS.result();
}
LuaDefine(queue_nth, "c") {
LuaArg queue, n;
LuaRet elt;
lua_Integer nth, head, tail;
LuaStack LS(L, queue, n, elt);
nth = LS.ckinteger(n) - 1;
LS.getfield(head, queue, "head");
LS.getfield(tail, queue, "tail");
if ((nth < 0) || (nth + tail >= head)) {
luaL_error(L, "index out of range");
}
LS.rawget(elt, queue, tail + nth);
return LS.result();
}
LuaDefine(table_getregistry, "f") {
LuaArg key;
LuaRet result;
LuaStack LS(L, key, result);
LS.rawget(result, LuaRegistry, key);
return LS.result();
}