提问人:Akhil Akkapelli 提问时间:11/1/2023 更新时间:11/2/2023 访问量:64
将变量名称替换为 Julia 宏中的字符串
Replacing Variable Name with a String in a Julia Macro
问:
我正在处理一个项目,我需要在 Julia 中创建一个宏,该宏将 Julia 代码表达式、变量名称和字符串作为输入,并返回相同的表达式,并将指定的变量名称替换为给定的字符串。宏必须遵循 Julia 中的变量范围,这一点很重要。
例如,如果我有以下表达式:
x = 42
expr = :(2 * x + 3)
我使用变量名称 x 和替换字符串“y”调用宏,如下所示:
@my_macro expr x "y"
我想得到修改后的表达式:
:(2 * y + 3)
我一直在尝试实现这个宏,但我在处理变量范围和确保仅针对指定变量进行替换时遇到了麻烦。
我将不胜感激在正确实现此宏方面的任何指导或帮助。如果有人对如何在 Julia 中实现这一目标有任何见解、代码片段或建议,请与我分享。
答:
3赞
Przemyslaw Szufel
11/2/2023
#1
您可以定义以下函数:
using AbstractTrees
function replace!(expr::Expr, old_val::Symbol, new_val::Symbol)
for e in collect(PreOrderDFS(expr))
if typeof(e) <: Expr
ix = findfirst(==(old_val), e.args)
if !isnothing(ix)
e.args[ix] = new_val
end
end
end
expr
end
现在可以使用此功能,例如:
julia> replace!(quote; f(x,z) = 2x+4z; end, :x, :y)
quote
#= REPL[61]:1 =#
f(y, z) = begin
#= REPL[61]:1 =#
2y + 4z
end
end
这可以在宏中使用,例如:
macro replace(mycode, oldval, newval)
replace!(mycode, oldval.value, newval.value)
end
可用作:
julia> x=1; y=100;
julia> @replace(3x+y, :x, :y)
400
评论
0赞
Akhil Akkapelli
11/22/2023
在这里,in loop: for e in collect(PreOrderDFS(expr)),为什么修改 e.args 会反映在 expr 中,而修改 e 不会。
0赞
Przemyslaw Szufel
11/24/2023
“修改”是什么意思? 是一个局部变量,此循环包含引用。因此,我们得到一组引用作为局部变量,然后修改它们的字段。也许这会有所帮助:stackoverflow.com/questions/58150295/......e
e
0赞
Akhil Akkapelli
11/24/2023
我想直接修改expr树的节点。不是 expr 的任何参数。
评论
expr
express
@my_macro