signature_size = {
a = 4,
b = 2,
c = 5,
d = 3,
e = 2,
f = 3,
g = 6,
h = 1
}
--these table keys are automatically strings
tail_calls_whom = {
a = {"b"},
b = {"a", "c", "e"},
c = {},
d = {"e"},
e = {"d"},
f = {"g", "h"},
g = {"f", "h"},
h = {"f", "g"}
}
--lua lacks a table copy so I'll need this
function copy(t)
s = {}
for k, v in pairs(t) do s[k] = v end
return s
end
function find_max_sizes()
inverse_table = {}
descending_size = {}
max_sizes = copy(signature_size)
for func, targets in pairs(tail_calls_whom) do
table.insert(descending_size, func)
for _, becomee in ipairs(targets) do
if not inverse_table[becomee] then
inverse_table[becomee] = {}
end
table.insert(inverse_table[becomee], func)
end
end
table.sort(descending_size, function(f, g)
return signature_size[f] > signature_size[g]
end)
repeat
--remove the largest function
f = table.remove(descending_size, 1)
for _, caller in ipairs(inverse_table[f]) do
--annotate each function that calls it
max_sizes[caller] = math.max(max_sizes[f], max_sizes[caller])
--move that function to the front of the descending size list
for k, v in ipairs(descending_size) do
if v == caller then
table.remove(descending_size, k)
table.insert(descending_size, 1, caller)
break
end
end
end
until #descending_size == 0
return max_sizes
end
for k, v in pairs(find_max_sizes()) do
print(k, ":", v)
end