2

struct-of-arrays データ構造のヘルパーを定義するマクロを作成しようとしています (このスニペットに基づいています)。そのマクロ内で、構造体のすべてのスロット値をトラバースするのに役立つ別のマクロを定義します。問題は、二重引用符の解除を適切に機能させることができないということです。コードは次のとおりです。

(defmacro defcomponent (name-and-options &body slots)
  (setf name-and-options (ensure-list name-and-options))
  (let ((struct (first name-and-options))
        (slot-names (iter (for s in slots)
                          (collecting
                           (ematch s
                             ((or (and name (symbol)
                                       (<> _ '*)
                                       (<> _ nil))
                                  (list* name _ (plist :type _ :read-only _)))
                              name))))))
    `(progn (defstruct ,name-and-options
              ;; some task-specific stuff omitted here
              )
            (defmacro ,(symbolicate 'with- struct) (components &rest body)
              `(loop
                 ,@',(iter (for s in slot-names)
                          (appending `(for ,s across (,(symbolicate struct '- s) components))))
                 do ,@body)))))

たとえば、(defcomponent buzz x y)マクロは次のように展開します

(PROGN
 (DEFSTRUCT (BUZZ)
   X Y)  ;; details omitted
 (DEFMACRO WITH-BUZZ (COMPONENTS &REST BODY)
   `(LOOP ,@'(FOR X ACROSS (BUZZ-X COMPONENTS) FOR Y ACROSS (BUZZ-Y COMPONENTS))
          DO ,@BODY))

componentsこれはちょっと機能しますが、内部with-buzzマクロのパラメーターにアクセスしたい、つまりこのようなものです

(DEFMACRO WITH-BUZZ (COMPONENTS &REST BODY)
   `(LOOP FOR X ACROSS (BUZZ-X ,COMPONENTS) FOR Y ACROSS (BUZZ-Y ,COMPONENTS)
          DO ,@BODY))

どうすればそれを達成できますか?と の組み合わせをたくさん試しましたが、うまくいきませ,,@でした。

4

2 に答える 2