如何在常见的lisp中编写宏定义宏

krz*_*z00 10 lisp macros common-lisp

我的代码库中有两个宏(和攀爬),如下所示:

(defmacro def-stat-method (method-name stat)
  `(progn
     (defmethod ,method-name ((monster monster))
       (getf (stats monster) ,stat))
     (defmethod (setf ,method-name) (value (monster monster))
       (setf (getf (stats monster) ,stat) value))))
Run Code Online (Sandbox Code Playgroud)

还有这个:

(defmacro def-energy-method (method-name stat)
  `(progn
     (defmethod ,method-name ((monster monster))
       (getf (energies monster) ,stat))
     (defmethod (setf ,method-name) (value (monster monster))
       (setf (getf (energies monster) ,stat) value))))
Run Code Online (Sandbox Code Playgroud)

每个宏都具有以下调用语法: (def-stat-method ranged-weapon :ranged-weapon)

我想要一个宏(def-foo-method macro-name method)扩展到适当的宏,以便(def-foo-method def-stat-method stats)扩展到上面的第一个例子.我是一个口齿不清的新手,并不知道该怎么做.所有帮助赞赏.

wde*_*aum 13

只需编写一个扩展为另一个defmacro的宏,如下所示:

(defmacro def-foo-method (macro-name method)
  `(defmacro ,macro-name (method-name stat)
     (let ((method ',method))
       `(progn
          (defmethod ,method-name ((monster monster))
            (getf (,method monster) ,stat))
          (defmethod (setf ,method-name) (value (monster monster))
            (setf (getf (,method monster) ,stat) value))))))
Run Code Online (Sandbox Code Playgroud)

我认为可能有一种方法可以做到这一点没有let,但嵌套的反引号令人困惑:)

  • 这对我没问题(抱歉延迟回复). (2认同)