2016-06-18 4 views
4

Учитывая такую ​​ситуацию:перекомпиляция в автоматизации Emacs/слизью живой среде

(defmacro mac1 ...) 

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

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

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

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

(watch 
    (defmacro mac1 ...)) 

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

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

+1

Не настоящий ответ, но если вы готовы вступить в пакет 'cl', вы можете закрепить источник функции как свойство своего имени символа в обертке вокруг' defun' и иметь вторую оболочку вокруг 'defmacro', чтобы посмотреть' who-macroexpands' и перебрать эти скрытые источники. Или просто 'slime-compile-and-load-file', когда вы теряете информацию о том, что могли сделать ваши макрокоманды. – BRFennPocock

ответ

5

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

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

1

Например, в 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-calls, можно перекомпилировать все функции, которые непосредственно используются и зависят от o те функции/макросы.

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

+0

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

+1

NB. Аналогом SBCL является 'sb-introspect: who-macroexpands' ... и функция Slime -' slime-who-macroexpands'. Тем не менее, 'sb-introspect: who-macroexpands' возвращает alist символов и структуры' definition-source', а передача символа 'compile' не имеет никакого эффекта; вам придется использовать «определение-источник-путь» или что-то проследить. – BRFennPocock

Смежные вопросы