2010-05-23 23 views
5

Yazdığım bir oyun için bir makro (with-hooks (monster method who what) &body body) yazmam gerek. Canavar bir CLOS nesnesi, yöntemi ve kimin dizeleri ve bir işlev (# 'notasyonu)' dir. macroexpansion Böyle bir makro yazma kesinlikle hiçbir fikri varMakro (basit) nasıl yazılır?

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

etkisiyle adam olabilir, ve yardıma takdir ediyorum. Bunun kolay olduğunu ve biraz cahil olduğumu garip hissediyorum.

cevap

10

bu gibi yazmak isterim:

(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))))) 

bazı notlar:

  1. something-var ler ifadeler için monster, method, who, what sadece bir kez değerlendirilir sağlamak için kullanılır (çünkü Bu ifadeler, makro gövdede birden çok kez referans alınır ve soldan sağa sırayla.
  2. gensym s değişkenler
  3. açma-koruma remove-hook bile yerel olmayan çıkış durumunda adlandırılan sağlamak için kullanılır (örneğin, bağlı durum atılan için açmak yığını) benzersiz adlar garanti emin olmak için kullanılır.
+2

komik, aynı kodu neredeyse satır-by-line yazmıştım –

+0

Teşekkür ederim. Madenlerin Menace (http://motm.sourceforge.net) adlı bir GPL roguelike oyunu üzerinde çalışıyorum ve sadece orada olmanın sizin için uygun olduğundan emin olmak istiyorum. (Bir öznitelik yorumum var (Bir süredir var)) – krzysz00

+0

Bu makroyu herhangi bir projeye herhangi bir şekilde dahil ederseniz umurumda değil. –