2016-06-18 31 views
4

鑑於這種情況重新編譯自動化:的mac1環境中生活在Emacs /煤泥現場環境

(defmacro mac1 ...) 

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

重新定義不會影響func1,直到它本身就是重新編譯。

只要mac1重新編譯,有沒有辦法讓emacs或lisp自動重新編譯func1

像這樣的事情在源是可以接受的:

(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 CallersContinue Tags Search找到調用者,然後手動重新編譯它們。編寫重新編譯所有調用者的編輯器命令應該很容易/可能。

+0

最後一個例子有點讓人誤解,重新編譯已經編譯好的函數對大多數實現都沒有影響,當然所有編譯爲本地機器代碼的實現都是如此。請在示例之前或之前添加註釋。 – acelent

+1

注意。 SBCL模擬是'sb-introspect:who-macroexpands' ...而Slime函數是'slime-who-macroexpands'。然而,'sb-introspect:who-macroexpands'返回符號和'定義 - 源'結構的符號,並且將符號傳遞給'compile'沒有任何影響;你可能需要使用'definition-source-pathname'或其他東西來追蹤它。 – BRFennPocock