macros - 使用 Lisp 宏创建类似的函数

标签 macros lisp common-lisp metaprogramming

在我的工作中,我尝试在 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/

相关文章:

lisp - 获取字符串而不是数字

macros - 匹配封闭函数的返回类型

Scala 极端解构?

vector - 给定向量列表的质心

lisp - Common Lisp中的整数除法?

c - 将 C 中的局部静态变量翻译成 Common Lisp

lisp - 我如何检查一个项目是否是 Common Lisp 列表的成员?

c - 如何在宏中调用宏?

c - 下面的c定义的语法是什么?

lambda - 如何在 lisp 中本地定义一个函数?