From 5e6dee2f0935d7cbc21ce6990b805077c7928f5f Mon Sep 17 00:00:00 2001 From: Teddy Date: Wed, 7 Aug 2013 22:32:07 +0800 Subject: added support for `eval` --- builtin.cpp | 29 ++++++++++++++++++++++++++++- builtin.h | 15 +++++++++++++++ eval.cpp | 1 + 3 files changed, 44 insertions(+), 1 deletion(-) 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(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("#"); } +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(*top_ptr)->addr; + Cons *pc = static_cast(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_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); -- cgit v1.2.3