2010-05-23 143 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