如何写(简单)宏?

时间:2010-05-23 16:41:16

标签: macros lisp common-lisp clos

我需要为我正在编写的游戏编写一个宏(with-hooks (monster method who what) &body body)。 Monster是一个CLOS对象,方法,谁是字符串,什么是函数(#'表示法)。

是宏观扩张的结果
(add-hook monster method who what)
,@body
(remove-hook monster method who)

绝对不知道怎么写这样的宏,我会很感激一些帮助。 我有一种令人毛骨悚然的感觉,这很容易,我有点无知。

1 个答案:

答案 0 :(得分: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用于确保monstermethodwhowhat的表达式仅被评估一次(因为这些表达式被引用多个宏观体中的时间)和从左到右的顺序。
  2. gensym用于确保变量具有唯一名称
  3. unwind-protect用于确保即使在非本地退出的情况下也会调用remove-hook(例如,由于抛出异常而导致堆栈展开)。