From e75147ec77359cd31ce8c28c0a27c5b09ee5013b Mon Sep 17 00:00:00 2001 From: Max Cahill <1bardesign@gmail.com> Date: Fri, 17 Apr 2020 10:45:15 +1000 Subject: [PATCH] [modified] moved tablex.stringify to stringx.pretty --- stringx.lua | 65 ++++++++++++++++++++++++++++++++++++++++++++++++----- tablex.lua | 38 ------------------------------- 2 files changed, 59 insertions(+), 44 deletions(-) diff --git a/stringx.lua b/stringx.lua index e98ece1..8fd3a40 100644 --- a/stringx.lua +++ b/stringx.lua @@ -8,15 +8,24 @@ local stringx = setmetatable({}, { --split a string on a delimiter into an ordered table function stringx:split(delim) - --try to create as little garbage as possible! - --one table to contain the result, plus the split strings should be all we need - --as such we work with the bytes underlying the string, as string.find is not compiled on older luajit :) + --we try to create as little garbage as possible! + --only one table to contain the result, plus the split strings. + --so we do two passes, and work with the bytes underlying the string + --partly because string.find is not compiled on older luajit :) + local res = {} local length = self:len() -- local delim_length = delim:len() + --empty delim? split to individual characters + if delim_length == 0 then + for i = 1, length do + table.insert(res, self:sub(i, i)) + end + return res + end local delim_start = delim:byte(1) - --iterate through and collect split sites - local res = {} + --pass 1 + --collect split sites local i = 1 while i <= length do --scan for delimiter @@ -38,7 +47,8 @@ function stringx:split(delim) i = i + 1 end end - --re-iterate, collecting substrings + --pass 2 + --collect substrings i = 1 for si, j in ipairs(res) do res[si] = self:sub(i, j-1) @@ -50,4 +60,47 @@ function stringx:split(delim) return res end + +--turn input into a vaguely easy to read string +--(which is also able to be parsed by lua in many cases) +--todo: multi-line for big tables +--todo: support self-referential tables at least without crashing :) +function stringx.pretty(input) + --if the input is not a table, or it has a tostring metamethod + --then we can just use tostring + local mt = getmetatable(input) + if type(input) ~= "table" or mt and mt.__tostring then + local s = tostring(input) + --quote strings + if type(input) == "string" then + s = '"' .. s .. '"' + end + return s + end + + --otherwise, we've got to build up a table representation + --collate into member chunks + local chunks = {} + --(tracking for already-seen elements from ipairs) + local seen = {} + --sequential part first + --(in practice, pairs already does this, but the order isn't guaranteed) + for i, v in ipairs(input) do + seen[i] = true + table.insert(chunks, stringx.pretty(v)) + end + --non sequential follows + for k, v in pairs(input) do + if not seen[k] then + --encapsulate anything that's not a string + --todo: also keywords + if type(k) ~= "string" then + k = "[" .. tostring(k) .. "]" + end + table.insert(chunks, k .. " = " .. stringx.pretty(v)) + end + end + return "{" .. table.concat(chunks, ", ") .. "}" +end + return stringx diff --git a/tablex.lua b/tablex.lua index 7ec4412..74bf62a 100644 --- a/tablex.lua +++ b/tablex.lua @@ -269,44 +269,6 @@ function tablex.overlay(to, from) return to end ---turn a table into a vaguely easy to read string ---which is also able to be parsed by lua in most cases -function tablex.stringify(t) - --if the input is not a table, or it has a tostring metamethod - --just use tostring - local mt = getmetatable(t) - if type(t) ~= "table" or mt and mt.__tostring then - local s = tostring(t) - --quote strings - if type(t) == "string" then - s = '"' .. s .. '"' - end - return s - end - - --otherwise, collate into member chunks - local chunks = {} - --(tracking for already-seen elements from ipairs) - local seen = {} - --sequential part first - for i, v in ipairs(t) do - seen[i] = true - table.insert(chunks, tablex.stringify(v)) - end - --non sequential follows - for k, v in pairs(t) do - if not seen[k] then - --encapsulate anything that's not a string - --todo: also keywords - if type(k) ~= "string" then - k = "[" .. tostring(k) .. "]" - end - table.insert(chunks, k .. " = " .. tablex.stringify(v)) - end - end - return "{" .. table.concat(chunks, ", ") .. "}" -end - --faster unpacking for known-length tables up to 8 --gets around nyi in luajit --note: you can use a larger unpack than you need as the rest