diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2013-11-13 17:37:55 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2013-11-13 17:37:55 -0800 |
commit | 8d0fd244e013683b049d86b6599de369bbad592f (patch) | |
tree | a7c3cd91352615ac138b8f48cc028368fa558858 | |
parent | 47d04de6478f48c6296198776b0ed572e736b008 (diff) | |
download | lisp-snippets-8d0fd244e013683b049d86b6599de369bbad592f.tar.gz lisp-snippets-8d0fd244e013683b049d86b6599de369bbad592f.tar.bz2 lisp-snippets-8d0fd244e013683b049d86b6599de369bbad592f.zip |
DEFTAIL: bugfix when function directly recurses. The return-from in the
generated FLET then references the FLET rather than the surrounding function.
Fixed by introducing anon block as the target of the return instead.
-rw-r--r-- | tail-recursion.lisp | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/tail-recursion.lisp b/tail-recursion.lisp index 635982e..8381345 100644 --- a/tail-recursion.lisp +++ b/tail-recursion.lisp @@ -252,6 +252,7 @@ (defmacro deftail (name lambda-list &body body) (let ((escape (gensym "ESCAPE-")) (other-tails `(,name)) + (anon-block (gensym)) (docstring) (decls)) (when (stringp (first body)) @@ -267,13 +268,14 @@ `(defun ,name (,@lambda-list &aux (,escape *tail-escape*)) ,@docstring ,@decls - (flet (,@(loop for other in other-tails - collecting `(,other (&rest args) - (return-from ,name - (let ((*tail-escape* ,escape)) - (tail-call #',other args))))) - (tail-call (fun args) - (let ((*tail-escape* ,escape)) - (tail-call fun args)))) - (let ((*tail-escape* nil)) - ,@body))))) + (block ,anon-block + (flet (,@(loop for other in other-tails + collecting `(,other (&rest args) + (return-from ,anon-block + (let ((*tail-escape* ,escape)) + (tail-call #',other args))))) + (tail-call (fun args) + (let ((*tail-escape* ,escape)) + (tail-call fun args)))) + (let ((*tail-escape* nil)) + ,@body)))))) |