aboutsummaryrefslogtreecommitdiff
path: root/types.cpp
diff options
context:
space:
mode:
authorTeddy <[email protected]>2013-08-15 08:30:12 +0800
committerTeddy <[email protected]>2013-08-15 08:30:12 +0800
commit3c6e957edadd896e15c32c5f7765913c8ad4d63c (patch)
tree3973035dcf7b3789bb98b10e6eb50d0b428ee5c7 /types.cpp
parentaddbfae58d8afceb06d92f6ef1cdfed89c07518b (diff)
tail-recursion opt in user-def call
Diffstat (limited to 'types.cpp')
-rw-r--r--types.cpp20
1 files changed, 14 insertions, 6 deletions
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<EvalObj*>(*(++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<EvalObj*>(*(++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);
}