Reputation: 437
Trying to define resursive macro in elisp
(defmacro remacro (keys)
(if keys
`(func1 ,(car keys)
,(remacro (cdr keys)))
))
(macroexpand '(remacro '(a b c)))
But it is ended up in
Lisp nesting exceeds `max-lisp-eval-depth'
error.
Wanted to get result like
(func1 a (func1 b (func1 c nil nil) '(c)) '(b c))
from
(remacro '(a b c))
Please let me know how I can correct this definition.
One more thing could I defined `keys' as rest parameter like
(defmacro remacro (&rest keys)
(if keys
`(abc ,(car keys)
,(remacro `,@(cdr keys)))
))
tried this one but it is not working.
USE CASE:
Basically I wanted to define a function
to set a tree node that is arranged in alist way
(it is still not working, have to work on it)
(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)
After running
(set-tree-node egtree new-node n b c)
should get
egtree eq
((n (b (c . new-node))))
or
(n (b (c . new-node)))
I had defined it as function
(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))
But it could work only for existing list
It can successfully change (tree if full path exists)
egtree from
(setq egtree '((n (b (c . d)))))
to
egtree eq
'((n (b (c . replaced-d))))
after called like this
(set-tree-node jt 'replaced-d 'n 'b 'c)
But this function do not work with if list if complete path do not exits
Upvotes: 2
Views: 661
Reputation: 437
(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)
wanted to make macro like this.
Upvotes: 0
Reputation: 780673
Write the macro as:
(defmacro remacro (keys)
(if keys
`(abc ,(car keys)
(remacro ,(cdr keys)))))
and call it:
(remacro (a b c))
You don't need to quote the argument because macro parameters are not evaluated.
To see the expansion, use:
(macroexpand-all '(remacro (a b c)))
(abc a (abc b (abc c nil)))
I don't see where add
is supposed to come from in your example, I assume that was a typo for abc
.
Upvotes: 1