diff options
author | Teddy <[email protected]> | 2013-08-07 22:32:07 +0800 |
---|---|---|
committer | Teddy <[email protected]> | 2013-08-07 22:32:07 +0800 |
commit | 5e6dee2f0935d7cbc21ce6990b805077c7928f5f (patch) | |
tree | d5e83342161a21f18d177ab65d1fd205ab0be48b | |
parent | b6a279fafe43f502ab5647a705b8880f8961b404 (diff) |
added support for `eval`
-rw-r--r-- | builtin.cpp | 29 | ||||
-rw-r--r-- | builtin.h | 15 | ||||
-rw-r--r-- | eval.cpp | 1 |
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; @@ -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) @@ -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); |