【问题标题】:Interpolating an expression into an expression inside of a quote将表达式插入到引号内的表达式中
【发布时间】:2017-02-10 07:02:52
【问题描述】:

这个问题builds off of a previous SO question 用于从宏内部的表达式构建表达式。然而,当引用整个表达时,事情变得有点卡车司机。例如,我想构建表达式:(name=val)。以下:

macro quotetest(name,val)
  quote
    nm = Meta.quot($(QuoteNode(name)))
    v = Meta.quot($(QuoteNode(val)))
    println(nm); println(typeof(nm))
    println(v); println(typeof(val))
  end
end

@quotetest x 5 # Test case: build :(x=5)

打印出来

:x
Expr
$(Expr(:quote, 5))
Expr

表明我在正确的道路上:nm 和 val 是我想要在引号内的表达式。但是,此时我似乎无法应用以前的解决方案。例如,

macro quotetest(name,val)
  quote
    nm = Meta.quot($(QuoteNode(name)))
    v = Meta.quot($(QuoteNode(val)))
    println(nm); println(typeof(nm))
    println(v); println(typeof(v))
    println(:($(Expr(:(=),$(QuoteNode(nm)),$(QuoteNode(val))))))
  end
end

失败,说nm is not defined。我尝试在没有QuoteNode 的情况下进行插值,转义插值$(esc(nm)) 等。我似乎不知道如何让它构建表达式。

【问题讨论】:

  • macro qtest(name,val) :(Expr(:(=),$(Meta.quot(name)),$(Meta.quot(val)))) end。这会返回所需的表达式吗?在问题中,引用嵌套似乎比需要的要高(quote 然后quot 然后:() 然后QuoteNode... 一些$s 胡椒)。
  • 虽然直接构建表达式适用于所示的简单案例,但概括起来要困难得多。您可以构建一个宏,该宏会生成一个可在 REPL 上工作且易于测试的输出,然后通过引用它并正确插入所有内容,将其转换为可在函数中工作的东西。我发现这比逐步构建大型表达式要容易得多。

标签: macros metaprogramming julia


【解决方案1】:

我认为您使用$ 标志的次数超出了您的需要。这是你要找的吗?

julia> macro quotetest(name,val)
           quote
               expr = :($$(QuoteNode(name)) = $$(QuoteNode(val)))
               println(expr)
               display(expr)
               println(typeof(expr))
           end
       end
@quotetest (macro with 1 method)

julia> @quotetest test 1
test = 1
:(test = 1)
Expr

【讨论】:

    猜你喜欢
    • 2017-02-05
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    相关资源
    最近更新 更多