Как оценить выражение Юлии, содержащее макрос? - PullRequest
5 голосов
/ 26 сентября 2019

Я генерирую некоторый код, который позже оценивается.Несмотря на то, что сгенерированный код является правильным, и его оценка построчно не вызывает проблем, он не может быть правильно оценен в целом.

eval(quote
  macro m() "return" end
  @m()
end)

Возвращает: ERROR: LoadError: UndefVarError: @m not defined

eval(quote macro m() "return" end end)
eval(@m())

Возвращает: "return"

1 Ответ

5 голосов
/ 26 сентября 2019

Расширение макроса выполняется до оценки, поэтому, когда в этом коде происходит расширение макроса, определение макроса в первом выражении в блоке происходит слишком поздно, чтобы повлиять на раскрытие второго выражения в блоке.Есть один особый случай, который делает то, что вы хотите: тип выражения :toplevel.Это автоматически используется для глобальных выражений верхнего уровня в модулях, но вы можете вручную создать выражения этого типа следующим образом:

ex = Expr(:toplevel,
    :(macro m() "return" end),
    :(@m())
)

И, конечно же, это делает то, что вы хотите:

julia> eval(ex)
"return"

Поскольку у Джулии нет макросов локальной области действия, это определение макроса уже должно иметь место в глобальной области видимости, так что, вероятно, это должно работать везде, где сработал бы оригинальный макрос, то есть определение макроса должно быть допустимо во всех тех же местах, которыесоставное выражение верхнего уровня допустимо.

...