2013-05-12 64 views
2

試圖在elisp的elisp的遞歸宏

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



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

定義resursive宏但它結束了在

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) 

之後,但這個功能不如果列表中,如果工作完整路徑不要 出口

+0

解釋你如何看待這個宏的控制流應該工作。你的基本情況是什麼?它只應該與abc一起工作嗎?加入的地方在哪裏?你認爲你打印的地方(cdr鍵)? – Greg 2013-05-12 18:30:22

回答

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一個錯字。

+1

另外,M-x pp-macroexpand-last-sexp – 2013-05-28 10:24:40

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) 

想要使這樣的宏。