update Lua std library
This commit is contained in:
parent
7dbda8d281
commit
f16937da5a
156
common/luajit.cc
156
common/luajit.cc
@ -17,11 +17,7 @@
|
|||||||
|
|
||||||
namespace nf7::luajit {
|
namespace nf7::luajit {
|
||||||
|
|
||||||
// pushes original libraries
|
static void PushStd(lua_State* L) noexcept;
|
||||||
static void PushLuaLib(lua_State* L) noexcept;
|
|
||||||
static void PushMathLib(lua_State* L) noexcept;
|
|
||||||
static void PushTableLib(lua_State* L) noexcept;
|
|
||||||
static void PushTimeLib(lua_State* L) noexcept;
|
|
||||||
|
|
||||||
// buffer <-> lua value conversion
|
// buffer <-> lua value conversion
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -35,62 +31,8 @@ static size_t ToBytes(lua_State* L, uint8_t* ptr, uint8_t* end);
|
|||||||
|
|
||||||
void PushGlobalTable(lua_State* L) noexcept {
|
void PushGlobalTable(lua_State* L) noexcept {
|
||||||
if (luaL_newmetatable(L, "nf7::luajit::PushGlobalTable")) {
|
if (luaL_newmetatable(L, "nf7::luajit::PushGlobalTable")) {
|
||||||
PushLuaLib(L);
|
PushStd(L);
|
||||||
lua_setfield(L, -2, "lua");
|
lua_setfield(L, -2, "std");
|
||||||
|
|
||||||
PushMathLib(L);
|
|
||||||
lua_setfield(L, -2, "math");
|
|
||||||
|
|
||||||
PushTableLib(L);
|
|
||||||
lua_setfield(L, -2, "table");
|
|
||||||
|
|
||||||
PushTimeLib(L);
|
|
||||||
lua_setfield(L, -2, "time");
|
|
||||||
|
|
||||||
lua_pushcfunction(L, [](auto L) {
|
|
||||||
if (lua_isstring(L, 2)) {
|
|
||||||
const char* type = lua_tostring(L, 2);
|
|
||||||
if (std::string_view {"integer"} == type) {
|
|
||||||
PushValue(L, static_cast<nf7::Value::Integer>(luaL_checkinteger(L, 1)));
|
|
||||||
} else {
|
|
||||||
return luaL_error(L, "unknown type specifier: %s", type);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PushValue(L, CheckValue(L, 1));
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
});
|
|
||||||
lua_setfield(L, -2, "nf7_Value");
|
|
||||||
|
|
||||||
lua_pushcfunction(L, [](auto L) {
|
|
||||||
if (auto imm = ToVector(L, 1)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (auto mut = ToMutableVector(L, 1)) {
|
|
||||||
PushVector(L, std::make_shared<std::vector<uint8_t>>(std::move(*mut)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return luaL_error(L, "expected nf7::Value::MutableVector or nf7::Value::ConstVector");
|
|
||||||
});
|
|
||||||
lua_setfield(L, -2, "nf7_Vector");
|
|
||||||
|
|
||||||
lua_pushcfunction(L, [](auto L) {
|
|
||||||
if (auto imm = ToVector(L, 1)) {
|
|
||||||
if (imm->use_count() == 1) {
|
|
||||||
PushMutableVector(L, std::move(const_cast<std::vector<uint8_t>&>(**imm)));
|
|
||||||
} else {
|
|
||||||
PushMutableVector(L, std::vector<uint8_t> {**imm});
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (auto mut = ToMutableVector(L, 1)) {
|
|
||||||
PushMutableVector(L, std::vector<uint8_t> {*mut});
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
PushMutableVector(L, {});
|
|
||||||
return 1;
|
|
||||||
});
|
|
||||||
lua_setfield(L, -2, "nf7_MutableVector");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void PushImmEnv(lua_State* L) noexcept {
|
void PushImmEnv(lua_State* L) noexcept {
|
||||||
@ -439,12 +381,14 @@ std::optional<std::vector<uint8_t>> ToMutableVector(lua_State* L, int idx) noexc
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void PushLuaLib(lua_State* L) noexcept {
|
static void PushStd(lua_State* L) noexcept {
|
||||||
lua_newuserdata(L, 0);
|
lua_newuserdata(L, 0);
|
||||||
|
|
||||||
lua_createtable(L, 0, 0);
|
lua_createtable(L, 0, 0);
|
||||||
lua_createtable(L, 0, 0);
|
lua_createtable(L, 0, 0);
|
||||||
{
|
{
|
||||||
|
// ---- lua lib ----
|
||||||
|
|
||||||
|
// assert(expr[, msg])
|
||||||
lua_pushcfunction(L, [](auto L) {
|
lua_pushcfunction(L, [](auto L) {
|
||||||
if (lua_toboolean(L, 1)) {
|
if (lua_toboolean(L, 1)) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -457,11 +401,13 @@ static void PushLuaLib(lua_State* L) noexcept {
|
|||||||
});
|
});
|
||||||
lua_setfield(L, -2, "assert");
|
lua_setfield(L, -2, "assert");
|
||||||
|
|
||||||
|
// error(msg)
|
||||||
lua_pushcfunction(L, [](auto L) {
|
lua_pushcfunction(L, [](auto L) {
|
||||||
return luaL_error(L, luaL_checkstring(L, 1));
|
return luaL_error(L, luaL_checkstring(L, 1));
|
||||||
});
|
});
|
||||||
lua_setfield(L, -2, "error");
|
lua_setfield(L, -2, "error");
|
||||||
|
|
||||||
|
// load(str)
|
||||||
lua_pushcfunction(L, [](auto L) {
|
lua_pushcfunction(L, [](auto L) {
|
||||||
if (0 != luaL_loadstring(L, luaL_checkstring(L, 1))) {
|
if (0 != luaL_loadstring(L, luaL_checkstring(L, 1))) {
|
||||||
return luaL_error(L, "lua.load error: %s", lua_tostring(L, -1));
|
return luaL_error(L, "lua.load error: %s", lua_tostring(L, -1));
|
||||||
@ -470,6 +416,7 @@ static void PushLuaLib(lua_State* L) noexcept {
|
|||||||
});
|
});
|
||||||
lua_setfield(L, -2, "load");
|
lua_setfield(L, -2, "load");
|
||||||
|
|
||||||
|
// pcall(func, args...) -> success, result
|
||||||
lua_pushcfunction(L, [](auto L) {
|
lua_pushcfunction(L, [](auto L) {
|
||||||
if (0 == lua_pcall(L, lua_gettop(L)-1, LUA_MULTRET, 0)) {
|
if (0 == lua_pcall(L, lua_gettop(L)-1, LUA_MULTRET, 0)) {
|
||||||
lua_pushboolean(L, true);
|
lua_pushboolean(L, true);
|
||||||
@ -482,44 +429,35 @@ static void PushLuaLib(lua_State* L) noexcept {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
lua_setfield(L, -2, "pcall");
|
lua_setfield(L, -2, "pcall");
|
||||||
}
|
|
||||||
lua_setfield(L, -2, "__index");
|
|
||||||
lua_setmetatable(L, -2);
|
|
||||||
}
|
|
||||||
static void PushMathLib(lua_State* L) noexcept {
|
|
||||||
lua_newuserdata(L, 0);
|
|
||||||
|
|
||||||
lua_createtable(L, 0, 0);
|
|
||||||
lua_createtable(L, 0, 0);
|
// ---- math lib ----
|
||||||
{
|
|
||||||
|
// sin(theta)
|
||||||
lua_pushcfunction(L, [](auto L) {
|
lua_pushcfunction(L, [](auto L) {
|
||||||
lua_pushnumber(L, std::sin(luaL_checknumber(L, 1)));
|
lua_pushnumber(L, std::sin(luaL_checknumber(L, 1)));
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
lua_setfield(L, -2, "sin");
|
lua_setfield(L, -2, "sin");
|
||||||
|
|
||||||
|
// cos(theta)
|
||||||
lua_pushcfunction(L, [](auto L) {
|
lua_pushcfunction(L, [](auto L) {
|
||||||
lua_pushnumber(L, std::cos(luaL_checknumber(L, 1)));
|
lua_pushnumber(L, std::cos(luaL_checknumber(L, 1)));
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
lua_setfield(L, -2, "cos");
|
lua_setfield(L, -2, "cos");
|
||||||
|
|
||||||
|
// tan(slope)
|
||||||
lua_pushcfunction(L, [](auto L) {
|
lua_pushcfunction(L, [](auto L) {
|
||||||
lua_pushnumber(L, std::tan(luaL_checknumber(L, 1)));
|
lua_pushnumber(L, std::tan(luaL_checknumber(L, 1)));
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
lua_setfield(L, -2, "tan");
|
lua_setfield(L, -2, "tan");
|
||||||
}
|
|
||||||
lua_setfield(L, -2, "__index");
|
|
||||||
lua_setmetatable(L, -2);
|
|
||||||
}
|
|
||||||
static void PushTableLib(lua_State* L) noexcept {
|
|
||||||
lua_newuserdata(L, 0);
|
|
||||||
|
|
||||||
lua_createtable(L, 0, 0);
|
|
||||||
lua_createtable(L, 0, 0);
|
// ---- table lib ----
|
||||||
{
|
|
||||||
// table.setmetatable(table, meta_table)
|
// meta(table, meta_table)
|
||||||
lua_pushcfunction(L, [](auto L) {
|
lua_pushcfunction(L, [](auto L) {
|
||||||
luaL_checktype(L, 1, LUA_TTABLE);
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
luaL_checktype(L, 2, LUA_TTABLE);
|
luaL_checktype(L, 2, LUA_TTABLE);
|
||||||
@ -527,18 +465,12 @@ static void PushTableLib(lua_State* L) noexcept {
|
|||||||
lua_setmetatable(L, 1);
|
lua_setmetatable(L, 1);
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
lua_setfield(L, -2, "setmetatable");
|
lua_setfield(L, -2, "meta");
|
||||||
}
|
|
||||||
lua_setfield(L, -2, "__index");
|
|
||||||
lua_setmetatable(L, -2);
|
|
||||||
}
|
|
||||||
static void PushTimeLib(lua_State* L) noexcept {
|
|
||||||
lua_newuserdata(L, 0);
|
|
||||||
|
|
||||||
lua_createtable(L, 0, 0);
|
|
||||||
lua_createtable(L, 0, 0);
|
// ---- time lib ----
|
||||||
{
|
|
||||||
// time.now()
|
// now()
|
||||||
lua_pushcfunction(L, [](auto L) {
|
lua_pushcfunction(L, [](auto L) {
|
||||||
const auto now = nf7::Env::Clock::now().time_since_epoch();
|
const auto now = nf7::Env::Clock::now().time_since_epoch();
|
||||||
const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now);
|
const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now);
|
||||||
@ -546,6 +478,44 @@ static void PushTimeLib(lua_State* L) noexcept {
|
|||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
lua_setfield(L, -2, "now");
|
lua_setfield(L, -2, "now");
|
||||||
|
|
||||||
|
|
||||||
|
// ---- value lib ----
|
||||||
|
|
||||||
|
// value(entity) -> value
|
||||||
|
lua_pushcfunction(L, [](auto L) {
|
||||||
|
if (lua_isstring(L, 2)) {
|
||||||
|
const auto type = std::string_view {lua_tostring(L, 2)};
|
||||||
|
if (type == "integer" || type == "int") {
|
||||||
|
PushValue(L, static_cast<nf7::Value::Integer>(luaL_checkinteger(L, 1)));
|
||||||
|
} else {
|
||||||
|
return luaL_error(L, "unknown type specifier: %s", type);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PushValue(L, CheckValue(L, 1));
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
lua_setfield(L, -2, "value");
|
||||||
|
|
||||||
|
// mvector(vector or mutable vector) -> mutable vector
|
||||||
|
lua_pushcfunction(L, [](auto L) {
|
||||||
|
if (auto imm = ToVector(L, 1)) {
|
||||||
|
if (imm->use_count() == 1) {
|
||||||
|
PushMutableVector(L, std::move(const_cast<std::vector<uint8_t>&>(**imm)));
|
||||||
|
} else {
|
||||||
|
PushMutableVector(L, std::vector<uint8_t> {**imm});
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
} else if (auto mut = ToMutableVector(L, 1)) {
|
||||||
|
PushMutableVector(L, std::vector<uint8_t> {*mut});
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
PushMutableVector(L, {});
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lua_setfield(L, -2, "mvector");
|
||||||
}
|
}
|
||||||
lua_setfield(L, -2, "__index");
|
lua_setfield(L, -2, "__index");
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user