首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Elisp递归宏

Elisp递归宏
EN

Stack Overflow用户
提问于 2013-05-13 02:18:42
回答 2查看 527关注 0票数 2

尝试在elisp中定义返回宏

代码语言:javascript
复制
(defmacro remacro (keys)
  (if keys
      `(func1 ,(car keys)
            ,(remacro (cdr keys)))
      ))



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

但它最终是在

代码语言:javascript
复制
 Lisp nesting exceeds `max-lisp-eval-depth'

错误。

想要得到这样的结果

代码语言:javascript
复制
(func1 a (func1 b (func1 c nil nil) '(c)) '(b c))

从…

代码语言:javascript
复制
(remacro '(a b c))

请告诉我如何才能纠正这个定义。

还有一件事,我可以将‘`keys’定义为rest参数,比如

代码语言:javascript
复制
(defmacro remacro (&rest keys)
  (if keys
      `(abc ,(car keys)
            ,(remacro `,@(cdr keys)))
      ))

我试过这个,但它不起作用。

使用案例:

基本上我想定义一个函数

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

(它仍然不起作用,必须对其进行改进)

代码语言:javascript
复制
(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)

运行后

代码语言:javascript
复制
(set-tree-node egtree new-node n b c)

应该得到

egtree eq

代码语言:javascript
复制
((n  (b  (c . new-node))))

代码语言:javascript
复制
(n  (b  (c . new-node)))

我把它定义为函数

代码语言:javascript
复制
(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))

但它只适用于现有的列表

它可以成功更改(如果存在完整路径,则为树)

代码语言:javascript
复制
  egtree from


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

代码语言:javascript
复制
  egtree eq


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

在像这样调用之后

代码语言:javascript
复制
  (set-tree-node jt 'replaced-d 'n 'b 'c)

但是,如果完整路径不存在,则此函数不适用于if list

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-13 02:38:41

将宏写成:

代码语言:javascript
复制
(defmacro remacro (keys)
  (if keys
      `(abc ,(car keys)
            (remacro ,(cdr keys)))))

并将其称为:

代码语言:javascript
复制
(remacro (a b c))

您不需要引用参数,因为宏参数不会求值。

要查看扩展,请使用:

代码语言:javascript
复制
(macroexpand-all '(remacro (a b c)))
(abc a (abc b (abc c nil)))

我不明白在你的例子中add应该来自哪里,我假设这是一个abc的拼写错误。

票数 1
EN

Stack Overflow用户

发布于 2013-05-31 03:51:34

代码语言:javascript
复制
(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)

想做这样的宏。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16510603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档