Как записать (простой) макрос?

Я должен записать макрос (with-hooks (monster method who what) &body body) для игры я пишу. Монстр является объектом CLOS, методом и кто строки и что такое функция (#' нотация). Макрорасширение было бы чем-то к эффекту

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

У меня нет абсолютно никакой идеи, как записать такой макрос, и я ценил бы некоторую справку. У меня есть жуткое чувство, что это легко, и я немного не осведомлен.

5
задан krzysz00 23 May 2010 в 18:53
поделиться

1 ответ

Я бы написал это так:

(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 используются, чтобы гарантировать, что выражения для monster , метод , who , what оцениваются только один раз (поскольку на эти выражения ссылаются несколько раз в теле макроса) и в порядке слева направо.
  2. gensym используются для того, чтобы гарантировать, что переменные имеют гарантированные уникальные имена.
  3. unwind-protect используется, чтобы гарантировать, что remove-hook вызывается даже в случае нелокальных выходов (например, , раскрутка стека из-за возникшего исключения).
10
ответ дан 13 December 2019 в 22:02
поделиться