引用宏时避免额外的开始块

时间:2019-05-29 14:59:01

标签: julia metaprogramming ffi

我正在这样编写Julia宏:

macro cfunc(name, rettype)
  quotedname = Expr(:quote, name)
  return quote 
    (()->ccall(($quotedname, "libc.so.6"), $rettype, ()))
  end
end

我可以用它来创建一个函数:

@cfunc(time, Int32)()  # Returns current time

但是,如果我排除了引用宏:

macro q(name)
  sym = Expr(:quote,name)
  return quote
    $(sym)
  end
end

macroexpand产生了一个额外的开始和结束:

:((begin
      #= REPL[142]:4 =#
      ()->begin
              #= REPL[142]:4 =#
              ccall((begin # <-- This is the extra begin
                          #= REPL[102]:4 =#
                          :clock
                      end, "libc.so.6"), Main.Int32, ())
          end       # ^^^ This is the extra end
  end)())

这会导致调用失败:

@cfunc(time, Int32)()
ERROR: error compiling #26: unsupported or misplaced expression "block" in function #26
Stacktrace:
 [1] top-level scope at REPL[151]:4

这样引用时如何避免开始/结束?

1 个答案:

答案 0 :(得分:0)

quote宏中的q块在完全扩展的版本中引入了额外的beginend。它通常不应该影响结果,而是ccall is special

这有效:

macro q(name)
  sym = Expr(:quote,name)
  return sym
end

此引用形式不会引入begin / end

macro q(name)
  sym = Expr(:quote,name)
  return :($sym)
end