Skip to content

Commit 0514598

Browse files
committed
fix: setproperty! for tuple children
1 parent 5505506 commit 0514598

File tree

2 files changed

+44
-31
lines changed

2 files changed

+44
-31
lines changed

src/Node.jl

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ for N in (:Node, :GraphNode)
8686
# TODO: Test with this disabled to spot any unintended uses
8787
end
8888
end
89+
# TODO: If we can't reach the same speed, we should make a Node2 type
90+
# that is specialized for 2-arity nodes.
8991

9092
#! format: off
9193
"""
@@ -164,38 +166,46 @@ when constructing or setting properties.
164166
"""
165167
GraphNode
166168

167-
@inline function Base.getproperty(n::Union{Node,GraphNode}, k::Symbol)
168-
if k == :l
169-
# TODO: Should a depwarn be raised here? Or too slow?
170-
return getfield(n, :children)[1][]
171-
elseif k == :r
172-
return getfield(n, :children)[2][]
173-
else
174-
return getfield(n, k)
175-
end
176-
end
177-
@inline function Base.setproperty!(n::Union{Node,GraphNode}, k::Symbol, v)
178-
if k == :l
179-
getfield(n, :children)[1][] = v
180-
elseif k == :r
181-
getfield(n, :children)[2][] = v
182-
elseif k == :degree
183-
setfield!(n, :degree, convert(UInt8, v))
184-
elseif k == :constant
185-
setfield!(n, :constant, convert(Bool, v))
186-
elseif k == :feature
187-
setfield!(n, :feature, convert(UInt16, v))
188-
elseif k == :op
189-
setfield!(n, :op, convert(UInt8, v))
190-
elseif k == :val
191-
setfield!(n, :val, convert(eltype(n), v))
192-
elseif k == :children
193-
setfield!(n, :children, v)
194-
else
195-
error("Invalid property: $k")
196-
end
169+
macro make_accessors(node_type)
170+
esc(quote
171+
@inline function Base.getproperty(n::$node_type, k::Symbol)
172+
if k == :l
173+
# TODO: Should a depwarn be raised here? Or too slow?
174+
return getfield(n, :children)[1][]
175+
elseif k == :r
176+
return getfield(n, :children)[2][]
177+
else
178+
return getfield(n, k)
179+
end
180+
end
181+
@inline function Base.setproperty!(n::$node_type, k::Symbol, v)
182+
if k == :l
183+
if isdefined(n, :children)
184+
getfield(n, :children)[1][] = v
185+
else
186+
r = Ref(v)
187+
setfield!(n, :children, (r, Ref{typeof(n)}()))
188+
r
189+
end
190+
elseif k == :r
191+
# TODO: Remove this assert once we know that this is safe
192+
@assert isdefined(n, :children)
193+
getfield(n, :children)[2][] = v
194+
else
195+
T = fieldtype(typeof(n), k)
196+
if v isa T
197+
setfield!(n, k, v)
198+
else
199+
setfield!(n, k, convert(T, v))
200+
end
201+
end
202+
end
203+
end)
197204
end
198205

206+
@make_accessors Node
207+
@make_accessors GraphNode
208+
199209
################################################################################
200210
#! format: on
201211

src/ParametricExpression.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import ..NodeModule:
1818
leaf_convert,
1919
leaf_hash,
2020
leaf_equal,
21-
set_node!
21+
set_node!,
22+
@make_accessors
2223
import ..NodePreallocationModule: copy_into!, allocate_container
2324
import ..NodeUtilsModule:
2425
count_constant_nodes,
@@ -69,6 +70,8 @@ mutable struct ParametricNode{T,D} <: AbstractExpressionNode{T,D}
6970
end
7071
end
7172

73+
@make_accessors ParametricNode
74+
7275
"""
7376
ParametricExpression{T,N<:ParametricNode{T},D<:NamedTuple} <: AbstractExpression{T,N}
7477

0 commit comments

Comments
 (0)