aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2013-08-14 17:29:41 +0800
committerTeddy <ted.sybil@gmail.com>2013-08-14 17:29:41 +0800
commit3bf02a37cdd49d4d12c8fdf3a4a421d5dae3a75b (patch)
tree5dbfdcb5ca98768f193d529c88cd5ac1812006d8
parentbe368fbac6b8d80033ccb8e4138b55c4b0954c34 (diff)
big change in framework: unification of user-def proc and others
-rw-r--r--Makefile2
-rw-r--r--eval.cpp39
-rw-r--r--types.cpp96
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<RetAddr*>(*top_ptr);
+// RetAddr *ret_addr = static_cast<RetAddr*>(*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<OptObj*>(opt)->
+ call(args, envt, cont, top_ptr);
else
- {
- EvalObj *opt = args->car;
- if (opt->is_opt_obj())
- pc = static_cast<OptObj*>(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<RetAddr*>(*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<SymObj*> 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<RetAddr*>(*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<SymObj*>(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<EvalObj*>(*(++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<SymObj*> 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<SymObj*>(TO_PAIR(ppar)->car), args->car);
+ }
- if (ppar->is_sym_obj())
- _envt->add_binding(static_cast<SymObj*>(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<SymObj*>(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<EvalObj*>(*(++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() {