From b615cb5c8e638cffe77bbe5cb86c9362e2b2fc18 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 3 Oct 2018 16:14:17 -0700 Subject: [PATCH] Fixed up some edge cases with as_lua_id and from_lua_id that were producing bad results. --- string2.lua | 25 +++++++++++++++++++++---- string2.moon | 13 +++++++------ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/string2.lua b/string2.lua index 1f15fed..ae0e49d 100644 --- a/string2.lua +++ b/string2.lua @@ -143,8 +143,6 @@ local string2 = { return '"' .. escaped .. '"' end, as_lua_id = function(str) - local orig = str - str = gsub(str, "^ *$", "%1 ") str = gsub(str, "x([0-9A-F][0-9A-F])", "x78%1") str = gsub(str, "%W", function(c) if c == ' ' then @@ -159,18 +157,37 @@ local string2 = { return str end, from_lua_id = function(str) - if not (is_lua_id("^_+(.*)$")) then + if not (is_lua_id(str:match("^_*(.*)$"))) then str = str:sub(2, -1) end str = gsub(str, "_", " ") str = gsub(str, "x([0-9A-F][0-9A-F])", function(hex) return char(tonumber(hex, 16)) end) - str = gsub(str, "^ ([ ]*)$", "%1") return str end } for k, v in pairs(string) do string2[k] = string2[k] or v end +local _list_0 = { + "", + "_", + " ", + "return", + "asdf", + "one two", + "one_two", + "Hex2Dec", + "He-ec", + "\3" +} +for _index_0 = 1, #_list_0 do + local test = _list_0[_index_0] + local lua_id = string2.as_lua_id(test) + assert(is_lua_id(lua_id), "failed to convert '" .. tostring(test) .. "' to a valid Lua identifier (got '" .. tostring(lua_id) .. "')") + local roundtrip = string2.from_lua_id(lua_id) + assert(roundtrip == test, "Failed lua_id roundtrip: '" .. tostring(test) .. "' -> " .. tostring(lua_id) .. " -> " .. tostring(roundtrip)) +end +assert(string2.as_lua_id('') == '_') return string2 diff --git a/string2.moon b/string2.moon index 140c586..8d2f3f9 100644 --- a/string2.moon +++ b/string2.moon @@ -67,10 +67,6 @@ string2 = { -- but not idempotent. In logic terms: (x != y) => (as_lua_id(x) != as_lua_id(y)), -- but not (as_lua_id(a) == b) => (as_lua_id(b) == b). as_lua_id: (str)-> - orig = str - -- Empty strings are not valid lua identifiers, so treat them like " ", - -- and treat " " as " ", etc. to preserve injectivity. - str = gsub str, "^ *$", "%1 " -- Escape 'x' (\x78) when it precedes something that looks like an uppercase hex sequence. -- This way, all Lua IDs can be unambiguously reverse-engineered, but normal usage -- of 'x' won't produce ugly Lua IDs. @@ -88,13 +84,18 @@ string2 = { -- from_lua_id(as_lua_id(str)) == str, but behavior is unspecified for inputs that -- did not come from as_lua_id() from_lua_id: (str)-> - unless is_lua_id("^_+(.*)$") + unless is_lua_id(str\match("^_*(.*)$")) str = str\sub(2,-1) str = gsub(str, "_", " ") str = gsub(str, "x([0-9A-F][0-9A-F])", (hex)-> char(tonumber(hex, 16))) - str = gsub(str, "^ ([ ]*)$", "%1") return str } for k,v in pairs(string) do string2[k] or= v +for test in *{"", "_", " ", "return", "asdf", "one two", "one_two", "Hex2Dec", "He-ec", "\3"} + lua_id = string2.as_lua_id(test) + assert is_lua_id(lua_id), "failed to convert '#{test}' to a valid Lua identifier (got '#{lua_id}')" + roundtrip = string2.from_lua_id(lua_id) + assert roundtrip == test, "Failed lua_id roundtrip: '#{test}' -> #{lua_id} -> #{roundtrip}" + return string2