aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin.cpp29
-rw-r--r--builtin.h15
-rw-r--r--eval.cpp1
3 files changed, 44 insertions, 1 deletions
diff --git a/builtin.cpp b/builtin.cpp
index e435c8c..d9cee5e 100644
--- a/builtin.cpp
+++ b/builtin.cpp
@@ -616,7 +616,7 @@ Cons *SpecialOptIf::call(ArgList *args, Environment * &envt,
top_ptr += 2;
// Undo pop and invoke again
// static_cast because it's a call invocation
- return static_cast<Cons*>(ret_addr->car)->next;
+ return TO_CONS(ret_addr->car)->next;
}
}
@@ -817,6 +817,33 @@ Cons *SpecialOptQuote::call(ArgList *args, Environment * &envt,
string SpecialOptQuote::ext_repr() { return string("#<Builtin Macro: quote>"); }
+SpecialOptEval::SpecialOptEval() : SpecialOptObj("eval") {}
+
+void SpecialOptEval::prepare(Cons *pc) {
+ state = 0;
+}
+
+Cons *SpecialOptEval::call(ArgList *args, Environment * &envt,
+ Continuation * &cont, FrameObj ** &top_ptr) {
+ if (args->cdr == empty_list ||
+ TO_CONS(args->cdr)->cdr != empty_list)
+ throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS);
+ Cons *ret_addr = static_cast<RetAddr*>(*top_ptr)->addr;
+ Cons *pc = static_cast<Cons*>(ret_addr->car);
+ if (state)
+ {
+ *top_ptr++ = TO_CONS(args->cdr)->car;
+ return ret_addr->next; // Move to the next instruction
+ }
+ else
+ {
+ state = 1;
+ top_ptr += 2;
+ return TO_CONS(args->cdr);
+ }
+}
+
+string SpecialOptEval::ext_repr() { return string("#<Builtin Macro: eval>"); }
BUILTIN_PROC_DEF(make_pair) {
ARGS_EXACTLY_TWO;
diff --git a/builtin.h b/builtin.h
index b6585f3..be40b90 100644
--- a/builtin.h
+++ b/builtin.h
@@ -216,6 +216,21 @@ class SpecialOptQuote: public SpecialOptObj {
string ext_repr();
};
+/** @class SpecialOptEval
+ * The implementation of `eval` operator
+ */
+class SpecialOptEval: public SpecialOptObj {
+ private:
+ unsigned char state; /**< 0 for prepared, 1 for pre_called */
+ public:
+ SpecialOptEval();
+ void prepare(Cons *pc);
+ Cons *call(ArgList *args, Environment * &envt,
+ Continuation * &cont, FrameObj ** &top_ptr);
+
+ string ext_repr();
+};
+
#define BUILTIN_PROC_DEF(func)\
EvalObj *(func)(ArgList *args, const string &name)
diff --git a/eval.cpp b/eval.cpp
index f05eae0..85b9482 100644
--- a/eval.cpp
+++ b/eval.cpp
@@ -21,6 +21,7 @@ void Evaluator::add_builtin_routines() {
ADD_ENTRY("define", new SpecialOptDefine());
ADD_ENTRY("set!", new SpecialOptSet());
ADD_ENTRY("quote", new SpecialOptQuote());
+ ADD_ENTRY("eval", new SpecialOptEval());
ADD_BUILTIN_PROC("+", num_add);
ADD_BUILTIN_PROC("-", num_sub);