【发布时间】:2018-09-06 10:17:31
【问题描述】:
意图:
我正在尝试使用宏形式生成宏:
(make-type "int32" 32)
会产生:
(defmacro make-int32t (name)
`(quote (:type 'int32t :bit-length 32 :name ,name)))
这个生成的宏会产生如下内容:
(make-int32t "myvar")
(:TYPE 'INT32T :BIT-LENGTH 32 :NAME "myvar")
问题:
我正在努力解决如何使宏产生前导反引号和逗号。
这是我所拥有的:
(defmacro make-type (type-name bit-length)
(let*
((make-name (concatenate 'string "make-" type-name))
(mac-name (intern make-name)))
`(defmacro ,mac-name (name)
'(quote (:type ,type-name :bit-length ,bit-length :name "substitued")))))
; "substituted" ideally is something like ,name
如果我进行宏展开,我会得到:
(macroexpand-1 '(make-type "int32" 32))
(DEFMACRO |make-int32| (NAME)
''(:TYPE "int32" :BIT-LENGTH 32 :NAME "substitued"))
如果我尝试使用宏,我会得到:
(make-type "int44" 44)
; in: MAKE-TYPE "int44"
; (SB-INT:NAMED-DS-BIND (:MACRO |make-int44| . DEFMACRO)
; (NAME)
; (CDR #:EXPR)
; (BLOCK |make-int44| ''(:TYPE "int44" :BIT-LENGTH 44 :NAME "substitued")))
; --> SB-INT:BINDING*
; ==>
; (LET* ((#:G0 (SB-C::CHECK-DS-LIST (CDR #:EXPR) 1 1 '(# NAME)))
; (NAME (POP #:G0)))
; (BLOCK |make-int44| ''(:TYPE "int44" :BIT-LENGTH 44 :NAME "substitued")))
;
; caught STYLE-WARNING:
; The variable NAME is defined but never used.
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
WARNING: redefining COMMON-LISP-USER::|make-int44| in DEFMACRO
|make-int44|
但是如果我尝试使用宏,它是没有定义的。
(make-int44 "myvar")
The function COMMON-LISP-USER::MAKE-INT44 is undefined.
问题
1) 如何将"substituted" 替换为,name
2) 如何正确执行此操作?
编辑:我有一个错字:MARCO --> 宏,所以我相应地更改了问题
【问题讨论】:
-
什么是 DEFMARCO ?似乎不是 Common Lisp 运算符。
-
我现在没时间回答,但是google“common lisp double backquote”和“common lisp nested backquote”
-
一点提示,宏可能应该包含类似
','name的东西来代替"substituted" -
另外,与其考虑反引号和拼接,您将如何构建您需要的表单?毕竟,`(defmacro ,mac-name (name) ,@body)` 等价于(足够)
(list* 'defmacro mac-name (list 'name) body)。如果您以这种方式构建表单,您可能会更快地获得工作版本,然后可以尝试将其转换为基于反引号的实现(如果这仍然很重要)。
标签: macros common-lisp