2017-09-27 20:11:21 +00:00
|
|
|
children(x) = ()
|
|
|
|
mapchildren(f, x) = x
|
|
|
|
|
|
|
|
function treelike(T, fs = fieldnames(T))
|
|
|
|
@eval begin
|
|
|
|
children(x::$T) = ($([:(x.$f) for f in fs]...),)
|
|
|
|
mapchildren(f, x::$T) = $T(f.(children(x))...)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-09-27 20:58:34 +00:00
|
|
|
# TODO: prewalk/postwalk with correct caching
|
|
|
|
# This is only correct in general for idempotent functions
|
|
|
|
|
|
|
|
mapparams(f, x::AbstractArray) = f(x)
|
|
|
|
mapparams(f, x) = mapchildren(x -> mapparams(f, x), x)
|
2017-09-27 20:11:21 +00:00
|
|
|
|
2017-09-27 20:58:34 +00:00
|
|
|
forparams(f, x) = (mapparams(x -> (f(x); x), x); return)
|
|
|
|
|
|
|
|
using DataFlow: OSet
|
2017-09-27 20:11:21 +00:00
|
|
|
|
|
|
|
function params(m)
|
2017-10-10 11:16:32 +00:00
|
|
|
ps, seen = [], OSet()
|
|
|
|
forparams(p -> p ∉ seen && (push!(ps, p); push!(seen, p)), m)
|
|
|
|
return ps
|
2017-09-27 20:11:21 +00:00
|
|
|
end
|