Add support for doc(builtin)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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__); }
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user