Избегайте дополнительного блока начала при цитировании в макросе - PullRequest
0 голосов
/ 29 мая 2019

Я пишу макрос Джулии так:

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)())

, что приводит к сбою ccall:

@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 Ответ

1 голос
/ 29 мая 2019

Блок quote в макросе q вводит дополнительные begin и end в полностью расширенной версии.Обычно это не должно влиять на результат, но ccall является особенным .

Это работает:

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

, как и эта форма цитаты, которая не вводит begin / end:

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