Improvements to the pretty-printer
This commit is contained in:
@@ -257,7 +257,7 @@ void LuaStack::makeclass(LuaSlot tab, const std::string &name) const {
|
|||||||
lua_pop(L_, 1);
|
lua_pop(L_, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LuaStack::classname(LuaSlot tab) {
|
std::string LuaStack::classname(LuaSlot tab) const {
|
||||||
std::string result;
|
std::string result;
|
||||||
if (istable(tab)) {
|
if (istable(tab)) {
|
||||||
lua_pushstring(L_, "__class");
|
lua_pushstring(L_, "__class");
|
||||||
@@ -279,6 +279,22 @@ std::string LuaStack::classname(LuaSlot tab) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t LuaStack::tanid(LuaSlot tab) const {
|
||||||
|
int64_t result = 0;
|
||||||
|
if (istable(tab) && gettabletype(tab) == LUA_TT_TANGIBLE) {
|
||||||
|
if (lua_getmetatable(L_, tab.index())) {
|
||||||
|
lua_pushstring(L_, "id");
|
||||||
|
lua_rawget(L_, -2);
|
||||||
|
if (lua_type(L_, -1) == LUA_TNUMBER) {
|
||||||
|
result = int64_t(lua_tonumber(L_, -1));
|
||||||
|
}
|
||||||
|
lua_pop(L_, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LuaStack::movesortablekey(LuaSlot key, LuaStack &otherstack, LuaSlot otherslot) {
|
void LuaStack::movesortablekey(LuaSlot key, LuaStack &otherstack, LuaSlot otherslot) {
|
||||||
int type = lua_type(L_, key);
|
int type = lua_type(L_, key);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|||||||
@@ -390,7 +390,10 @@ public:
|
|||||||
void makeclass(LuaSlot tab, LuaSlot name) const;
|
void makeclass(LuaSlot tab, LuaSlot name) const;
|
||||||
void makeclass(LuaSlot tab, const char *name) const;
|
void makeclass(LuaSlot tab, const char *name) const;
|
||||||
void makeclass(LuaSlot tab, const std::string &name) const;
|
void makeclass(LuaSlot tab, const std::string &name) const;
|
||||||
std::string classname(LuaSlot tab);
|
std::string classname(LuaSlot tab) const;
|
||||||
|
|
||||||
|
int64_t tanid(LuaSlot tab) const;
|
||||||
|
|
||||||
// There's no 'isclass' operator, but 'classname' will return empty
|
// There's no 'isclass' operator, but 'classname' will return empty
|
||||||
// string if tab is not a valid class.
|
// string if tab is not a valid class.
|
||||||
|
|
||||||
|
|||||||
@@ -37,9 +37,16 @@ static bool string_quote(LuaStack &LS, LuaSlot val, std::ostream *os) {
|
|||||||
case LUA_TSTRING:
|
case LUA_TSTRING:
|
||||||
util::quote_string(LS.ckstring(val), os);
|
util::quote_string(LS.ckstring(val), os);
|
||||||
return true;
|
return true;
|
||||||
case LUA_TNUMBER:
|
case LUA_TNUMBER: {
|
||||||
(*os) << LS.ckinteger(val);
|
double value = LS.cknumber(val);
|
||||||
|
int64_t ivalue = int64_t(value);
|
||||||
|
if (double(ivalue) == value) {
|
||||||
|
(*os) << ivalue;
|
||||||
|
} else {
|
||||||
|
(*os) << value;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
case LUA_TBOOLEAN:
|
case LUA_TBOOLEAN:
|
||||||
(*os) << (LS.ckboolean(val) ? "true" : "false");
|
(*os) << (LS.ckboolean(val) ? "true" : "false");
|
||||||
return true;
|
return true;
|
||||||
@@ -140,29 +147,48 @@ static void pprint_r(Inspector &insp, int level, LuaSlot root) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the table ID is greater than zero, then we've already
|
// Determine the table's ID, allocating an ID if necessary.
|
||||||
// printed it. Just print the table ID.
|
|
||||||
LS.rawget(idv, insp.ids, root);
|
LS.rawget(idv, insp.ids, root);
|
||||||
int id = LS.ckint(idv);
|
int id = LS.ckint(idv);
|
||||||
if (id > 0) {
|
bool new_id = false;
|
||||||
if (lua_nkeys(insp.L, root.index())==0) {
|
if (id < 0) {
|
||||||
(*insp.stream) << "<table " << id << ">{}";
|
new_id = true;
|
||||||
} else {
|
id = insp.nextid++;
|
||||||
(*insp.stream) << "<table " << id << ">{...}";
|
LS.rawset(insp.ids, root, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the table's name, if any.
|
||||||
|
bool is_class = false;
|
||||||
|
bool is_tangible = false;
|
||||||
|
std::string cname = LS.classname(root);
|
||||||
|
if (cname != "") {
|
||||||
|
is_class = true;
|
||||||
|
(*insp.stream) << "<class " << cname << ">";
|
||||||
|
} else {
|
||||||
|
int64_t tid = LS.tanid(root);
|
||||||
|
if (tid > 0) {
|
||||||
|
is_tangible = true;
|
||||||
|
(*insp.stream) << "<tangible " << tid << ">";
|
||||||
|
} else if (id > 0) {
|
||||||
|
(*insp.stream) << "<table " << id << ">";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a class, and we're not at the top level, truncate.
|
||||||
|
if ((is_class || is_tangible) && (level > 0)) {
|
||||||
LS.result();
|
LS.result();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate an ID for the table, if necessary.
|
// If this is a table we've already printed, truncate it.
|
||||||
if (id < 0) {
|
if ((id > 0) && (!new_id)) {
|
||||||
id = insp.nextid++;
|
if (lua_nkeys(insp.L, root.index())==0) {
|
||||||
LS.rawset(insp.ids, root, id);
|
(*insp.stream) << "{}";
|
||||||
}
|
} else {
|
||||||
|
(*insp.stream) << "{...}";
|
||||||
// Print the table ID if greater than zero.
|
}
|
||||||
if (id > 0) {
|
LS.result();
|
||||||
(*insp.stream) << "<table " << id << ">";
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// State variables.
|
// State variables.
|
||||||
@@ -212,12 +238,6 @@ static void pprint_r(Inspector &insp, int level, LuaSlot root) {
|
|||||||
needcomma = true;
|
needcomma = true;
|
||||||
tabify(insp, level + 1);
|
tabify(insp, level + 1);
|
||||||
(*insp.stream) << "<meta> = ";
|
(*insp.stream) << "<meta> = ";
|
||||||
|
|
||||||
// if isclass(mt) then
|
|
||||||
// self:puts('<class ')
|
|
||||||
// self:puts(rawget(mt, "__class"))
|
|
||||||
// self:puts('>')
|
|
||||||
// end
|
|
||||||
pprint_r(insp, level + 1, val);
|
pprint_r(insp, level + 1, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -188,7 +188,11 @@ LuaDefine(tangible_id, "c") {
|
|||||||
LuaArg tanobj;
|
LuaArg tanobj;
|
||||||
LuaRet id;
|
LuaRet id;
|
||||||
LuaStack LS(L, tanobj, id);
|
LuaStack LS(L, tanobj, id);
|
||||||
LS.set(id, World::tangible_id(LS, tanobj));
|
int64_t tid = LS.tanid(tanobj);
|
||||||
|
if (tid == 0) {
|
||||||
|
luaL_error(L, "Not a tangible");
|
||||||
|
}
|
||||||
|
LS.set(id, tid);
|
||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ World::TanVector World::tangible_get_all(const IdVector &ids) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Tangible *World::tangible_get(const LuaStack &LS, LuaSlot tab) {
|
Tangible *World::tangible_get(const LuaStack &LS, LuaSlot tab) {
|
||||||
int64_t id = tangible_id(LS, tab);
|
int64_t id = LS.tanid(tab);
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
luaL_error(LS.state(), "parameter is not a tangible");
|
luaL_error(LS.state(), "parameter is not a tangible");
|
||||||
}
|
}
|
||||||
@@ -138,22 +138,6 @@ Tangible *World::tangible_get(const LuaStack &LS, LuaSlot tab) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t World::tangible_id(const LuaStack &LS, LuaSlot tab) {
|
|
||||||
int64_t id = 0;
|
|
||||||
if (LS.istable(tab) && LS.gettabletype(tab) == LUA_TT_TANGIBLE) {
|
|
||||||
lua_State *L = LS.state();
|
|
||||||
if (lua_getmetatable(L, tab.index())) {
|
|
||||||
lua_pushstring(L, "id");
|
|
||||||
lua_rawget(L, -2);
|
|
||||||
if (lua_type(L, -1) == LUA_TNUMBER) {
|
|
||||||
id = lua_tointeger(L, -1);
|
|
||||||
}
|
|
||||||
lua_pop(L, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tangible *World::tangible_make(lua_State *L, int64_t id, const std::string &plane, bool pushdb) {
|
Tangible *World::tangible_make(lua_State *L, int64_t id, const std::string &plane, bool pushdb) {
|
||||||
// Get a state if we don't already have one.
|
// Get a state if we don't already have one.
|
||||||
if (L == nullptr) {
|
if (L == nullptr) {
|
||||||
|
|||||||
@@ -70,11 +70,13 @@ static bool equivalent_values(LuaStack &MLS, LuaSlot mval, LuaSlot mtnmap,
|
|||||||
}
|
}
|
||||||
case LUA_TT_CLASS: {
|
case LUA_TT_CLASS: {
|
||||||
if (SLS.xtype(sval) != LUA_TT_CLASS) return false;
|
if (SLS.xtype(sval) != LUA_TT_CLASS) return false;
|
||||||
|
// What if it's an ill-formed class?
|
||||||
return MLS.classname(mval) == SLS.classname(sval);
|
return MLS.classname(mval) == SLS.classname(sval);
|
||||||
}
|
}
|
||||||
case LUA_TT_TANGIBLE: {
|
case LUA_TT_TANGIBLE: {
|
||||||
if (SLS.xtype(sval) != LUA_TT_TANGIBLE) return false;
|
if (SLS.xtype(sval) != LUA_TT_TANGIBLE) return false;
|
||||||
return World::tangible_id(MLS, mval) == World::tangible_id(SLS, sval);
|
// What if it's an ill-formed tangible?
|
||||||
|
return MLS.tanid(mval) == SLS.tanid(sval);
|
||||||
}
|
}
|
||||||
case LUA_TT_GLOBALENV: {
|
case LUA_TT_GLOBALENV: {
|
||||||
return (SLS.xtype(sval) == LUA_TT_GLOBALENV);
|
return (SLS.xtype(sval) == LUA_TT_GLOBALENV);
|
||||||
@@ -120,7 +122,7 @@ static void transmit_value(LuaStack &MLS, LuaSlot mval, LuaSlot mtnmap, StreamBu
|
|||||||
}
|
}
|
||||||
case LUA_TT_TANGIBLE: {
|
case LUA_TT_TANGIBLE: {
|
||||||
sb->write_uint8(LUA_TT_TANGIBLE);
|
sb->write_uint8(LUA_TT_TANGIBLE);
|
||||||
sb->write_int64(World::tangible_id(MLS, mval));
|
sb->write_int64(MLS.tanid(mval));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case LUA_TT_GLOBALENV: {
|
case LUA_TT_GLOBALENV: {
|
||||||
|
|||||||
@@ -130,12 +130,6 @@ public:
|
|||||||
//
|
//
|
||||||
Tangible *tangible_make(lua_State *L, int64_t id, const std::string &plane, bool pushdb);
|
Tangible *tangible_make(lua_State *L, int64_t id, const std::string &plane, bool pushdb);
|
||||||
|
|
||||||
// Get the tangible ID of the specified LUA tangible database.
|
|
||||||
//
|
|
||||||
// Return zero if the item is not a tangible database.
|
|
||||||
//
|
|
||||||
static int64_t tangible_id(const LuaStack &LS, LuaSlot slot);
|
|
||||||
|
|
||||||
// Get a pointer to the specified tangible.
|
// Get a pointer to the specified tangible.
|
||||||
//
|
//
|
||||||
// If there's no such tangible, returns nullptr.
|
// If there's no such tangible, returns nullptr.
|
||||||
|
|||||||
Reference in New Issue
Block a user