以编程方式生成符号宏 [英] Programmatically generating symbol macros

查看:21
本文介绍了以编程方式生成符号宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到了一个由两部分组成的数据结构:

  1. 将符号映射到索引的哈希表
  2. 包含数据的向量向量

例如:

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

这篇关于以编程方式生成符号宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆