2010-05-23 115 views
5

我需要爲我寫的遊戲寫一個宏(with-hooks (monster method who what) &body body)。怪物是一個CLOS對象,方法和誰是字符串,什麼是函數(#'符號)。該宏擴展將是東西的如何編寫(簡單)宏?

(add-hook monster method who what) 
,@body 
(remove-hook monster method who) 

效果我絕對不知道如何編寫這樣一個宏,我將不勝感激一些幫助。 我有令人毛骨悚然的感覺,這很容易,我有點無知。

回答

10

我會寫這樣的:

(defmacro with-hooks ((monster method who what) &body body) 
    (let ((monster-var (gensym)) 
     (method-var (gensym)) 
     (who-var (gensym)) 
     (what-var (gensym))) 
    `(let ((,monster-var ,monster) ; dummy comment 
      (,method-var ,method) 
      (,who-var ,who) 
      (,what-var ,what)) 
     (add-hook ,monster-var ,method-var ,who-var ,what-var) 
     (unwind-protect 
      (progn ,@body) 
      (remove-hook ,monster-var ,method-var ,who-var))))) 

一些注意事項:

  1. something-var s的用於確保表達式monstermethodwhowhat只計算一次(因爲這些表達式在宏體中被多次引用)並且按照從左到右的順序。
  2. gensym s的用於確保變量保證了唯一的名稱
  3. 開卷保護來確保remove-hook即使在非本地退出的情況下,所謂的(例如,堆放鬆由於被拋出的異常)。
+2

好笑,我寫了幾乎一行一行的代碼 – 2010-05-23 19:15:28

+0

謝謝。我正在開發一個叫做Menines of the Mines(http://motm.sourceforge.net)的GPL roguelike遊戲,並且只是想確保這個遊戲在你身邊。 (我有一個歸因評論(已經有一段時間了)) – krzysz00 2010-06-25 21:35:24

+0

我不介意你是否以任何方式在任何項目中包含這個宏。 – 2010-06-27 04:56:19