2

试图在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))

请让我知道如何纠正这个定义。

我可以将“键”定义为其他参数,例如

(defmacro remacro (&rest keys)
  (if keys
      `(abc ,(car keys)
            ,(remacro `,@(cdr keys)))
      ))

试过这个,但它不工作。

用例:

基本上我想定义一个函数

设置以alist方式排列的树节点

(它仍然无法正常工作,必须努力)

(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 eq

((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

4

2 回答 2

1

将宏写为:

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

于 2013-05-12T18:38:40.890 回答
0
(defmacro tree-node (tree &rest keys)
  (if keys
      `(cdr
        (assoc ',(car (last keys))
               (pushnew
                ',(last keys)
                (tree-node ,tree ,@(butlast keys))
                :key 'car)))
    tree))


(setq egtree nil)
(setf (tree-node egtree l1 l2 lx) 'value)
(push (tree-node egtree l1 l2 ly) 'element1)
(push (tree-node egtree l1 l2 ly) 'element2)


(defmacro set-tree-node (tree value &rest keys)
  `(setf (tree-node ,tree ,@keys) ,value))


(set-tree-node egtree 'value l1 l2 lz)

想做这样的宏。

于 2013-05-30T19:51:33.637 回答