在我的工作中,我尝试在 Common Lisp 中使用宏并有一些问题。 我有两个功能
(defun when-tagflag ()
(when (= tagflag 1)
(setf tagflag 0)
(push tagbuf taglist)
(setf tagbuf "")))
(defun when-attrflag ()
(when (= attrflag 1)
(setf attrflag 0)
(push attrbuf attrlist)
(setf attrbuf "")))
非常相似的功能。经过几个小时的实验得到了这样一个宏
defmacro when-flag (name)
(let ((flag (read-from-string (concatenate 'string (string name) "flag")))
(lst (read-from-string (concatenate 'string (string name) "list")))
(buf (read-from-string (concatenate 'string (string name) "buf"))))
`(when (= ,flag 1)
(setf ,flag 0)
(push ,buf ,lst)
(setf ,buf ""))))
> (pprint (macroexpand-1 '(when-flag "tag")))
> (WHEN (= TAGFLAG 1) (SETF TAGFLAG 0) (PUSH TAGBUF TAGLIST) (SETF TAGBUF ""))
在 when-flag 中,我使用连接字符串和读取字符串,但我认为我的方法不规范。有没有更合适的方法来解决这样的问题?
附言此解决方案对我不起作用 Can you create interactive functions in an Emacs Lisp macro?
最佳答案
Common Lisp 中的符号名称在内部默认为大写。
CL-USER 10 > (intern (concatenate 'string "TAG" "FLAG") "CL-USER")
TAGFLAG
:INTERNAL
CL-USER 11 > (intern (format nil "~:@(~AFLAG~)" "TAG") "CL-USER")
TAGFLAG
:INTERNAL
例子:
(defmacro when-flag (prefix &key (package-name "CL-USER"))
(flet ((create-symbol (suffix)
(intern (format nil "~:@(~A~A~)" prefix suffix)
package-name)))
(let ((flag-sym (create-symbol "FLAG"))
(list-sym (create-symbol "LIST"))
(buf-sym (create-symbol "BUF")))
`(when (= ,flag-sym 1)
(setf ,flag-sym 0)
(push ,buf-sym ,list-sym)
(setf ,buf-sym "")))))
关于macros - 使用 Lisp 宏创建类似的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25942241/