Common lisp 宏定义宏中的引用

Common lisp 宏定义宏中的引用,common-lisp,lisp-macros,backquote,Common Lisp,Lisp Macros,Backquote,我正在尝试编写一个宏,它基于代码段为数组结构的数据结构定义一些帮助程序。在该宏中,我定义了另一个宏,它有助于遍历struct中的所有插槽值。问题是我不能让双引号正常工作。代码如下: DEF宏defcomponent名称、选项和主体插槽 setf名称和选项确保列表名称和选项 让结构名和选项 插槽名称iter用于插槽中的s 收集 ematch s 或名称和符号 _ '* _零 列表*名称plist:type\只读_ 名称 `progn defstruct、名称和选项 ;; 这里省略了一些特定于任务的

我正在尝试编写一个宏,它基于代码段为数组结构的数据结构定义一些帮助程序。在该宏中,我定义了另一个宏,它有助于遍历struct中的所有插槽值。问题是我不能让双引号正常工作。代码如下:

DEF宏defcomponent名称、选项和主体插槽 setf名称和选项确保列表名称和选项 让结构名和选项 插槽名称iter用于插槽中的s 收集 ematch s 或名称和符号 _ '* _零 列表*名称plist:type\只读_ 名称 `progn defstruct、名称和选项 ;; 这里省略了一些特定于任务的内容 defmacro,symbolicate'with-struct components&rest body `环路 插槽名称中s的,@',iter 附加'for',s overs,symbolicate struct'-s组件 你知道吗,@body 例如,defx x y宏扩展到

程序 解构嗡嗡声 xy;;遗漏细节 DEFMACRO带嗡嗡声组件和休息身体 `循环,@'X代表BUZZ-X组件,Y代表BUZZ-Y组件 你知道吗,@BODY 这是可行的,但我想用buzz宏访问内部的components参数,例如

DEFMACRO带嗡嗡声组件和休息身体 `在BUZZ-X上为X循环,在BUZZ-Y上为Y循环,组件 你知道吗,@BODY
我怎么可能做到呢?我尝试了很多和的组合,但都没有成功。

好吧,我尝试了手动列表构建+评估,而不是准排序,但亲爱的上帝之母,它看起来太哈克了

;; 跳过 defmacro,symbolicate'with-struct components&rest body 追加 '循环 评估 `国际热核聚变实验堆(iter)中的插槽名称 附加'for,s overs,symbolicate','struct'-,'s',components ”“是吗 身体
我很乐意接受任何其他更习惯地解决问题的答案。

有时不使用反报价模式会有所帮助。然后,在编译器的帮助下,作用域问题就更容易理解了,编译器会对常见的变量作用域问题发出警告

作为一个稍微简化的练习,我们将编写一个生成代码的函数。生成的代码是宏定义,宏定义本身生成代码

(defun makeit (name slots)
  (labels ((symbolicate (pattern &rest things)
             (intern (apply #'format nil pattern things)))
           (compute-for-clauses (slots)
             (loop for s in slots
                   append (list ''for (list 'quote s)
                                ''across (list 'list
                                               (list 'quote
                                                     (symbolicate "~a-~a" name s))
                                               'components)))))

    (list 'progn
          (list 'defmacro
                (symbolicate "WITH-~a" name)
                '(components &rest body)
                (append '(list* 'loop)
                        (compute-for-clauses slots)
                        (list ''do 'body))))))
范例

CL-USER 51 > (pprint (makeit 'buzz '(x y)))

(PROGN
  (DEFMACRO WITH-BUZZ (COMPONENTS &REST BODY)
    (LIST* 'LOOP
           'FOR
           'X
           'ACROSS
           (LIST 'BUZZ-X COMPONENTS)
           'FOR
           'Y
           'ACROSS
           (LIST 'BUZZ-Y COMPONENTS)
           'DO
           BODY)))

CL-USER 52 > (eval *)
NIL

CL-USER 53 > (macroexpand-1 '(with-buzz a (+ 12) (+ 30)))
(LOOP FOR X ACROSS (BUZZ-X A) FOR Y ACROSS (BUZZ-Y A) DO (+ 12) (+ 30))
T