Add support for doc(builtin)

This commit is contained in:
2021-12-16 13:06:15 -05:00
parent 1cfdb4fa09
commit 9b956f00e7
5 changed files with 80 additions and 4 deletions

View File

@@ -17,7 +17,7 @@ LuaFunctionReg::LuaFunctionReg(const char *n, const char *a, const char *d, lua_
LuaFunctionReg::List LuaFunctionReg::all() {
LuaFunctionReg::List result;
for (const LuaFunctionReg *r = LuaFunctionRegistry; r != 0; r = r->next_) {
for (LuaFunctionReg *r = LuaFunctionRegistry; r != 0; r = r->next_) {
result.push_back(r);
}
return result;
@@ -366,7 +366,7 @@ std::string LuaStack::get_function_name(LuaSlot fn) {
LS.getglobaltable(globals);
LS.set(key, LuaNil);
while (LS.next(globals, key, val)) {
if (LS.isstring(key)) {
if (LS.isstring(key) && !LS.rawequal(globals, val)) {
if (LS.rawequal(val, fn)) {
return LS.ckstring(key);
}

View File

@@ -478,7 +478,7 @@ private:
static LuaFunctionReg *LuaFunctionRegistry;
public:
using List = std::vector<const LuaFunctionReg *>;
using List = std::vector<LuaFunctionReg *>;
LuaFunctionReg(const char *name, const char *args, const char *docs, lua_CFunction f);
static List all();
@@ -488,6 +488,7 @@ public:
const char *get_args() const { return args_; }
const char *get_docs() const { return docs_; }
lua_CFunction get_func() const { return func_; }
void set_func(lua_CFunction fn) { func_ = fn; }
};
@@ -497,6 +498,10 @@ public:
int lfn_##name(lua_State *L)
#define LuaDefineBuiltin(name, args, docs) \
LuaFunctionReg reg_##name(#name, args, docs, nullptr);
#define LuaStringify(x) #x
#define LuaAssert(L, x) if (!(x)) { luaL_error((L), "Assert failed: %s (file %s line %d)", LuaStringify(x), __FILE__, __LINE__); }
#define LuaAssertStrEq(L, x, y) { std::string _s1_ = (x); std::string _s2_ = (y); if (_s1_ != _s2_) luaL_error((L), "Assert failed: value=%s (file %s line %d)", _s1_.c_str(), __FILE__, __LINE__); }

View File

@@ -4,6 +4,7 @@
#include "lpxserver.hpp"
#include "drivertests.hpp"
#include "driver.hpp"
#include "source.hpp"
#include <iostream>
struct EngineMaker {
@@ -33,6 +34,7 @@ static void usage() {
int main(int argc, char **argv)
{
SourceDB::register_lua_builtins();
UniqueDrivenEngine engine;
if (argc < 2) usage();
std::string mode = argv[1];

View File

@@ -78,6 +78,19 @@ static void load_builtin_class(lua_State *L, const char *name, lua_CFunction fun
LS.result();
}
static void erase_builtin(LuaStack &LS, LuaSlot globtab, const std::string &classname, const std::string &funcname) {
if (classname.empty()) {
LS.rawset(globtab, funcname, LuaNil);
} else {
LuaVar classtab;
LuaStack LSX(LS.state(), classtab);
LS.rawget(classtab, globtab, classname);
if (LS.istable(classtab)) {
LS.rawset(classtab, funcname, LuaNil);
}
}
}
static void source_install_builtins(lua_State *L) {
LuaVar nullstring, stringclass, globtab;
LuaStack LS(L, nullstring, stringclass, globtab);
@@ -90,7 +103,10 @@ static void source_install_builtins(lua_State *L) {
// Nuke a few of the builtin functions for sandboxing reasons.
LS.getglobaltable(globtab);
LS.rawset(globtab, "loadfile", LuaNil);
erase_builtin(LS, globtab, "", "loadfile");
erase_builtin(LS, globtab, "", "loadstring");
erase_builtin(LS, globtab, "string", "dump");
// Set the metatable for strings.
// Normally, this would be done by luaopen_string, but we're
@@ -468,6 +484,35 @@ void SourceDB::deserialize_source(util::LuaSourceVec *sv, StreamBuffer *sb) {
}
}
void SourceDB::register_lua_builtins() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
LuaVar globals,classtab,func;
LuaStack LS(L, globals, classtab, func);
LS.getglobaltable(globals);
auto regs = LuaFunctionReg::all();
for (LuaFunctionReg *reg : regs) {
std::string funcname;
std::string classname;
get_reg_name(reg, classname, funcname);
if (classname.empty()) {
LS.rawget(func, globals, funcname);
if (LS.iscfunction(func)) {
reg->set_func(lua_tocfunction(L, func.index()));
}
} else {
LS.rawget(classtab, globals, classname);
if (LS.istable(classtab)) {
LS.rawget(func, classtab, funcname);
if (LS.iscfunction(func)) {
reg->set_func(lua_tocfunction(L, func.index()));
}
}
}
}
lua_close(L);
}
std::string SourceDB::function_docs(const LuaStack &LS0, LuaSlot fn) {
lua_State *L = LS0.state();
LuaVar sourcedb, fname, finfo, code;
@@ -636,3 +681,24 @@ LuaDefine(unittests_sourcedb, "", "some unit tests") {
return 0;
}
LuaDefineBuiltin(table_concat, "vector1, vector2", "concatenate two vectors");
LuaDefineBuiltin(table_insert, "vector, pos, value", "insert an element into a vector");
LuaDefineBuiltin(table_remove, "vector, pos", "remove an element from a vector");
LuaDefineBuiltin(table_sort, "vector [,comparefn]", "sort a vector");
LuaDefineBuiltin(table_pack, "v1, v2, v3...", "turn a sequence of arguments into a vector");
LuaDefineBuiltin(table_unpack, "vector", "turn a vector into a sequence of return values");
LuaDefineBuiltin(string_byte, "str [,index]", "get a single byte from a string");
LuaDefineBuiltin(string_char, "byte, byte,...", "convert sequence of bytes to a string");
LuaDefineBuiltin(string_find, "str, pattern [,index]", "return start and end of pattern in a string");
LuaDefineBuiltin(string_len, "str", "return the length of the string, in bytes");
LuaDefineBuiltin(string_rep, "str, count", "repeat the string some number of times");
LuaDefineBuiltin(string_reverse, "str", "reverse the bytes of the string");
LuaDefineBuiltin(string_lower, "str", "convert string to lowercase");
LuaDefineBuiltin(string_upper, "str", "convert string to uppercase");
LuaDefineBuiltin(string_format, "formatstr, v1,v2,v3...", "generate formatted output string");
LuaDefineBuiltin(string_gmatch, "str, pattern", "iterate over pattern-matched substrings");
LuaDefineBuiltin(string_gsub, "str, pattern, replace", "global replace pattern in string");
LuaDefineBuiltin(string_match, "str, pattern", "return start and end of pattern in string");
LuaDefineBuiltin(string_sub, "str, pos1, pos2", "return substring of str from pos1 to pos2");

View File

@@ -173,6 +173,9 @@ public:
void set(const std::string &fn, const std::string &code, int sequence);
std::string get(const std::string &fn);
// Add builtins to the global function registry.
static void register_lua_builtins();
// Get function documentation.
static std::string function_docs(const LuaStack &LS, LuaSlot slot);