尝试在elisp中定义复活宏

(defmacro remacro (keys)
  (if keys
      `(func1 ,(car keys)
            ,(remacro (cdr keys)))
      ))



(macroexpand '(remacro '(a b c)))

但最终
 Lisp nesting exceeds `max-lisp-eval-depth'

错误。
想得到这样的结果
(func1 a (func1 b (func1 c nil nil) '(c)) '(b c))


(remacro '(a b c))

请告诉我怎样才能纠正这个定义。
还有一件事我可以把‘keys’定义为rest参数,比如
(defmacro remacro (&rest keys)
  (if keys
      `(abc ,(car keys)
            ,(remacro `,@(cdr keys)))
      ))

试过这个但没用。
用例:
基本上我想定义一个函数
设置按列表方式排列的树节点
(还是不行,得努力)
(defmacro set-tree-node (tree e &rest keys)
  `(setcdr
    ,(if keys
         `(assoc (car keys)
                 (pushnew
                  (list ,(car keys))
                  (cdr
                   ,(set-tree-node `(cdr ,xtree) e `,@(cdr keys)))
                  :key 'car))
         tree)
    e))


(setq egtree nil)

运行后
(set-tree-node egtree new-node n b c)

应该得到
egtree方程
((n  (b  (c . new-node))))


(n  (b  (c . new-node)))

我把它定义为函数
(defun set-tree-node (tree e &rest keys)
  (setcdr
   (reduce (lambda (xtree k)
             (message "tree %s k %s" xtree k)
             (assoc k (pushnew (list k) (cdr xtree) :key 'car)))
           keys :initial-value (cons nil tree))
   e))

但它只适用于现有的列表。
如果存在完整路径,它可以成功地改变(树)
  egtree from


  (setq egtree '((n  (b  (c . d)))))


  egtree eq


  '((n  (b  (c . replaced-d))))

像这样打过电话
  (set-tree-node jt 'replaced-d 'n 'b 'c)

但如果完整路径不适用,则此函数不适用于if list
出口

最佳答案

将宏编写为:

(defmacro remacro (keys)
  (if keys
      `(abc ,(car keys)
            (remacro ,(cdr keys)))))

并称之为:
(remacro (a b c))

不需要引用参数,因为宏参数不计算。
要查看扩展,请使用:
(macroexpand-all '(remacro (a b c)))
(abc a (abc b (abc c nil)))

在你的例子中,我不知道add应该来自哪里,我认为这是abc的一个拼写错误。

关于macros - Elisp递归宏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16510603/

10-10 16:42