aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.rst4
-rw-r--r--eval.cpp52
-rw-r--r--eval.h3
-rw-r--r--model.cpp8
-rw-r--r--model.h2
5 files changed, 46 insertions, 23 deletions
diff --git a/TODO.rst b/TODO.rst
index 1befc72..c978575 100644
--- a/TODO.rst
+++ b/TODO.rst
@@ -1,7 +1,7 @@
- Documents and comment
- - model
- - eval
+ - model --- done
+ - eval --- done
- builtin
- gc
- types
diff --git a/eval.cpp b/eval.cpp
index c6ded6e..918311e 100644
--- a/eval.cpp
+++ b/eval.cpp
@@ -1,13 +1,18 @@
+#include "consts.h"
#include "eval.h"
#include "builtin.h"
#include "exc.h"
-#include "consts.h"
#include "gc.h"
+
#include <cstdio>
+static const int EVAL_STACK_SIZE = 262144;
extern Pair *empty_list;
+
+/** The stack for evaluating expressions */
EvalObj *eval_stack[EVAL_STACK_SIZE];
+/** Add all kinds of built-in facilities before the evaluation */
void Evaluator::add_builtin_routines() {
#define ADD_ENTRY(name, rout) \
@@ -103,6 +108,9 @@ Evaluator::Evaluator() {
add_builtin_routines();
}
+/**
+ * Initiate the `next` pointer of an s-expression (a list)
+ */
inline bool make_exec(Pair *ptr) {
if (ptr == empty_list) return true;
EvalObj *nptr;
@@ -117,11 +125,15 @@ inline bool make_exec(Pair *ptr) {
return ptr->cdr == empty_list;
}
+/**
+ * Push a new stack frame according to current pc
+ */
inline void push(Pair * &pc, EvalObj ** &top_ptr,
Environment * &envt, Continuation * &cont) {
if (pc->car->is_simple_obj()) // Not an opt invocation
{
- *top_ptr++ = gc.attach(envt->get_obj(pc->car)); // Objectify the symbol
+ // Objectify the symbol
+ *top_ptr++ = gc.attach(envt->get_obj(pc->car));
pc = pc->next; // Move to the next instruction
}
else // Operational Invocation
@@ -136,59 +148,71 @@ inline void push(Pair * &pc, EvalObj ** &top_ptr,
gc.attach(cont);
*top_ptr++ = gc.attach(cont);
}
- else cont->tail = false;
+ else cont->tail = false; // tail recursion opt
if (!make_exec(TO_PAIR(pc->car)))
+ // not a valid an invocation
throw TokenError(pc->car->ext_repr(), RUN_ERR_WRONG_NUM_OF_ARGS);
- // static_cast because of is_simple_obj() is false
- cont->prog = pc = TO_PAIR(pc->car); // Go deeper to enter the call
+ // dive into the call
+ cont->prog = pc = TO_PAIR(pc->car);
+ // "pre-call" for some `SpecialObj`
envt->get_obj(pc->car)->prepare(pc);
}
}
+/**
+ * The main routine for the evaluation
+ */
EvalObj *Evaluator::run_expr(Pair *prog) {
+
EvalObj **top_ptr = eval_stack;
Pair *pc = prog;
Continuation *bcont = new Continuation(NULL, NULL, NULL), // dummy cont
*cont = bcont;
- gc.attach(cont);
+
#ifdef GC_DEBUG
fprintf(stderr, "Start the evaluation...\n");
#endif
+
+ // attach current cont and the whole s-expression tree, so they will not be
+ // garbage-collected
+ gc.attach(cont);
+ gc.attach(prog);
// envt is this->envt
push(pc, top_ptr, envt, cont);
- gc.attach(prog);
- while (cont != bcont)
+ // (cont != bcont) Still need to evaluate at least one level of invocation
+ while (cont != bcont)
{
if (top_ptr == eval_stack + EVAL_STACK_SIZE)
throw TokenError("Evaluation", RUN_ERR_STACK_OVERFLOW);
if (pc)
push(pc, top_ptr, envt, cont);
- else
+ else // All arguments are evaluated
{
Pair *args = empty_list;
while (*(--top_ptr) != cont)
{
EvalObj* obj = static_cast<EvalObj*>(*top_ptr);
gc.expose(obj);
- args = new Pair(obj, args);
+ // old args is auto attached due to the constructor of `Pair`
+ args = new Pair(obj, args);
}
- //gc.expose(*top_ptr);
- //< static_cast because the while condition
+ // manually protect the head pointer
gc.attach(args);
if ((args->car)->is_opt_obj())
{
OptObj *opt = static_cast<OptObj*>(args->car);
-// printf("%s\n", args->ext_repr().c_str());
pc = opt->call(args, envt, cont, top_ptr, cont->prog);
}
else
throw TokenError((args->car)->ext_repr(), SYN_ERR_CAN_NOT_APPLY);
-// gc.collect();
+// gc.collect(); THIS IS DEPRECATED BECAUSE IT'S NOT A SAFE POINT
+// ANYMORE DUE TO THE TAIL RECURSION OPT
}
}
+ // remove the protection
gc.expose(prog);
gc.expose(cont);
// static_cast because the previous while condition
diff --git a/eval.h b/eval.h
index a824748..c0e03e1 100644
--- a/eval.h
+++ b/eval.h
@@ -3,9 +3,8 @@
#include "model.h"
#include "types.h"
-const int EVAL_STACK_SIZE = 262144;
/** @class Evaluator
- * A runtime platform of interpreting
+ * A realtime interpreting platform
*/
class Evaluator {
private:
diff --git a/model.cpp b/model.cpp
index 3e5c9fa..12aa665 100644
--- a/model.cpp
+++ b/model.cpp
@@ -1,11 +1,11 @@
-#include <cstdio>
-
-#include "model.h"
-#include "exc.h"
#include "consts.h"
+#include "model.h"
#include "types.h"
+#include "exc.h"
#include "gc.h"
+#include <cstdio>
+
static const int REPR_STACK_SIZE = 262144;
extern EmptyList *empty_list;
extern GarbageCollector gc;
diff --git a/model.h b/model.h
index ab5dcc6..225cb37 100644
--- a/model.h
+++ b/model.h
@@ -118,7 +118,7 @@ class EvalObj : public FrameObj {/*{{{*/
*/
class ParseBracket : public FrameObj {/*{{{*/
public:
- /** The type of the bracket */
+ /** The type of the bracket (to distingiush '(' and '#(' ) */
unsigned char btype;
/** Construct a ParseBracket object */
ParseBracket(unsigned char btype);