@@ -89,7 +89,6 @@ for N in (:Node, :GraphNode)
8989 end
9090end
9191
92- # ! format: off
9392"""
9493 Node{T,D} <: AbstractExpressionNode{T,D}
9594
@@ -135,7 +134,6 @@ in the `allocator` keyword argument.
135134"""
136135Node
137136
138-
139137"""
140138 GraphNode{T,D} <: AbstractExpressionNode{T,D}
141139
@@ -184,21 +182,33 @@ function poison_node(n::AbstractNode)
184182 return n
185183end
186184
185+ """
186+ get_children(node::AbstractNode)
187+
188+ Return the raw `.children` tuple of a node. Some of these
189+ children may be "poisoned" nodes which you should not access,
190+ as they will trigger infinite recursion errors. Ensure to
191+ only access children only up to the `.degree` of the node.
192+ """
187193@inline function get_children (node:: AbstractNode )
188194 return getfield (node, :children )
189195end
190196
191197"""
192- get_children(node::AbstractNode)
198+ get_children(node::AbstractNode, n::Integer )
193199 get_children(node::AbstractNode, ::Val{n})
194200
195- Return the children tuple of a node. The first form returns the complete children tuple as stored.
196- The second form returns a tuple of exactly `n` children, useful for type stability when the
197- number of children needed is known at compile time.
201+ Return a tuple of exactly `n` children of the node. You should
202+ use the `.degree` field of a node to determine the number of children
203+ to return. Typically this is done within a `Base.Cartesian.@nif` statement
204+ for total type stability.
198205"""
199- @inline function get_children (node:: AbstractNode , :: Val{n} ) where {n}
206+ @inline function get_children (node:: AbstractNode{D} , n:: Integer ) where {D}
207+ return get_children (node, Val (n))
208+ end
209+ @inline function get_children (node:: AbstractNode{D} , :: Val{n} ) where {D,n}
200210 cs = get_children (node)
201- return ntuple (i -> cs[i], Val (Int (n) ))
211+ return ntuple (i -> cs[i], Val (n ))
202212end
203213
204214"""
207217Return the `i`-th child of a node (1-indexed).
208218"""
209219@inline function get_child (n:: AbstractNode{D} , i:: Int ) where {D}
210- return get_children (n)[i]
220+ return get_children (n, i)
211221end
212222
213223"""
227237Replace all children of a node with the given tuple. If fewer children are
228238provided than the node's maximum degree, remaining slots are filled with poison nodes.
229239"""
230- @inline function set_children! (n:: AbstractNode{D} , children:: Union{Tuple,AbstractVector{<:AbstractNode{D}}} ) where {D}
240+ @inline function set_children! (
241+ n:: AbstractNode{D} , children:: Union{Tuple,AbstractVector{<:AbstractNode{D}}}
242+ ) where {D}
231243 D2 = length (children)
232244 if D === D2
233245 n. children = children
@@ -243,37 +255,39 @@ provided than the node's maximum degree, remaining slots are filled with poison
243255end
244256
245257macro make_accessors (node_type)
246- esc (quote
247- @inline function Base. getproperty (n:: $node_type , k:: Symbol )
248- if k == :l
249- # TODO : Should a depwarn be raised here? Or too slow?
250- return $ (get_child)(n, 1 )
251- elseif k == :r
252- return $ (get_child)(n, 2 )
253- else
254- return getfield (n, k)
255- end
256- end
257- @inline function Base. setproperty! (n:: $node_type , k:: Symbol , v)
258- if k == :l
259- if isdefined (n, :children )
260- $ (set_child!)(n, v, 1 )
258+ esc (
259+ quote
260+ @inline function Base. getproperty (n:: $node_type , k:: Symbol )
261+ if k == :l
262+ # TODO : Should a depwarn be raised here? Or too slow?
263+ return $ (get_child)(n, 1 )
264+ elseif k == :r
265+ return $ (get_child)(n, 2 )
261266 else
262- $ (set_children!)(n, (v,))
263- v
267+ return getfield (n, k)
264268 end
265- elseif k == :r
266- $ (set_child!)(n, v, 2 )
267- else
268- T = fieldtype (typeof (n), k)
269- if v isa T
270- setfield! (n, k, v)
269+ end
270+ @inline function Base. setproperty! (n:: $node_type , k:: Symbol , v)
271+ if k == :l
272+ if isdefined (n, :children )
273+ $ (set_child!)(n, v, 1 )
274+ else
275+ $ (set_children!)(n, (v,))
276+ v
277+ end
278+ elseif k == :r
279+ $ (set_child!)(n, v, 2 )
271280 else
272- setfield! (n, k, convert (T, v))
281+ T = fieldtype (typeof (n), k)
282+ if v isa T
283+ setfield! (n, k, v)
284+ else
285+ setfield! (n, k, convert (T, v))
286+ end
273287 end
274288 end
275- end
276- end )
289+ end ,
290+ )
277291end
278292
279293# @make_accessors Node{T,2} where {T}
0 commit comments