From 47c868876a594041462b3d6661fd0e22f89c0c95 Mon Sep 17 00:00:00 2001 From: jyelon Date: Fri, 14 Apr 2023 14:52:44 -0400 Subject: [PATCH] Add LuaDefineAlias --- luprex/cpp/core/http.cpp | 2 +- luprex/cpp/core/luastack.hpp | 12 ++++---- luprex/cpp/core/pprint.cpp | 22 +++----------- luprex/cpp/core/table.cpp | 58 ++++++++++++++++++++++++++---------- 4 files changed, 53 insertions(+), 41 deletions(-) diff --git a/luprex/cpp/core/http.cpp b/luprex/cpp/core/http.cpp index 2a8ae3d2..7f484250 100644 --- a/luprex/cpp/core/http.cpp +++ b/luprex/cpp/core/http.cpp @@ -683,7 +683,7 @@ void HttpClientRequest::set_params(LuaCoreStack &LS0, LuaSlot tab) { return; } LuaVar key, val; - LuaDefStack LS(LS0.state(), key, val); + LuaExtStack LS(LS0.state(), key, val); LS.set(key, LuaNil); while (LS.next(tab, key, val)) { set_param(LS, key, val); diff --git a/luprex/cpp/core/luastack.hpp b/luprex/cpp/core/luastack.hpp index d00a8f82..53ac2555 100644 --- a/luprex/cpp/core/luastack.hpp +++ b/luprex/cpp/core/luastack.hpp @@ -411,7 +411,7 @@ public: int rawlen(LuaSlot val) const; int nkeys(LuaSlot tab) const; - + int next(LuaSlot tab, LuaSlot key, LuaSlot value) const; // Return true if the classname is legal. @@ -902,13 +902,13 @@ public: #define LuaDefine(name, args, docs) \ int lfn_##name(lua_State *L); \ - LuaFunctionReg reg_##name(#name, args, docs, false, lfn_##name); \ + const char *lfnarg_##name = args; \ + const char *lfndoc_##name = docs; \ + LuaFunctionReg reg_##name(#name, lfnarg_##name, lfndoc_##name, false, lfn_##name); \ int lfn_##name(lua_State *L) -#define LuaSandbox(name, args, docs) \ - int lfn_##name(lua_State *L); \ - LuaFunctionReg reg_##name(#name, args, docs, true, lfn_##name); \ - int lfn_##name(lua_State *L) +#define LuaDefineAlias(name1, name2) \ + LuaFunctionReg reg_##name1(#name1, lfnarg_##name2, lfndoc_##name2, false, lfn_##name2); \ #define LuaDefineBuiltin(name, args, docs) \ LuaFunctionReg reg_##name(#name, args, docs, false, nullptr); diff --git a/luprex/cpp/core/pprint.cpp b/luprex/cpp/core/pprint.cpp index a786d766..e7a838d9 100644 --- a/luprex/cpp/core/pprint.cpp +++ b/luprex/cpp/core/pprint.cpp @@ -320,25 +320,9 @@ LuaDefine(string_print, "obj", "|Concise print the specified object into a string" "|" "|This prints a concise representation of obj into a string. Tables" - "|are not expanded: for that, use string.pprintx. The functions" - "|tostring and string.print are identical." - "|") { - LuaArg val; - LuaRet result; - LuaDefStack LS(L, val, result); - eng::ostringstream oss; - atomic_print(LS, val, false, &oss); - LS.set(result, oss.str()); - return LS.result(); -} - - -LuaDefine(tostring, "obj", - "|Concise print the specified object into a string" + "|are not expanded: for that, use string.pprint or string.pprintx." "|" - "|This prints a concise representation of obj into a string. Tables" - "|are not expanded: for that, use string.pprint. The functions" - "|tostring and string.print are identical." + "|The functions string.print and tostring are identical." "|") { LuaArg val; LuaRet result; @@ -349,6 +333,8 @@ LuaDefine(tostring, "obj", return LS.result(); } +LuaDefineAlias(tostring, string_print); + LuaDefine(string_isidentifier, "str", "return true if the string is a valid lua identifier") { LuaArg str; LuaRet result; diff --git a/luprex/cpp/core/table.cpp b/luprex/cpp/core/table.cpp index d6d7340f..cb5f9d19 100644 --- a/luprex/cpp/core/table.cpp +++ b/luprex/cpp/core/table.cpp @@ -60,7 +60,16 @@ LuaDefine(table_equal, "table1,table2", return LS.result(); } -static int check_isvector(lua_State *L) { +LuaDefine(table_isvector, "table", + "|Return true if the table is a valid vector." + "|" + "|A vector is a table that has keys starting with 1, and no gaps." + "|The empty table also counts as a valid vector. This function" + "|scans the entire vector to verify its validity, so it takes O(N)" + "|time. See also table.isvectorq" + "|" + "|The functions vector.isvector and table.isvector are identical." + "|") { LuaArg table; LuaRet result; LuaVar tmp; @@ -81,27 +90,44 @@ static int check_isvector(lua_State *L) { return LS.result(); } -LuaDefine(table_isvector, "table", - "|Return true if the table is a valid vector." +LuaDefine(table_isvectorq, "table", + "|Return true if the table is probably a valid vector." "|" "|A vector is a table that has keys starting with 1, and no gaps." - "|The empty table also counts as a valid vector." + "|The empty table also counts as a valid vector. This function" + "|does a constant-time heuristic check: it gets the number of keys" + "|in the table, NKEYS. Then it verifies that table[NKEYS] is not" + "|nil and that table[NKEYS+1] is nil. If these things are both" + "|true, the table is very likely a valid vector." "|" - "|This function is identical to vector.isvector" + "|The functions vector.isvectorq and table.isvectorq are identical." "|") { - return check_isvector(L); + LuaArg table; + LuaRet result; + LuaVar tmp; + LuaDefStack LS(L, table, result, tmp); + if (!LS.istable(table)) { + LS.set(result, false); + return LS.result(); + } + int nkeys = LS.nkeys(table); + if (nkeys > 0) { + LS.rawget(tmp, table, nkeys); + if (LS.isnil(tmp)) { + LS.set(result, false); + return LS.result(); + } + LS.rawget(tmp, table, nkeys + 1); + if (!LS.isnil(tmp)) { + LS.set(result, false); + return LS.result(); + } + } + LS.set(result, true); + return LS.result(); } -LuaDefine(vector_isvector, "table", - "|Return true if the table is a valid vector." - "|" - "|A vector is a table that has keys starting with 1, and no gaps." - "|The empty table also counts as a valid vector." - "|" - "|This function is identical to table.isvector" - "|") { - return check_isvector(L); -} +LuaDefineAlias(vector_isvector, table_isvector); LuaDefine(vector_removeall, "vector,value", "|Remove all occurrences of value from vector."