From 3c6e957edadd896e15c32c5f7765913c8ad4d63c Mon Sep 17 00:00:00 2001 From: Teddy Date: Thu, 15 Aug 2013 08:30:12 +0800 Subject: tail-recursion opt in user-def call --- types.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'types.cpp') diff --git a/types.cpp b/types.cpp index 1aafca5..672fead 100644 --- a/types.cpp +++ b/types.cpp @@ -88,17 +88,25 @@ Pair *ProcObj::call(Pair *_args, Environment * &lenvt, { gc.expose(*top_ptr); *top_ptr++ = gc.attach(TO_PAIR(_args->cdr)->car); - EXIT_CURRENT_CONT(lenvt, cont); + EXIT_CURRENT_EXEC(lenvt, cont); // exit cont and envt gc.expose(_args); return ret_addr->next; } else { - gc.attach(static_cast(*(++top_ptr))); + if (!nexp->is_simple_obj() && nexp->cdr == empty_list) // tail recursion opt + { + cont->tail = true; + cont->state = NULL; + } + else + { + gc.attach(static_cast(*(++top_ptr))); + cont->state = nexp; + } top_ptr++; - cont->state = nexp; gc.expose(_args); - return cont->state; + return nexp; } } else @@ -302,7 +310,7 @@ BuiltinProcObj::BuiltinProcObj(BuiltinProc f, string _name) : Pair *ret_addr = cont->pc; gc.expose(*top_ptr); *top_ptr++ = gc.attach(handler(TO_PAIR(args->cdr), name)); - EXIT_CURRENT_CONT(lenvt, cont); + EXIT_CURRENT_EXEC(lenvt, cont); gc.expose(args); return ret_addr->next; // Move to the next instruction } @@ -398,7 +406,7 @@ Environment *Environment::get_prev() { } Continuation::Continuation(Environment *_envt, Pair *_pc, Continuation *_prev_cont ) : - Container(), prev_cont(_prev_cont), envt(_envt), pc(_pc), state(NULL) { + Container(), prev_cont(_prev_cont), envt(_envt), pc(_pc), state(NULL), tail(false) { gc.attach(prev_cont); gc.attach(envt); } -- cgit v1.2.3