This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
parent 6f050a029e
commit 776bba907c
3887 changed files with 59894 additions and 7280 deletions

View file

@ -0,0 +1,56 @@
local :no-copy set{ :num :str :ident :pair :frac :func }
(deepcopy) obj cache:
if has cache obj:
return get-from cache obj
if has no-copy type obj:
# this object is either immutable
# or a function object which can't be copied
return obj
if = :list type obj:
local :new []
set-to cache obj new
for value in reversed copy obj:
push-to new (deepcopy) value cache
return new
else:
local :new {}
set-to cache obj new
for key in keys obj:
set-to new (deepcopy) key cache (deepcopy) get-from obj key cache
return new
deepcopy obj:
(deepcopy) obj {}
#example usage:
#a reasonably complicated object:
set :A { :foo [ "bar" ] [] [ & 1 2 & 3 4 ] }
set :B deepcopy A
. A
#prints: { [ ] [ & 1 2 & 3 4 ] :foo [ "bar" ] }
. B
#prints: { [ ] [ & 1 2 & 3 4 ] :foo [ "bar" ] }
push-to get-from B :foo "HODOR"
. A
#prints: { [ ] [ & 1 2 & 3 4 ] :foo [ "bar" ] }
. B
#prints: { [ ] [ & 1 2 & 3 4 ] :foo [ "bar" "HODOR" ] }
#it works with cycles:
set :C push-through dup []
set :D deepcopy C
. C
#prints: [ [ [ [ [...] ] ] ] ]
. D
#prints: [ [ [ [ [...] ] ] ] ]
push-to C 7
. C
#prints: [ [ [ [ [...] 7 ] 7 ] 7 ] 7 ]
. D
#prints: [ [ [ [ [...] ] ] ] ]