Автоматизация перекомпиляции в среде emacs/slime

Учитывая эту ситуацию:

(defmacro mac1 ...)

(defun func1 () 
  (mac1 ...))

Переопределение mac1 в живую среду не повлияет func1 пока он сам не перекомпилируется.

Есть ли способ получить emacs или lisp для автоматической перекомпиляции func1 всякий раз, когда mac1 перекомпилируется?

Нечто подобное в источнике будет приемлемым:

(watch
  (defmacro mac1 ...))

(on-signal (mac1)
  (defun func1 ...))

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

2 ответа

Решение

Макросы не обязательно компилируются. Если вы используете SBCL (см. Руководство), существует переменная с именем sb-ext:*evaluator-mode* который может быть установлен на :interpret так что макрос расширяется во время оценки. Другие реализации могут предоставить нечто подобное. Это позволяет вам изменять определения макросов, не перекомпилируя сайты вызовов, как вы уже сделали с функциями.

В качестве альтернативы, slime определяет функцию с именем slime-who-macroexpands, Вам нужно немного покопаться, чтобы увидеть, как это работает, и, возможно, использовать это, либо в среде Common Lisp (swank), либо на стороне emacs.

Например, в LispWorks вы можете сделать следующее. Вероятно, у SBCL есть подобное средство.

Допустим, у нас есть это:

(defmacro foo ()
  `(list 1 2 3))

(defun bar () (first (foo)))
(defun baz () (second (foo)))

Теперь вы можете спросить, кто звонит foo:

CL-USER 11 > (who-calls 'foo)
(BAZ BAR)

Это позволяет легко перекомпилировать обе функции:

CL-USER 12 > (mapcar 'compile (who-calls 'foo))
;;;*** Warning in BAZ: The definition of BAZ is already compiled.
;;;*** Warning in BAR: The definition of BAR is already compiled.
(BAZ BAR)

Поскольку LispWorks хранит базу данных who-звонков, можно перекомпилировать все функции, которые непосредственно используют и зависят от других функций / макросов.

Редактор имеет команду Edit Callers а также Continue Tags Search чтобы найти абонентов, а затем перекомпилировать их вручную. Должно быть легко / возможно написать команду редактора, которая перекомпилирует всех вызывающих.

Другие вопросы по тегам