From 3bf02a37cdd49d4d12c8fdf3a4a421d5dae3a75b Mon Sep 17 00:00:00 2001 From: Teddy Date: Wed, 14 Aug 2013 17:29:41 +0800 Subject: big change in framework: unification of user-def proc and others --- Makefile | 2 +- eval.cpp | 39 +++++--------------------- types.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++--------------------- 3 files changed, 73 insertions(+), 64 deletions(-) diff --git a/Makefile b/Makefile index 2558d7b..5232363 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CXX = g++ -DGMP_SUPPORT BUILD_DIR = build -all: gc_debug +all: debug debug: CXX += -DGC_INFO -g -pg gc_debug: CXX += -DGC_INFO -DGC_DEBUG -g -pg release: CXX += -O2 diff --git a/eval.cpp b/eval.cpp index 5d50335..0157f14 100644 --- a/eval.cpp +++ b/eval.cpp @@ -175,40 +175,15 @@ EvalObj *Evaluator::run_expr(Pair *prog) { args = new Pair(obj, args); } //< static_cast because the while condition - RetAddr *ret_addr = static_cast(*top_ptr); +// RetAddr *ret_addr = static_cast(*top_ptr); gc.attach(args); - if (!ret_addr->addr) - { - Pair *nexp = TO_PAIR(cont->proc_body->cdr); - cont->proc_body = nexp; - if (nexp == empty_list) - { - *top_ptr = gc.attach(args->car); - - gc.expose(envt); - envt = cont->envt; - gc.attach(envt); - - pc = cont->pc->next; - - gc.expose(cont); - cont = cont->prev_cont; - gc.attach(cont); - } - else pc = nexp; - gc.expose(args); - top_ptr++; - } + EvalObj *opt = args->car; + if (opt->is_opt_obj()) + pc = static_cast(opt)-> + call(args, envt, cont, top_ptr); else - { - EvalObj *opt = args->car; - if (opt->is_opt_obj()) - pc = static_cast(opt)-> - call(args, envt, cont, top_ptr); - else - throw TokenError(opt->ext_repr(), SYN_ERR_CAN_NOT_APPLY); - gc.collect(); - } + throw TokenError(opt->ext_repr(), SYN_ERR_CAN_NOT_APPLY); + gc.collect(); } } gc.expose(prog); diff --git a/types.cpp b/types.cpp index 6371640..b479501 100644 --- a/types.cpp +++ b/types.cpp @@ -79,40 +79,74 @@ Pair *ProcObj::call(Pair *_args, Environment * &genvt, Continuation * &cont, FrameObj ** &top_ptr) { // Create a new continuation // static_cast see `call` invocation in eval.cpp - Pair *ret_addr = static_cast(*top_ptr)->addr; - Continuation *_cont = new Continuation(genvt, ret_addr, cont, body); - // Create local env and recall the closure - Environment *_envt = new Environment(envt); - // static_cast because the params is already checked - EvalObj *ppar, *nptr; - Pair *args = _args; - for (ppar = params; - ppar->is_pair_obj(); - ppar = TO_PAIR(ppar)->cdr) + RetAddr *ret_info = static_cast(*top_ptr); + Pair *ret_addr = ret_info->addr; + if (ret_info->state) { - if ((nptr = args->cdr) != empty_list) - args = TO_PAIR(nptr); - else break; - _envt->add_binding(static_cast(TO_PAIR(ppar)->car), args->car); + Pair *nexp = TO_PAIR(ret_info->state->cdr); + if (nexp == empty_list) + { + delete *top_ptr; + *top_ptr++ = gc.attach(TO_PAIR(_args->cdr)->car); + + gc.expose(genvt); + genvt = cont->envt; + gc.attach(genvt); + + gc.expose(cont); + cont = cont->prev_cont; + gc.attach(cont); + gc.expose(_args); + return ret_addr->next; + } + else + { + gc.attach(static_cast(*(++top_ptr))); + top_ptr++; + ret_info->state = nexp; + gc.expose(_args); + return ret_info->state; + } } + else + { + Continuation *_cont = new Continuation(genvt, ret_addr, cont, body); + // Create local env and recall the closure + Environment *_envt = new Environment(envt); + // static_cast because the params is already checked + EvalObj *ppar, *nptr; + Pair *args = _args; + for (ppar = params; + ppar->is_pair_obj(); + ppar = TO_PAIR(ppar)->cdr) + { + if ((nptr = args->cdr) != empty_list) + args = TO_PAIR(nptr); + else break; + _envt->add_binding(static_cast(TO_PAIR(ppar)->car), args->car); + } - if (ppar->is_sym_obj()) - _envt->add_binding(static_cast(ppar), args->cdr); // (... . var_n) - else if (args->cdr != empty_list || ppar != empty_list) - throw TokenError("", RUN_ERR_WRONG_NUM_OF_ARGS); - - gc.expose(genvt); - genvt = _envt; - gc.attach(genvt); - - gc.expose(cont); - cont = _cont; - gc.attach(cont); - - delete *top_ptr; // release ret addr - *top_ptr++ = new RetAddr(NULL); // Mark the entrance of a cont - gc.expose(_args); - return body; // Move pc to the proc entry point + if (ppar->is_sym_obj()) + _envt->add_binding(static_cast(ppar), args->cdr); // (... . var_n) + else if (args->cdr != empty_list || ppar != empty_list) + throw TokenError("", RUN_ERR_WRONG_NUM_OF_ARGS); + + gc.expose(genvt); + genvt = _envt; + gc.attach(genvt); + + gc.expose(cont); + cont = _cont; + gc.attach(cont); + + gc.attach(static_cast(*(++top_ptr))); + top_ptr++; + ret_info->state = body; +// delete *top_ptr; // release ret addr +// *top_ptr++ = new RetAddr(NULL); // Mark the entrance of a cont + gc.expose(_args); + return ret_info->state; // Move pc to the proc entry point + } } void ProcObj::gc_decrement() { -- cgit v1.2.3-70-g09d2