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);
|
||||
}
|
||||
|
||||
std::string LuaStack::classname(LuaSlot tab) {
|
||||
std::string LuaStack::classname(LuaSlot tab) const {
|
||||
std::string result;
|
||||
if (istable(tab)) {
|
||||
lua_pushstring(L_, "__class");
|
||||
@@ -279,6 +279,22 @@ std::string LuaStack::classname(LuaSlot tab) {
|
||||
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) {
|
||||
int type = lua_type(L_, key);
|
||||
switch (type) {
|
||||
|
||||
@@ -390,7 +390,10 @@ public:
|
||||
void makeclass(LuaSlot tab, LuaSlot name) const;
|
||||
void makeclass(LuaSlot tab, const char *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
|
||||
// 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:
|
||||
util::quote_string(LS.ckstring(val), os);
|
||||
return true;
|
||||
case LUA_TNUMBER:
|
||||
(*os) << LS.ckinteger(val);
|
||||
case LUA_TNUMBER: {
|
||||
double value = LS.cknumber(val);
|
||||
int64_t ivalue = int64_t(value);
|
||||
if (double(ivalue) == value) {
|
||||
(*os) << ivalue;
|
||||
} else {
|
||||
(*os) << value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case LUA_TBOOLEAN:
|
||||
(*os) << (LS.ckboolean(val) ? "true" : "false");
|
||||
return true;
|
||||
@@ -140,29 +147,48 @@ static void pprint_r(Inspector &insp, int level, LuaSlot root) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the table ID is greater than zero, then we've already
|
||||
// printed it. Just print the table ID.
|
||||
// Determine the table's ID, allocating an ID if necessary.
|
||||
LS.rawget(idv, insp.ids, root);
|
||||
int id = LS.ckint(idv);
|
||||
if (id > 0) {
|
||||
if (lua_nkeys(insp.L, root.index())==0) {
|
||||
(*insp.stream) << "<table " << id << ">{}";
|
||||
} else {
|
||||
(*insp.stream) << "<table " << id << ">{...}";
|
||||
bool new_id = false;
|
||||
if (id < 0) {
|
||||
new_id = true;
|
||||
id = insp.nextid++;
|
||||
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();
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate an ID for the table, if necessary.
|
||||
if (id < 0) {
|
||||
id = insp.nextid++;
|
||||
LS.rawset(insp.ids, root, id);
|
||||
}
|
||||
|
||||
// Print the table ID if greater than zero.
|
||||
if (id > 0) {
|
||||
(*insp.stream) << "<table " << id << ">";
|
||||
// If this is a table we've already printed, truncate it.
|
||||
if ((id > 0) && (!new_id)) {
|
||||
if (lua_nkeys(insp.L, root.index())==0) {
|
||||
(*insp.stream) << "{}";
|
||||
} else {
|
||||
(*insp.stream) << "{...}";
|
||||
}
|
||||
LS.result();
|
||||
return;
|
||||
}
|
||||
|
||||
// State variables.
|
||||
@@ -212,12 +238,6 @@ static void pprint_r(Inspector &insp, int level, LuaSlot root) {
|
||||
needcomma = true;
|
||||
tabify(insp, level + 1);
|
||||
(*insp.stream) << "<meta> = ";
|
||||
|
||||
// if isclass(mt) then
|
||||
// self:puts('<class ')
|
||||
// self:puts(rawget(mt, "__class"))
|
||||
// self:puts('>')
|
||||
// end
|
||||
pprint_r(insp, level + 1, val);
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +188,11 @@ LuaDefine(tangible_id, "c") {
|
||||
LuaArg tanobj;
|
||||
LuaRet 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ World::TanVector World::tangible_get_all(const IdVector &ids) const {
|
||||
}
|
||||
|
||||
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) {
|
||||
luaL_error(LS.state(), "parameter is not a tangible");
|
||||
}
|
||||
@@ -138,22 +138,6 @@ Tangible *World::tangible_get(const LuaStack &LS, LuaSlot tab) {
|
||||
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) {
|
||||
// Get a state if we don't already have one.
|
||||
if (L == nullptr) {
|
||||
|
||||
@@ -70,11 +70,13 @@ static bool equivalent_values(LuaStack &MLS, LuaSlot mval, LuaSlot mtnmap,
|
||||
}
|
||||
case LUA_TT_CLASS: {
|
||||
if (SLS.xtype(sval) != LUA_TT_CLASS) return false;
|
||||
// What if it's an ill-formed class?
|
||||
return MLS.classname(mval) == SLS.classname(sval);
|
||||
}
|
||||
case LUA_TT_TANGIBLE: {
|
||||
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: {
|
||||
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: {
|
||||
sb->write_uint8(LUA_TT_TANGIBLE);
|
||||
sb->write_int64(World::tangible_id(MLS, mval));
|
||||
sb->write_int64(MLS.tanid(mval));
|
||||
return;
|
||||
}
|
||||
case LUA_TT_GLOBALENV: {
|
||||
|
||||
@@ -130,12 +130,6 @@ public:
|
||||
//
|
||||
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.
|
||||
//
|
||||
// If there's no such tangible, returns nullptr.
|
||||
|
||||
Reference in New Issue
Block a user