From 8d0fd244e013683b049d86b6599de369bbad592f Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 13 Nov 2013 17:37:55 -0800 Subject: 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. --- tail-recursion.lisp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'tail-recursion.lisp') 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)))))) -- cgit v1.2.3