Clojure трассировка стека макросов исключений - PullRequest
1 голос
/ 29 апреля 2020

Допустим, у меня есть макрос, который заменяет все вхождения 'transact' на '\', вот так:

(defmacro transmuting-macro [& body]
  (let [transmuted-body (clojure.walk/postwalk 
                         #(if (and (list? %) (= 'transact (first %))) 
                            (-> % rest (conj `/)) %) body)]
    transmuted-body)) 

Теперь я могу сделать это:

(defn generate-error []
  (transmuting-macro (let [x 1
               b (transact 1 3)]
           (transact 3 0))))

Но трассировка стека исключения не может отследить, что находится внутри, она останавливается при вызове макроса (строка 2), а затем сразу же переходит к делению без предоставления какого-либо значащего номера строки (в данном случае строка 4).

Если я поставлю просто body вместо transmuted-body в последней строке определения макроса стек сохраняется. Итак, я считаю, что где-то есть скрытая информация, которая позволяет компилятору анализировать некоторые макросы, но не другие. Я попытался посмотреть на мета, а также специальные переменные & form и & env, но безрезультатно. Поскольку моя трансмутация ничего не меняет в номерах строк, достаточно просто скопировать эту информацию. Как заставить это работать?

1 Ответ

0 голосов
/ 29 апреля 2020

Глядя на macroexpand Я чувствую, что ваш макрос написан неправильно. Я не знаю, как вы вызываете исключения, чтобы вы могли попробовать этот вариант, который imho расширяется более правильно.

(defmacro transmuting-macro [& body]
  (let [transmuted-body (clojure.walk/postwalk
                          #(if (and (list? %) (= 'transact (first %)))
                             (-> % rest (conj `/)) %) body)]
    `(do ~@transmuted-body)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...