From 2bb741508a93335b94adfabf3631abd39b8c6e8a Mon Sep 17 00:00:00 2001 From: Teddy Date: Wed, 14 Aug 2013 21:35:36 +0800 Subject: big change in framework: unification of Continuation and RetAddr --- builtin.cpp | 244 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 133 insertions(+), 111 deletions(-) (limited to 'builtin.cpp') diff --git a/builtin.cpp b/builtin.cpp index 4116501..3440ab5 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -14,7 +14,10 @@ using std::stringstream; extern EmptyList *empty_list; extern UnspecObj *unspec_obj; -SpecialOptIf::SpecialOptIf() : SpecialOptObj("if") {} + + +SpecialOptIf::SpecialOptIf(Environment *envt) : + SpecialOptObj(envt, "if") {} void SpecialOptIf::prepare(Pair *pc) { #define IF_EXP_ERR \ @@ -38,16 +41,16 @@ void SpecialOptIf::prepare(Pair *pc) { pc->next = NULL; } -Pair *SpecialOptIf::call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { - RetAddr *ret_info = static_cast(*top_ptr); - Pair *ret_addr = ret_info->addr; - if (ret_info->state) +Pair *SpecialOptIf::call(Pair *args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { + Pair *ret_addr = cont->pc; + if (cont->state) { - if (ret_info->state == empty_list) + if (cont->state == empty_list) { - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(TO_PAIR(args->cdr)->car); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; // Move to the next instruction } @@ -64,7 +67,7 @@ Pair *SpecialOptIf::call(Pair *args, Environment * &envt, // Undo pop and invoke again gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = empty_list; + cont->state = empty_list; gc.expose(args); return second; } @@ -74,14 +77,15 @@ Pair *SpecialOptIf::call(Pair *args, Environment * &envt, // Undo pop and invoke again gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = empty_list; + cont->state = empty_list; gc.expose(args); return third; } else { - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(unspec_obj); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; } @@ -91,10 +95,10 @@ Pair *SpecialOptIf::call(Pair *args, Environment * &envt, { gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = TO_PAIR(TO_PAIR(ret_addr->car)->cdr); - ret_info->state->next = NULL; + cont->state = TO_PAIR(TO_PAIR(ret_addr->car)->cdr); + cont->state->next = NULL; gc.expose(args); - return ret_info->state; + return cont->state; } throw NormalError(INT_ERR); } @@ -138,17 +142,18 @@ do \ } \ while (0) -SpecialOptLambda::SpecialOptLambda() : SpecialOptObj("lambda") {} +SpecialOptLambda::SpecialOptLambda(Environment *envt) : + SpecialOptObj(envt, "lambda") {} void SpecialOptLambda::prepare(Pair *pc) { // Do not evaluate anything pc->next = NULL; } -Pair *SpecialOptLambda::call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { +Pair *SpecialOptLambda::call(Pair *args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { - Pair *ret_addr = static_cast(*top_ptr)->addr; + Pair *ret_addr = cont->pc; Pair *pc = static_cast(ret_addr->car); if (pc->cdr == empty_list) @@ -171,13 +176,15 @@ Pair *SpecialOptLambda::call(Pair *args, Environment * &envt, for (Pair *ptr = body; ptr != empty_list; ptr = TO_PAIR(ptr->cdr)) ptr->next = NULL; // Make each expression isolated - delete *top_ptr; - *top_ptr++ = gc.attach(new ProcObj(body, envt, params)); + gc.expose(*top_ptr); + *top_ptr++ = gc.attach(new ProcObj(body, lenvt, params)); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; // Move to the next instruction } -SpecialOptDefine::SpecialOptDefine() : SpecialOptObj("define") {} +SpecialOptDefine::SpecialOptDefine(Environment *envt) : + SpecialOptObj(envt, "define") {} void SpecialOptDefine::prepare(Pair *pc) { Pair *first, *second; @@ -196,24 +203,23 @@ void SpecialOptDefine::prepare(Pair *pc) { pc->next = NULL; } -Pair *SpecialOptDefine::call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { - RetAddr* ret_info = static_cast(*top_ptr); - Pair *ret_addr = ret_info->addr; +Pair *SpecialOptDefine::call(Pair *args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { + Pair *ret_addr = cont->pc; Pair *pc = static_cast(ret_addr->car); EvalObj *obj; SymObj *id; EvalObj *first = TO_PAIR(pc->cdr)->car; if (first->is_simple_obj()) { - if (!ret_info->state) + if (!cont->state) { gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = TO_PAIR(TO_PAIR(pc->cdr)->cdr); - ret_info->state->next = NULL; + cont->state = TO_PAIR(TO_PAIR(pc->cdr)->cdr); + cont->state->next = NULL; gc.expose(args); - return ret_info->state; + return cont->state; } if (!first->is_sym_obj()) throw TokenError(first->ext_repr(), SYN_ERR_NOT_AN_ID); @@ -245,16 +251,18 @@ Pair *SpecialOptDefine::call(Pair *args, Environment * &envt, for (Pair *ptr = body; ptr != empty_list; ptr = TO_PAIR(ptr->cdr)) ptr->next = NULL; // Make each expression a orphan - obj = new ProcObj(body, envt, params); + obj = new ProcObj(body, lenvt, params); } - envt->add_binding(id, obj); - delete *top_ptr; + lenvt->add_binding(id, obj); + gc.expose(*top_ptr); *top_ptr++ = gc.attach(unspec_obj); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; } -SpecialOptSet::SpecialOptSet() : SpecialOptObj("set!") {} +SpecialOptSet::SpecialOptSet(Environment *envt) : + SpecialOptObj(envt, "set!") {} void SpecialOptSet::prepare(Pair *pc) { Pair *first, *second; @@ -272,21 +280,20 @@ void SpecialOptSet::prepare(Pair *pc) { pc->next = NULL; } -Pair *SpecialOptSet::call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { - RetAddr *ret_info = static_cast(*top_ptr); - Pair *ret_addr = ret_info->addr; +Pair *SpecialOptSet::call(Pair *args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { + Pair *ret_addr = cont->pc; Pair *pc = static_cast(ret_addr->car); EvalObj *first = TO_PAIR(pc->cdr)->car; - if (!ret_info->state) + if (!cont->state) { gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = TO_PAIR(TO_PAIR(pc->cdr)->cdr); - ret_info->state->next = NULL; + cont->state = TO_PAIR(TO_PAIR(pc->cdr)->cdr); + cont->state->next = NULL; gc.expose(args); - return ret_info->state; + return cont->state; } if (!first->is_sym_obj()) @@ -294,32 +301,36 @@ Pair *SpecialOptSet::call(Pair *args, Environment * &envt, SymObj *id = static_cast(first); - bool flag = envt->add_binding(id, TO_PAIR(args->cdr)->car, false); + bool flag = lenvt->add_binding(id, TO_PAIR(args->cdr)->car, false); if (!flag) throw TokenError(id->ext_repr(), RUN_ERR_UNBOUND_VAR); - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(unspec_obj); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; } -SpecialOptQuote::SpecialOptQuote() : SpecialOptObj("quote") {} +SpecialOptQuote::SpecialOptQuote(Environment *envt) : + SpecialOptObj(envt, "quote") {} void SpecialOptQuote::prepare(Pair *pc) { // Do not evaluate anything pc->next = NULL; } -Pair *SpecialOptQuote::call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { - Pair *ret_addr = static_cast(*top_ptr)->addr; +Pair *SpecialOptQuote::call(Pair *args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { + Pair *ret_addr = cont->pc; Pair *pc = static_cast(ret_addr->car); - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(TO_PAIR(pc->cdr)->car); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; } -SpecialOptEval::SpecialOptEval() : SpecialOptObj("eval") {} +SpecialOptEval::SpecialOptEval(Environment *envt) : + SpecialOptObj(envt, "eval") {} void SpecialOptEval::prepare(Pair *pc) { if (pc->cdr == empty_list || @@ -327,15 +338,15 @@ void SpecialOptEval::prepare(Pair *pc) { throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS); } -Pair *SpecialOptEval::call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { - RetAddr *ret_info = static_cast(*top_ptr); - Pair *ret_addr = ret_info->addr; - if (ret_info->state) +Pair *SpecialOptEval::call(Pair *args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { + Pair *ret_addr = cont->pc; + if (cont->state) { - gc.expose(ret_info->state); // Exec done - delete *top_ptr; + gc.expose(cont->state); // Exec done + gc.expose(*top_ptr); *top_ptr++ = gc.attach(TO_PAIR(args->cdr)->car); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; // Move to the next instruction } @@ -343,49 +354,51 @@ Pair *SpecialOptEval::call(Pair *args, Environment * &envt, { gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = TO_PAIR(args->cdr); - gc.attach(ret_info->state); // Or it will be released - ret_info->state->next = NULL; + cont->state = TO_PAIR(args->cdr); + gc.attach(cont->state); // Or it will be released + cont->state->next = NULL; gc.expose(args); - return ret_info->state; + return cont->state; } throw NormalError(INT_ERR); } -SpecialOptAnd::SpecialOptAnd() : SpecialOptObj("and") {} +SpecialOptAnd::SpecialOptAnd(Environment *envt) : + SpecialOptObj(envt, "and") {} void SpecialOptAnd::prepare(Pair *pc) { pc->next = NULL; } -Pair *SpecialOptAnd::call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { - RetAddr *ret_info = static_cast(*top_ptr); - Pair *ret_addr = ret_info->addr; +Pair *SpecialOptAnd::call(Pair *args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { + Pair *ret_addr = cont->pc; Pair *pc = static_cast(ret_addr->car); if (pc->cdr == empty_list) { - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(new BoolObj(true)); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; } - if (!ret_info->state) + if (!cont->state) { gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = TO_PAIR(pc->cdr); - ret_info->state->next = NULL; + cont->state = TO_PAIR(pc->cdr); + cont->state->next = NULL; gc.expose(args); - return ret_info->state; + return cont->state; } EvalObj *ret = TO_PAIR(args->cdr)->car; if (ret->is_true()) { - if (ret_info->state->cdr == empty_list) // the last member + if (cont->state->cdr == empty_list) // the last member { - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(ret); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; } @@ -393,56 +406,59 @@ Pair *SpecialOptAnd::call(Pair *args, Environment * &envt, { gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = TO_PAIR(ret_info->state->cdr); - ret_info->state->next = NULL; + cont->state = TO_PAIR(cont->state->cdr); + cont->state->next = NULL; gc.expose(args); - return ret_info->state; + return cont->state; } } else { - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(ret); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; } throw NormalError(INT_ERR); } -SpecialOptOr::SpecialOptOr() : SpecialOptObj("or") {} +SpecialOptOr::SpecialOptOr(Environment *envt) : + SpecialOptObj(envt, "or") {} void SpecialOptOr::prepare(Pair *pc) { pc->next = NULL; } -Pair *SpecialOptOr::call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { - RetAddr *ret_info = static_cast(*top_ptr); - Pair *ret_addr = static_cast(*top_ptr)->addr; +Pair *SpecialOptOr::call(Pair *args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { + Pair *ret_addr = cont->pc; Pair *pc = static_cast(ret_addr->car); if (pc->cdr == empty_list) { - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(new BoolObj(false)); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; } - if (!ret_info->state) + if (!cont->state) { gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = TO_PAIR(pc->cdr); - ret_info->state->next = NULL; + cont->state = TO_PAIR(pc->cdr); + cont->state->next = NULL; gc.expose(args); - return ret_info->state; + return cont->state; } EvalObj *ret = TO_PAIR(args->cdr)->car; if (!ret->is_true()) { - if (ret_info->state->cdr == empty_list) // the last member + if (cont->state->cdr == empty_list) // the last member { - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(ret); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; } @@ -450,28 +466,30 @@ Pair *SpecialOptOr::call(Pair *args, Environment * &envt, { gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = TO_PAIR(ret_info->state->cdr); - ret_info->state->next = NULL; + cont->state = TO_PAIR(cont->state->cdr); + cont->state->next = NULL; gc.expose(args); - return ret_info->state; + return cont->state; } } else { - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(ret); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; } throw NormalError(INT_ERR); } -SpecialOptApply::SpecialOptApply() : SpecialOptObj("apply") {} +SpecialOptApply::SpecialOptApply(Environment *envt) : + SpecialOptObj(envt, "apply") {} void SpecialOptApply::prepare(Pair *pc) {} -Pair *SpecialOptApply::call(Pair *_args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { +Pair *SpecialOptApply::call(Pair *_args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { Pair *args = _args; top_ptr++; // Recover the return address if (args->cdr == empty_list) @@ -511,7 +529,8 @@ Pair *SpecialOptApply::call(Pair *_args, Environment * &envt, return NULL; } -SpecialOptForce::SpecialOptForce() : SpecialOptObj("force") {} +SpecialOptForce::SpecialOptForce(Environment *envt) : + SpecialOptObj(envt, "force") {} void SpecialOptForce::prepare(Pair *pc) { if (pc->cdr == empty_list || @@ -519,18 +538,18 @@ void SpecialOptForce::prepare(Pair *pc) { throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS); } -Pair *SpecialOptForce::call(Pair *_args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { +Pair *SpecialOptForce::call(Pair *_args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { Pair *args = _args; args = TO_PAIR(args->cdr); - RetAddr *ret_info = static_cast(*top_ptr); - Pair *ret_addr = ret_info->addr; - if (ret_info->state) + Pair *ret_addr = cont->pc; + if (cont->state) { EvalObj *mem = args->car; prom->feed_mem(mem); - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(mem); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(_args); return ret_addr->next; // Move to the next instruction } @@ -542,8 +561,9 @@ Pair *SpecialOptForce::call(Pair *_args, Environment * &envt, EvalObj *mem = prom->get_mem(); if (mem) // fetch from memorized result { - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(mem); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(_args); return ret_addr->next; } @@ -551,15 +571,16 @@ Pair *SpecialOptForce::call(Pair *_args, Environment * &envt, { gc.attach(static_cast(*(++top_ptr))); top_ptr++; - ret_info->state = prom->get_entry(); - ret_info->state->next = NULL; + cont->state = prom->get_entry(); + cont->state->next = NULL; gc.expose(_args); - return ret_info->state; + return cont->state; } } } -SpecialOptDelay::SpecialOptDelay() : SpecialOptObj("delay") {} +SpecialOptDelay::SpecialOptDelay(Environment *envt) : + SpecialOptObj(envt, "delay") {} void SpecialOptDelay::prepare(Pair *pc) { if (pc->cdr == empty_list || @@ -568,12 +589,13 @@ void SpecialOptDelay::prepare(Pair *pc) { pc->next = NULL; } -Pair *SpecialOptDelay::call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr) { - Pair *ret_addr = static_cast(*top_ptr)->addr; +Pair *SpecialOptDelay::call(Pair *args, Environment * &lenvt, + Continuation * &cont, EvalObj ** &top_ptr) { + Pair *ret_addr = cont->pc; Pair *pc = static_cast(ret_addr->car); - delete *top_ptr; + gc.expose(*top_ptr); *top_ptr++ = gc.attach(new PromObj(TO_PAIR(pc->cdr)->car)); + EXIT_CURRENT_CONT(lenvt, cont); gc.expose(args); return ret_addr->next; // Move to the next instruction } -- cgit v1.2.3