1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-27 16:49:31 +00:00

Proper checkpointing of mutable values

This commit is contained in:
Étienne Fildadut 2021-12-06 18:34:58 +01:00
parent 801df67461
commit 04c6683de8
14 changed files with 243 additions and 23 deletions

View file

@ -1,6 +1,20 @@
--- replace values recursively in table t according to to_replace ([old table] = new table)
local function replace_in_table(t, to_replace, already_replaced)
already_replaced = already_replaced or {}
already_replaced[t] = true
for k, v in pairs(t) do
if to_replace[v] then
t[k] = to_replace[v]
elseif type(v) == "table" and not already_replaced[v] then
replace_in_table(v, to_replace, already_replaced)
end
end
end
local common
common = {
--- recursively copy a table, handle cyclic references, no metatable
--- recursively copy a table, handle cyclic references, no metatable, don't copy keys
-- cache is table with copied tables [original table] = copied value, will use temporary table is omitted
copy = function(t, cache)
if type(t) == "table" then
cache = cache or {}
@ -17,6 +31,33 @@ common = {
else
return t
end
end,
--- given a table t from which some copy was issued, the copy cache, and a list of tables from the copied version,
-- put theses copied tables in t in place of their original values, preserving references to non-modified values
replace_with_copied_values = function(t, cache, copied_to_replace)
-- reverse copy cache
local ehcac = {}
for k, v in pairs(cache) do ehcac[v] = k end
-- build table of [original table] = replacement copied table
local to_replace = {}
for _, v in ipairs(copied_to_replace) do
local original = ehcac[v]
if original then -- table doesn't have an original value if it's a new table...
to_replace[original] = v
end
end
-- fix references to not-modified tables in modified values
local not_modified = {}
for original, modified in pairs(cache) do
if not to_replace[original] then
not_modified[modified] = original
end
end
for _, m in ipairs(copied_to_replace) do
replace_in_table(m, not_modified)
end
-- replace
replace_in_table(t, to_replace)
end
}
return common