Fix handling of cross-referencing tables

This commit is contained in:
Lars Mueller 2021-07-07 19:14:56 +02:00
parent e49cbdf9ff
commit 27df865b6e
2 changed files with 25 additions and 30 deletions

@ -40,7 +40,7 @@ function write(value, write)
write";" write";"
references[object] = ref references[object] = ref
if type_ == "table" then if type_ == "table" then
to_fill[object] = true to_fill[object] = ref
end end
increment_reference(1) increment_reference(1)
end end
@ -67,25 +67,7 @@ function write(value, write)
local ref = references[value] local ref = references[value]
if ref then if ref then
-- Referenced -- Referenced
if not to_fill[value] then return write(ref)
return write(ref)
end
-- Fill table
to_fill[value] = false
for k, v in pairs(value) do
write(ref)
if is_short_key(k) then
write"."
write(k)
else
write"["
dump(k)
write"]"
end
write"="
dump(v)
write";"
end
elseif type_ == "string" then elseif type_ == "string" then
return write(quote(value)) return write(quote(value))
elseif type_ == "table" then elseif type_ == "table" then
@ -117,17 +99,24 @@ function write(value, write)
error("unsupported type: " .. type_) error("unsupported type: " .. type_)
end end
end end
local fill_root = to_fill[value] for table, ref in pairs(to_fill) do
if fill_root then for k, v in pairs(table) do
-- Root table is circular, must return by named reference write(ref)
dump(value) if is_short_key(k) then
write"return " write"."
write(references[value]) write(k)
else else
-- Root table is not circular, can directly start writing write"["
write"return " dump(k)
dump(value) write"]"
end
write"="
dump(v)
write";"
end
end end
write"return "
dump(value)
end end
function write_file(value, file) function write_file(value, file)

@ -195,6 +195,12 @@ local function serializer_test(assert_preserves)
mixed.vec2 = modlib.table.copy(mixed.vec) mixed.vec2 = modlib.table.copy(mixed.vec)
mixed.blah = "blah" mixed.blah = "blah"
assert_preserves(mixed) assert_preserves(mixed)
local a, b, c = {}, {}, {}
a[a] = a; a[b] = b; a[c] = c;
b[a] = a; b[b] = b; b[c] = c;
c[a] = a; c[b] = b; c[c] = c;
a.a = {"a", a = a}
assert_preserves(a)
end end
-- bluon -- bluon