Macros 如何编写(简单)宏?

Macros 如何编写(简单)宏?,macros,lisp,common-lisp,clos,Macros,Lisp,Common Lisp,Clos,我需要为我正在编写的游戏编写一个宏(带有hook(怪物方法who what)和body body)。Monster是CLOS对象、方法,谁是字符串,什么是函数(#'符号)。宏观扩张的效果将是 (add-hook monster method who what) ,@body (remove-hook monster method who) 我绝对不知道如何编写这样一个宏,我希望能得到一些帮助。 我有一种令人毛骨悚然的感觉,这很容易,而且我有点无知。我会这样写: (defmacro with-h

我需要为我正在编写的游戏编写一个宏
(带有hook(怪物方法who what)和body body)
。Monster是CLOS对象、方法,谁是字符串,什么是函数(#'符号)。宏观扩张的效果将是

(add-hook monster method who what)
,@body
(remove-hook monster method who)
我绝对不知道如何编写这样一个宏,我希望能得到一些帮助。
我有一种令人毛骨悚然的感觉,这很容易,而且我有点无知。

我会这样写:

(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)))))
一些注意事项:

  • something var
    s用于确保
    monster
    method
    who
    what
    的表达式只计算一次(因为这些表达式在宏体中被多次引用)并按从左到右的顺序进行计算
  • gensym
    s用于确保变量具有保证唯一的名称
  • 展开保护用于确保即使在非本地退出的情况下(例如,由于抛出异常而导致堆栈展开),也会调用
    remove hook

  • 非常感谢。我正在开发一款名为地雷威胁()的GPL流氓类游戏,我只是想确定你们对这款游戏是否满意。(我有一个属性注释(已经有一段时间了))我不介意您是否以任何方式将此宏包含在任何项目中。