I would like to examine a user defined function to create a variable
example function
function foo(var)
out = var.a.a1 .+ var.b.c3
return out
end
in this case I would like to examine the code to identify that var
has keys “a” and “b” and create the tuple (“a”,“b”)
mkitti
January 27, 2024, 4:09am
2
julia> e = :(function foo(var)
out = var.a.a1 .+ var.b.c3
return out
end)
:(function foo(var)
#= REPL[47]:1 =#
#= REPL[47]:2 =#
out = var.a.a1 .+ var.b.c3
#= REPL[47]:3 =#
return out
end)
julia> sum_expr = e.args[2].args[3].args[2]
:(var.a.a1 .+ var.b.c3)
julia> sum_expr.args
3-element Vector{Any}:
:.+
:(var.a.a1)
:(var.b.c3)
julia> sum_expr.args[2].args[1].args[2].value
:a
julia> sum_expr.args[3].args[1].args[2].value
:b
julia> (sum_expr.args[2].args[1].args[2].value, sum_expr.args[3].args[1].args[2].value)
(:a, :b)
julia> string.((sum_expr.args[2].args[1].args[2].value, sum_expr.args[3].args[1].args[2].value))
("a", "b")
We could turn it into a macro as follows.
julia> macro metafoo(e)
sum_expr = e.args[2].args[3].args[2]
string.((sum_expr.args[2].args[1].args[2].value, sum_expr.args[3].args[1].args[2].value))
("a", "b")
end
@metafoo (macro with 1 method)
julia> @metafoo function foo(var)
out = var.a.a1 .+ var.b.c3
return out
end
("a", "b")
Perhaps you could not convince the user to use a macro. Then you might be able to parse through the lowered code as follows.
julia> lowered = code_lowered(foo, Tuple{NamedTuple})[1]
CodeInfo(
1 ─ %1 = Main.:+
│ %2 = Base.getproperty(var, :a)
│ %3 = Base.getproperty(%2, :a1)
│ %4 = Base.getproperty(var, :b)
│ %5 = Base.getproperty(%4, :c3)
│ %6 = Base.broadcasted(%1, %3, %5)
│ out = Base.materialize(%6)
└── return out
)
julia> lowered.code[2].args[3].value
:a
julia> lowered.code[4].args[3].value
:b
julia> lowered.code[2].args[3].value, lowered.code[4].args[3].value
(:a, :b)
julia> string.((lowered.code[2].args[3].value, lowered.code[4].args[3].value))
("a", "b")
3 Likes