json.encode and json.decode finished. Also lots of refactoring.
This commit is contained in:
@@ -226,6 +226,40 @@ int LuaTypeTagValue(lua_State *L) { return 0; }
|
||||
#define LUA_TT_GLOBALDB 22
|
||||
#define LUA_TT_CLASS 23
|
||||
|
||||
// We use lightuserdata to store 'tokens': short
|
||||
// strings of 8 characters or less. These tokens
|
||||
// are useful as unique markers. The 8 characters
|
||||
// are packed into a uint64.
|
||||
|
||||
struct LuaToken {
|
||||
private:
|
||||
static constexpr uint64_t literal_to_token(const char *str) {
|
||||
uint64_t result = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
unsigned char c = *str;
|
||||
result = (result << 8) + c;
|
||||
if (*str) str++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public:
|
||||
uint64_t value;
|
||||
|
||||
template<class T>
|
||||
LuaToken(T arg) = delete;
|
||||
|
||||
constexpr LuaToken(const char *str) : value(literal_to_token(str)) {}
|
||||
LuaToken(uint64_t v) : value(v) {}
|
||||
LuaToken(void *v) : value((uint64_t)v) {}
|
||||
LuaToken() : value(0) {}
|
||||
|
||||
bool empty() const { return value == 0; }
|
||||
bool operator ==(const LuaToken &other) const { return value == other.value; }
|
||||
void *voidvalue() const { return (void*)value; }
|
||||
|
||||
eng::string str() const;
|
||||
};
|
||||
|
||||
class LuaStack : public eng::nevernew {
|
||||
private:
|
||||
int narg_;
|
||||
@@ -302,6 +336,7 @@ private:
|
||||
void push_any_value(lua_Integer s) const { lua_pushinteger(L_, s); }
|
||||
void push_any_value(lua_CFunction s) const { lua_pushcfunction(L_, s); }
|
||||
void push_any_value(bool b) const { lua_pushboolean(L_, b ? 1:0); }
|
||||
void push_any_value(LuaToken token) const { lua_pushlightuserdata(L_, (void*)(token.value)); }
|
||||
|
||||
// Push multiple values on the stack, in order, by type.
|
||||
template<typename T0, typename... T>
|
||||
@@ -354,6 +389,7 @@ public:
|
||||
bool isboolean(LuaSlot s) const { return lua_type(L_, s) == LUA_TBOOLEAN; }
|
||||
bool isnil(LuaSlot s) const { return lua_type(L_, s) == LUA_TNIL; }
|
||||
bool iscfunction(LuaSlot s) const { return lua_iscfunction(L_, s) != 0; }
|
||||
bool istoken(LuaSlot s) const { return lua_islightuserdata(L_, s) != 0; }
|
||||
|
||||
void checktable(LuaSlot index) const { checktype(index, LUA_TTABLE); }
|
||||
void checkstring(LuaSlot index) const { checktype(index, LUA_TSTRING); }
|
||||
@@ -362,13 +398,16 @@ public:
|
||||
void checkfunction(LuaSlot index) const { checktype(index, LUA_TFUNCTION); }
|
||||
void checkboolean(LuaSlot index) const { checktype(index, LUA_TBOOLEAN); }
|
||||
void checknil(LuaSlot index) const { checktype(index, LUA_TNIL); }
|
||||
void checktoken(LuaSlot index) const { checktype(index, LUA_TLIGHTUSERDATA); }
|
||||
|
||||
bool ckboolean(LuaSlot s) const;
|
||||
lua_Integer ckinteger(LuaSlot s) const;
|
||||
int ckint(LuaSlot s) const;
|
||||
lua_Number cknumber(LuaSlot s) const;
|
||||
eng::string ckstring(LuaSlot s) const;
|
||||
std::string_view ckstringview(LuaSlot s) const;
|
||||
lua_State *ckthread(LuaSlot s) const;
|
||||
LuaToken cktoken(LuaSlot s) const;
|
||||
|
||||
void clearmetatable(LuaSlot tab) const;
|
||||
void setmetatable(LuaSlot tab, LuaSlot mt) const;
|
||||
@@ -472,8 +511,29 @@ public:
|
||||
// Lua flagbits manipulation: visited bit.
|
||||
bool getvisited(LuaSlot tab) const;
|
||||
void setvisited(LuaSlot tab, bool visited) const;
|
||||
|
||||
// Return true if the int64 value can be stored as a lua number.
|
||||
static bool int64_storable(int64_t v) { return (v <= MAXINT) && (v >= -MAXINT); }
|
||||
};
|
||||
|
||||
class LuaConstantReg : public eng::nevernew {
|
||||
private:
|
||||
const char *name_;
|
||||
const char *docs_;
|
||||
LuaToken tokenvalue_;
|
||||
lua_Number numbervalue_;
|
||||
LuaConstantReg *next_;
|
||||
|
||||
public:
|
||||
static LuaConstantReg *All;
|
||||
LuaConstantReg(const char *name, const char *docs, LuaToken tokenvalue, lua_Number numbervalue);
|
||||
|
||||
const char *get_name() const { return name_; }
|
||||
const char *get_docs() const { return docs_; }
|
||||
LuaToken get_tokenvalue() const { return tokenvalue_; }
|
||||
lua_Number get_numbervalue() const { return numbervalue_; }
|
||||
LuaConstantReg *next() const { return next_; }
|
||||
};
|
||||
|
||||
class LuaFunctionReg : public eng::nevernew {
|
||||
private:
|
||||
@@ -498,6 +558,11 @@ public:
|
||||
void set_func(lua_CFunction fn) { func_ = fn; }
|
||||
};
|
||||
|
||||
#define LuaTokenConstant(name, tvalue, docs) \
|
||||
LuaConstantReg reg_##name(#name, docs, LuaToken(tvalue), 0);
|
||||
|
||||
#define LuaNumberConstant(name, nvalue, docs) \
|
||||
LuaConstantReg reg_##name(#name, docs, LuaToken(), nvalue);
|
||||
|
||||
#define LuaDefine(name, args, docs) \
|
||||
int lfn_##name(lua_State *L); \
|
||||
@@ -518,4 +583,5 @@ public:
|
||||
#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) { eng::string _s1_(x); eng::string _s2_(y); if (_s1_ != _s2_) luaL_error((L), "Assert failed: value=%s (file %s line %d)", _s1_.c_str(), __FILE__, __LINE__); }
|
||||
|
||||
#endif // LUASTACK_HPP
|
||||
|
||||
Reference in New Issue
Block a user