diff options
Diffstat (limited to 'src/ast_opts.lua')
| -rw-r--r-- | src/ast_opts.lua | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/ast_opts.lua b/src/ast_opts.lua new file mode 100644 index 0000000..de49932 --- /dev/null +++ b/src/ast_opts.lua @@ -0,0 +1,100 @@ +--[[ + Optimizatoins for abstract syntax trees +]] +local msg = io.write +--A debugging function, a replacement for glua PrintTable +local function printtable(tbl, tabset) + tabset = tabset or 0 + for k,v in pairs(tbl) do + for i = 0,tabset do msg("\t") end + msg(k .. ":") + if type(v) == "table" then + msg("\n") + printtable(v, tabset + 1) + else + msg(tostring(v) .. "\n") + end + end +end + +--A function to see if two ast's are equal-ish (does not compare position) +local function deepcompare(tbl1, tbl2) + if type(tbl1) ~= type(tbl2) then return false end + for k,v in pairs(tbl1) do + print("Checking ", k, " from tbl1") + if k == "pos" then goto cont end + if type(v) == "table" then + print("It is a table! going deeper") + if not deepcompare(v,tbl2[k]) then + return false + end + else + print("Checking ", v , " against ", tbl2[k]) + if v ~= tbl2[k] then + return false + end + end + ::cont:: + end + return true +end + +local opts = {} + +--Optimization 1 +--Folds things with an operator when the fold results in a smaller string +local foldables = { + ["add"] = function(a,b) return a + b end, + ["mul"] = function(a,b) return a * b end, + ["mod"] = function(a,b) return a % b end, + ["sub"] = function(a,b) return a - b end, + --["div"] = function(a,b) return a / b end, division has the chance to give us really long strings! +} +opts[1] = function(ast) + if ast.tag ~= "Op" then return false end + local opname = ast[1] + local func = foldables[opname] + if ast[3] ~= nil and func ~= nil and ast[2].tag == "Number" and ast[3].tag == "Number" then + ast.tag = "Number" + ast[1] = func(ast[2][1],ast[3][1]) + for i = 2,#ast do + ast[i] = nil + end + return true + end + return false +end + +--Optimization 2 +--Find places where we can replace calls with invokes. +opts[2] = function(ast) + if ast.tag == "Call" and ast.pos == 160 then + print("Ast:") + printtable(ast) + print("ast[1][1]") + printtable(ast[1][1]) + print("ast[2]") + printtable(ast[2]) + local dcr = deepcompare(ast[1][1],ast[2]) + print("Deepcompare:",dcr) + --error("stopping") + end + if ast.tag == "Call" and deepcompare(ast[1][1][1], ast[2][1]) then + print("Before correcting for invoke, ast is") + printtable(ast) + for i = 2,#ast[2] do + ast[i] = ast[i+1] + end + ast.tag = "Invoke" + ast[2] = ast[1][2] + ast[1] = ast[1][1] + print("After correcting for invoke, ast is") + printtable(ast) + + --error("Call that should be invoke detected") + return true + end + +end + +return opts |
