From 1e11ee7e61f72864c2389b262f35e0682725a6dc Mon Sep 17 00:00:00 2001 From: Peter Lundberg Date: Sat, 5 Nov 2022 01:56:58 +0100 Subject: [PATCH 1/3] Refactor Util to make it more consistent --- FormatBeautiful.lua | 2 +- FormatIdentity.lua | 8 ++++---- FormatMini.lua | 2 +- ParseLua.lua | 2 +- Util.lua | 28 +++++++++++----------------- tests/test_identity.lua | 18 +++++++++--------- 6 files changed, 27 insertions(+), 33 deletions(-) diff --git a/FormatBeautiful.lua b/FormatBeautiful.lua index 1262202..8aec1ee 100644 --- a/FormatBeautiful.lua +++ b/FormatBeautiful.lua @@ -7,7 +7,7 @@ local parser = require"ParseLua" local ParseLua = parser.ParseLua local util = require'Util' -local lookupify = util.lookupify +local lookupify = util.Lookupify local LowerChars = lookupify{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', diff --git a/FormatIdentity.lua b/FormatIdentity.lua index 8cbb59c..7138f44 100644 --- a/FormatIdentity.lua +++ b/FormatIdentity.lua @@ -4,7 +4,7 @@ local util = require'Util' local function debug_printf(...) --[[ - util.printf(...) + util.Printf(...) --]] end @@ -26,7 +26,7 @@ local function Format_Identity(ast) appendStr = function(self, str) table.insert(self.rope, str) - local lines = util.splitLines(str) + local lines = util.SplitLines(str) if #lines == 1 then self.char = self.char + #str else @@ -41,7 +41,7 @@ local function Format_Identity(ast) --[*[ --debug_printf("appendToken(%q)", token.Data) local data = token.Data - local lines = util.splitLines(data) + local lines = util.SplitLines(data) while self.line + #lines < token.Line do print("Inserting extra line") self.str = self.str .. '\n' @@ -100,7 +100,7 @@ local function Format_Identity(ast) local function appendComma(mandatory, seperators) if true then seperators = seperators or { "," } - seperators = util.lookupify( seperators ) + seperators = util.Lookupify( seperators ) if not mandatory and not seperators[peek()] then return end diff --git a/FormatMini.lua b/FormatMini.lua index 4d04602..4212626 100644 --- a/FormatMini.lua +++ b/FormatMini.lua @@ -2,7 +2,7 @@ local parser = require'ParseLua' local ParseLua = parser.ParseLua local util = require'Util' -local lookupify = util.lookupify +local lookupify = util.Lookupify -- -- FormatMini.lua diff --git a/ParseLua.lua b/ParseLua.lua index 6af7ee4..9edb118 100644 --- a/ParseLua.lua +++ b/ParseLua.lua @@ -11,7 +11,7 @@ require'strict' local util = require'Util' -local lookupify = util.lookupify +local lookupify = util.Lookupify local WhiteChars = lookupify{' ', '\n', '\t', '\r'} local EscapeLookup = {['\r'] = '\\r', ['\n'] = '\\n', ['\t'] = '\\t', ['"'] = '\\"', ["'"] = "\\'"} diff --git a/Util.lua b/Util.lua index b04f894..417df2d 100644 --- a/Util.lua +++ b/Util.lua @@ -4,8 +4,9 @@ -- -- Provides some common utilities shared throughout the project. -- +local Util = {} -local function lookupify(tb) +function Util.Lookupify(tb) for _, v in pairs(tb) do tb[v] = true end @@ -13,19 +14,19 @@ local function lookupify(tb) end -local function CountTable(tb) +function Util.CountTable(tb) local c = 0 for _ in pairs(tb) do c = c + 1 end return c end -local function PrintTable(tb, atIndent) +function Util.PrintTable(tb, atIndent) if tb.Print then return tb.Print() end atIndent = atIndent or 0 - local useNewlines = (CountTable(tb) > 1) + local useNewlines = (Util.CountTable(tb) > 1) local baseIndent = string.rep(' ', atIndent+1) local out = "{"..(useNewlines and '\n' or '') for k, v in pairs(tb) do @@ -34,7 +35,7 @@ local function PrintTable(tb, atIndent) out = out..(useNewlines and baseIndent or '') if type(k) == 'number' then --nothing to do - elseif type(k) == 'string' and k:match("^[A-Za-z_][A-Za-z0-9_]*$") then + elseif type(k) == 'string' and k:match("^[A-Za-z_][A-Za-z0-9_]*$") then out = out..k.." = " elseif type(k) == 'string' then out = out.."[\""..k.."\"] = " @@ -46,7 +47,7 @@ local function PrintTable(tb, atIndent) elseif type(v) == 'number' then out = out..v elseif type(v) == 'table' then - out = out..PrintTable(v, atIndent+(useNewlines and 1 or 0)) + out = out..Util.PrintTable(v, atIndent+(useNewlines and 1 or 0)) else out = out..tostring(v) end @@ -63,10 +64,10 @@ local function PrintTable(tb, atIndent) end -local function splitLines(str) +function Util.SplitLines(str) if str:match("\n") then local lines = {} - for line in str:gmatch("[^\n]*") do + for line in str:gmatch("[^\n]*") do table.insert(lines, line) end assert(#lines > 0) @@ -77,15 +78,8 @@ local function splitLines(str) end -local function printf(fmt, ...) +function Util.Printf(fmt, ...) return print(string.format(fmt, ...)) end - -return { - PrintTable = PrintTable, - CountTable = CountTable, - lookupify = lookupify, - splitLines = splitLines, - printf = printf, -} +return Util diff --git a/tests/test_identity.lua b/tests/test_identity.lua index 6658cd4..9e3e8df 100644 --- a/tests/test_identity.lua +++ b/tests/test_identity.lua @@ -71,14 +71,14 @@ function reconstructText(text) else print("Reconstruction failed") - local inputLines = util.splitLines(text) - local outputLines = util.splitLines(reconstructed) + local inputLines = util.SplitLines(text) + local outputLines = util.SplitLines(reconstructed) local n = math.max(#inputLines, #outputLines) for i = 1,n do if inputLines[i] ~= outputLines[i] then - util.printf("ERROR on line %i", i) - util.printf("Input: %q", inputLines[i]) - util.printf("Output: %q", outputLines[i]) + util.Printf("ERROR on line %i", i) + util.Printf("Input: %q", inputLines[i]) + util.Printf("Output: %q", outputLines[i]) break end end @@ -111,7 +111,7 @@ local line_nr = 0 for text in io.lines("test_lines.txt") do line_nr = line_nr + 1 if not text:find("FAIL") then - --util.printf("\nText: %q", text) + --util.Printf("\nText: %q", text) reconstructText(text) end end @@ -119,6 +119,6 @@ end reconstructText('function a(p,q,r,...) end') -util.printf("Lex time: %f s", g_lexTime) -util.printf("Parse time: %f s", g_parseTime) -util.printf("Format time: %f s", g_reconstructTime) +util.Printf("Lex time: %f s", g_lexTime) +util.Printf("Parse time: %f s", g_parseTime) +util.Printf("Format time: %f s", g_reconstructTime) From 7645e3df8f0d91015ce282d665295a2efdb2da3b Mon Sep 17 00:00:00 2001 From: Peter Lundberg Date: Sat, 5 Nov 2022 02:14:24 +0100 Subject: [PATCH 2/3] Refactor Scope to make it more consistent --- Scope.lua | 372 +++++++++++++++++++++++++++--------------------------- 1 file changed, 186 insertions(+), 186 deletions(-) diff --git a/Scope.lua b/Scope.lua index c4b8444..a5b7955 100644 --- a/Scope.lua +++ b/Scope.lua @@ -1,195 +1,195 @@ -local Scope = { - new = function(self, parent) - local s = { - Parent = parent, - Locals = { }, - Globals = { }, - oldLocalNamesMap = { }, - oldGlobalNamesMap = { }, - Children = { }, - } - - if parent then - table.insert(parent.Children, s) - end - - return setmetatable(s, { __index = self }) - end, - - AddLocal = function(self, v) - table.insert(self.Locals, v) - end, - - AddGlobal = function(self, v) - table.insert(self.Globals, v) - end, - - CreateLocal = function(self, name) - local v - v = self:GetLocal(name) - if v then return v end - v = { } - v.Scope = self - v.Name = name - v.IsGlobal = false - v.CanRename = true - v.References = 1 - self:AddLocal(v) - return v - end, - - GetLocal = function(self, name) - for k, var in pairs(self.Locals) do - if var.Name == name then return var end - end - - if self.Parent then - return self.Parent:GetLocal(name) - end - end, - - GetOldLocal = function(self, name) - if self.oldLocalNamesMap[name] then - return self.oldLocalNamesMap[name] - end - return self:GetLocal(name) - end, - - mapLocal = function(self, name, var) - self.oldLocalNamesMap[name] = var - end, - - GetOldGlobal = function(self, name) - if self.oldGlobalNamesMap[name] then - return self.oldGlobalNamesMap[name] - end - return self:GetGlobal(name) - end, - - mapGlobal = function(self, name, var) - self.oldGlobalNamesMap[name] = var - end, - - GetOldVariable = function(self, name) - return self:GetOldLocal(name) or self:GetOldGlobal(name) - end, - - RenameLocal = function(self, oldName, newName) - oldName = type(oldName) == 'string' and oldName or oldName.Name - local found = false - local var = self:GetLocal(oldName) - if var then - var.Name = newName - self:mapLocal(oldName, var) - found = true - end - if not found and self.Parent then - self.Parent:RenameLocal(oldName, newName) - end - end, - - RenameGlobal = function(self, oldName, newName) - oldName = type(oldName) == 'string' and oldName or oldName.Name - local found = false - local var = self:GetGlobal(oldName) - if var then - var.Name = newName - self:mapGlobal(oldName, var) - found = true - end - if not found and self.Parent then - self.Parent:RenameGlobal(oldName, newName) - end - end, - - RenameVariable = function(self, oldName, newName) - oldName = type(oldName) == 'string' and oldName or oldName.Name - if self:GetLocal(oldName) then - self:RenameLocal(oldName, newName) - else - self:RenameGlobal(oldName, newName) +local Scope = {} + +function Scope.new(self, parent) + local s = { + Parent = parent, + Locals = { }, + Globals = { }, + oldLocalNamesMap = { }, + oldGlobalNamesMap = { }, + Children = { }, + } + + if parent then + table.insert(parent.Children, s) + end + + return setmetatable(s, { __index = self }) +end + +function Scope.AddLocal(self, v) + table.insert(self.Locals, v) +end + +function Scope.AddGlobal(self, v) + table.insert(self.Globals, v) +end + +function Scope.CreateLocal(self, name) + local v + v = self:GetLocal(name) + if v then return v end + v = { } + v.Scope = self + v.Name = name + v.IsGlobal = false + v.CanRename = true + v.References = 1 + self:AddLocal(v) + return v +end + +function Scope.GetLocal(self, name) + for k, var in pairs(self.Locals) do + if var.Name == name then return var end + end + + if self.Parent then + return self.Parent:GetLocal(name) + end +end + +function Scope.GetOldLocal(self, name) + if self.oldLocalNamesMap[name] then + return self.oldLocalNamesMap[name] + end + return self:GetLocal(name) +end + +function Scope.MapLocal(self, name, var) + self.oldLocalNamesMap[name] = var +end + +function Scope.GetOldGlobal(self, name) + if self.oldGlobalNamesMap[name] then + return self.oldGlobalNamesMap[name] + end + return self:GetGlobal(name) +end + +function Scope.MapGlobal(self, name, var) + self.oldGlobalNamesMap[name] = var +end + +function Scope.GetOldVariable(self, name) + return self:GetOldLocal(name) or self:GetOldGlobal(name) +end + +function Scope.RenameLocal(self, oldName, newName) + oldName = type(oldName) == 'string' and oldName or oldName.Name + local found = false + local var = self:GetLocal(oldName) + if var then + var.Name = newName + self:MapLocal(oldName, var) + found = true + end + if not found and self.Parent then + self.Parent:RenameLocal(oldName, newName) + end +end + +function Scope.RenameGlobal(self, oldName, newName) + oldName = type(oldName) == 'string' and oldName or oldName.Name + local found = false + local var = self:GetGlobal(oldName) + if var then + var.Name = newName + self:MapGlobal(oldName, var) + found = true + end + if not found and self.Parent then + self.Parent:RenameGlobal(oldName, newName) + end +end + +function Scope.RenameVariable(self, oldName, newName) + oldName = type(oldName) == 'string' and oldName or oldName.Name + if self:GetLocal(oldName) then + self:RenameLocal(oldName, newName) + else + self:RenameGlobal(oldName, newName) + end +end + +function Scope.GetAllVariables(self) + local ret = self:GetVars(true) -- down + for k, v in pairs(self:GetVars(false)) do -- up + table.insert(ret, v) + end + return ret +end + +function Scope.GetVars(self, top) + local ret = { } + if top then + for k, v in pairs(self.Children) do + for k2, v2 in pairs(v:GetVars(true)) do + table.insert(ret, v2) + end end - end, - - GetAllVariables = function(self) - local ret = self:getVars(true) -- down - for k, v in pairs(self:getVars(false)) do -- up + else + for k, v in pairs(self.Locals) do table.insert(ret, v) end - return ret - end, - - getVars = function(self, top) - local ret = { } - if top then - for k, v in pairs(self.Children) do - for k2, v2 in pairs(v:getVars(true)) do - table.insert(ret, v2) - end - end - else - for k, v in pairs(self.Locals) do - table.insert(ret, v) - end - for k, v in pairs(self.Globals) do - table.insert(ret, v) - end - if self.Parent then - for k, v in pairs(self.Parent:getVars(false)) do - table.insert(ret, v) - end - end - end - return ret - end, - - CreateGlobal = function(self, name) - local v - v = self:GetGlobal(name) - if v then return v end - v = { } - v.Scope = self - v.Name = name - v.IsGlobal = true - v.CanRename = true - v.References = 1 - self:AddGlobal(v) - return v - end, - - GetGlobal = function(self, name) for k, v in pairs(self.Globals) do - if v.Name == name then return v end + table.insert(ret, v) end - if self.Parent then - return self.Parent:GetGlobal(name) - end - end, - - GetVariable = function(self, name) - return self:GetLocal(name) or self:GetGlobal(name) - end, - - ObfuscateLocals = function(self, recommendedMaxLength, validNameChars) - recommendedMaxLength = recommendedMaxLength or 7 - local chars = validNameChars or "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_" - local chars2 = validNameChars or "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_1234567890" - for _, var in pairs(self.Locals) do - local id = "" - local tries = 0 - repeat - local n = math.random(1, #chars) - id = id .. chars:sub(n, n) - for i = 1, math.random(0, tries > 5 and 30 or recommendedMaxLength) do - local n = math.random(1, #chars2) - id = id .. chars2:sub(n, n) - end - tries = tries + 1 - until not self:GetVariable(id) - self:RenameLocal(var.Name, id) + for k, v in pairs(self.Parent:GetVars(false)) do + table.insert(ret, v) + end end - end, -} + end + return ret +end + +function Scope.CreateGlobal(self, name) + local v + v = self:GetGlobal(name) + if v then return v end + v = { } + v.Scope = self + v.Name = name + v.IsGlobal = true + v.CanRename = true + v.References = 1 + self:AddGlobal(v) + return v +end + +function Scope.GetGlobal(self, name) + for k, v in pairs(self.Globals) do + if v.Name == name then return v end + end + + if self.Parent then + return self.Parent:GetGlobal(name) + end +end + +function Scope.GetVariable(self, name) + return self:GetLocal(name) or self:GetGlobal(name) +end + +function Scope.ObfuscateLocals(self, recommendedMaxLength, validNameChars) + recommendedMaxLength = recommendedMaxLength or 7 + local chars = validNameChars or "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_" + local chars2 = validNameChars or "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_1234567890" + for _, var in pairs(self.Locals) do + local id = "" + local tries = 0 + repeat + local n = math.random(1, #chars) + id = id .. chars:sub(n, n) + for i = 1, math.random(0, tries > 5 and 30 or recommendedMaxLength) do + local n = math.random(1, #chars2) + id = id .. chars2:sub(n, n) + end + tries = tries + 1 + until not self:GetVariable(id) + self:RenameLocal(var.Name, id) + end +end return Scope From ec6d111a996be10d2d1438caf9444854ba2de9fc Mon Sep 17 00:00:00 2001 From: Peter Lundberg Date: Sat, 5 Nov 2022 02:23:04 +0100 Subject: [PATCH 3/3] Remove unused require and variables --- CommandLineBeautify.lua | 2 -- CommandLineMinify.lua | 2 -- FormatBeautiful.lua | 2 -- FormatIdentity.lua | 20 ++++++++++---------- FormatMini.lua | 9 +++------ ParseLua.lua | 2 -- 6 files changed, 13 insertions(+), 24 deletions(-) diff --git a/CommandLineBeautify.lua b/CommandLineBeautify.lua index 12b0ced..465a512 100644 --- a/CommandLineBeautify.lua +++ b/CommandLineBeautify.lua @@ -4,11 +4,9 @@ -- A command line utility for beautifying lua source code using the beautifier. -- -local util = require'Util' local Parser = require'ParseLua' local Format_Beautify = require'FormatBeautiful' local ParseLua = Parser.ParseLua -local PrintTable = util.PrintTable local function splitFilename(name) --table.foreach(arg, print) diff --git a/CommandLineMinify.lua b/CommandLineMinify.lua index c239195..9dc87d3 100644 --- a/CommandLineMinify.lua +++ b/CommandLineMinify.lua @@ -5,11 +5,9 @@ -- A command line utility for minifying lua source code using the minifier. -- -local util = require'Util' local Parser = require'ParseLua' local Format_Mini = require'FormatMini' local ParseLua = Parser.ParseLua -local PrintTable = util.PrintTable local function splitFilename(name) table.foreach(arg, print) diff --git a/FormatBeautiful.lua b/FormatBeautiful.lua index 8aec1ee..ad26cf6 100644 --- a/FormatBeautiful.lua +++ b/FormatBeautiful.lua @@ -4,8 +4,6 @@ -- Returns a beautified version of the code, including comments -- -local parser = require"ParseLua" -local ParseLua = parser.ParseLua local util = require'Util' local lookupify = util.Lookupify diff --git a/FormatIdentity.lua b/FormatIdentity.lua index 7138f44..fd1e923 100644 --- a/FormatIdentity.lua +++ b/FormatIdentity.lua @@ -1,13 +1,3 @@ -require'strict' -require'ParseLua' -local util = require'Util' - -local function debug_printf(...) - --[[ - util.Printf(...) - --]] -end - -- -- FormatIdentity.lua -- @@ -17,6 +7,16 @@ end -- an AST. -- +require'strict' + +local util = require'Util' + +local function debug_printf(...) + --[[ + util.Printf(...) + --]] +end + local function Format_Identity(ast) local out = { rope = {}, -- List of strings diff --git a/FormatMini.lua b/FormatMini.lua index 4212626..3c87a8b 100644 --- a/FormatMini.lua +++ b/FormatMini.lua @@ -1,9 +1,3 @@ - -local parser = require'ParseLua' -local ParseLua = parser.ParseLua -local util = require'Util' -local lookupify = util.Lookupify - -- -- FormatMini.lua -- @@ -12,6 +6,9 @@ local lookupify = util.Lookupify -- - All local variables are renamed -- +local util = require'Util' +local lookupify = util.Lookupify + local LowerChars = lookupify{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'} diff --git a/ParseLua.lua b/ParseLua.lua index 9edb118..452f143 100644 --- a/ParseLua.lua +++ b/ParseLua.lua @@ -13,8 +13,6 @@ require'strict' local util = require'Util' local lookupify = util.Lookupify -local WhiteChars = lookupify{' ', '\n', '\t', '\r'} -local EscapeLookup = {['\r'] = '\\r', ['\n'] = '\\n', ['\t'] = '\\t', ['"'] = '\\"', ["'"] = "\\'"} local LowerChars = lookupify{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}