本文介绍了以编程方式生成符号宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我得到了一个由两部分组成的数据结构:
- 将符号映射到索引的哈希表
- 包含数据的向量向量
例如:
(defparameter *h* (make-hash-table))
(setf (gethash 'a *h*) 0)
(setf (gethash 'b *h*) 1)
(setf (gethash 'c *h*) 2)
(defparameter *v-of-v* #(#(1 2 3 4) ;vector a
#(5 6 7 8) ;vector b
#(9 10 11 12))) ;vector c
我想定义一个符号宏来获取向量a
,而不需要遍历哈希图。在代表处:
(define-symbol-macro a (aref *v-of-v* 0))
工作正常:
* a
#(1 2 3 4)
但是可能有很多命名向量,而且我不知道提前会有什么映射,所以我需要自动执行此过程:
(defun do-all-names ()
(maphash #'(lambda (key index)
(define-symbol-macro key (aref *v-of-v* index)))
*h*))
但这没有任何作用。我尝试过的将do-all-name设置为宏、反引号/逗号模板等组合也没有。我开始怀疑这是否与define-symbol-macro
本身无关。这似乎是一个很少使用的特性,在Lisp上只提到了两次。这里和其他地方也没有太多提到。在本例中,我使用的是SBCL 2.1
有人有什么想法吗?
推荐答案
您需要在运行时执行上述操作:
(defun do-all-names ()
(maphash #'(lambda (key index)
(eval `(define-symbol-macro ,key (aref *v-of-v* ,index)))
*h*))
DEFINE-SYMBOL-MACRO
是宏,并不计算其所有参数。因此,您需要为每个参数对生成新的宏表单并对其进行计算。
另一种方法(通常是在编译时)是编写一个宏,该宏在顶层生成以下表单:
(progn
(define-symbol-macro a (aref *v-of-v* 0))
(define-symbol-macro b (aref *v-of-v* 1))
; ....
)
这篇关于以编程方式生成符号宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!