macros - Julia 中宏生成宏中的转义表达式

标签 macros julia metaprogramming

我想在 Julia 中编写一个生成多个宏的宏

@register_attribute foo

应该生成宏

@set_foo
@get_foo

这又应该被定义为

@set_foo x 5 == set_attr!(x, :foo, 5)

我已经成功地完成了第一部分,但是@macroexpand显示内部变量x没有正确转义,导致 UndefVarErrors 如果我使用局部变量调用该方法。

@macroexpand @set_foo x 5 =
    :(Main.set_attr!(Main.x, (Symbol)("foo"), 5))

而我想要的是

@macroexpand @set_foo x 5 =
    :(set_attr!(x, (Symbol)("foo"), 5))

我的代码是

macro register_attribute(name)
    setn = Symbol("set_", string(name))
    getn = Symbol("get_", string(name))
    arg = gensym()
    arg2 = gensym()
    nsym = string(name)
    return Expr(:block, 
    esc(:(
        macro $(setn)($arg, $arg2)
            :(set_attr!($$arg, $$Symbol($$nsym), $$arg2)) 
        end)
        ),
    esc(:(
        macro $(getn)($arg, $arg2)
            :(get_attr!($$arg, $$Symbol($$nsym), $$arg2)) 
        end)
        ))
    e2
end

最佳答案

这是我解决整个问题的方法:

# for purely generative tasks like this, where the generated code is
# (presumably?) destined to be evalled at top level, I prefer using @eval
for attr in [:foo, :bar]
    get_attr_name = Symbol("get_", attr)
    set_attr_name = Symbol("set_", attr)
    quoted_attr   = QuoteNode(attr)

    @eval begin
        $get_attr_name(x)      = getproperty( x, $quoted_attr)
        $set_attr_name(x, val) = setproperty!(x, $quoted_attr, val)
    end
end

# should generate code like:
#   get_foo(x) = getproperty(x, :foo)
julia> nt = (foo=1, bar=2);

julia> get_foo(nt)
1

julia> get_bar(nt)
2

# Let's test in local scope too
julia> let nt2 = (foo=42,)
           get_foo(nt2)
       end
42

关于macros - Julia 中宏生成宏中的转义表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60887945/

相关文章:

dataframe - 使用 Julia 组合和透视 DataFrame

macros - 让出 Lambda : symbolic representation in macros

泛型类的 scala 宏泛型字段不适用类泛型类型参数

macros - 如何在 GNU Make 中使用 $(call ...) 执行可变宏

检查输入字符串与 C 中给定宏的匹配

julia - 如何在 Julia 中按多列对数据框进行排序

if-statement - Julia 中的一个简单的 'if' 语句将我的主筛的运行时间增加了 15 倍——为什么?

C++ 模板元编程特化歧义

django-models - Pythonic 字典遍历

目标名称的 Xcode/GCC 预定义宏?