diff options
-rw-r--r-- | builtin.cpp | 76 | ||||
-rw-r--r-- | builtin.h | 123 | ||||
-rw-r--r-- | eval.cpp | 16 | ||||
-rw-r--r-- | model.cpp | 17 | ||||
-rw-r--r-- | model.h | 4 | ||||
-rw-r--r-- | types.cpp | 3 | ||||
-rw-r--r-- | types.h | 1 |
7 files changed, 113 insertions, 127 deletions
diff --git a/builtin.cpp b/builtin.cpp index 1c76053..aa69c06 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -11,20 +11,6 @@ using std::stringstream; extern EmptyList *empty_list; -#define ARGS_EXACTLY_TWO \ - if (args == empty_list || \ - args->cdr == empty_list || \ - TO_PAIR(args->cdr)->cdr != empty_list) \ - throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS) - -#define ARGS_EXACTLY_ONE \ - if (args == empty_list || \ - args->cdr != empty_list ) \ - throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS) - -#define ARGS_AT_LEAST_ONE \ - if (args == empty_list) \ - throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS) SpecialOptIf::SpecialOptIf() : SpecialOptObj("if") {} @@ -107,10 +93,6 @@ Pair *SpecialOptIf::call(Pair *args, Environment * &envt, } } -ReprCons *SpecialOptIf::get_repr_cons() { - return new ReprStr("#<Builtin Macro: if>"); -} - SpecialOptLambda::SpecialOptLambda() : SpecialOptObj("lambda") {} #define CHECK_COM(pc) \ do \ @@ -191,10 +173,6 @@ Pair *SpecialOptLambda::call(Pair *args, Environment * &envt, return ret_addr->next; // Move to the next instruction } -ReprCons *SpecialOptLambda::get_repr_cons() { - return new ReprStr("#<Builtin Macro: lambda>"); -} - SpecialOptDefine::SpecialOptDefine() : SpecialOptObj("define") {} void SpecialOptDefine::prepare(Pair *pc) { @@ -266,10 +244,6 @@ Pair *SpecialOptDefine::call(Pair *args, Environment * &envt, return ret_addr->next; } -ReprCons *SpecialOptDefine::get_repr_cons() { - return new ReprStr("#<Builtin Macro: define>"); -} - void SpecialOptSet::prepare(Pair *pc) { if (!pc->cdr->is_pair_obj()) throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS); @@ -306,10 +280,6 @@ Pair *SpecialOptSet::call(Pair *args, Environment * &envt, SpecialOptSet::SpecialOptSet() : SpecialOptObj("set!") {} -ReprCons *SpecialOptSet::get_repr_cons() { - return new ReprStr("#<Builtin Macro: set!>"); -} - SpecialOptQuote::SpecialOptQuote() : SpecialOptObj("quote") {} void SpecialOptQuote::prepare(Pair *pc) { @@ -328,10 +298,6 @@ Pair *SpecialOptQuote::call(Pair *args, Environment * &envt, return ret_addr->next; } -ReprCons *SpecialOptQuote::get_repr_cons() { - return new ReprStr("#<Builtin Macro: quote>"); -} - SpecialOptEval::SpecialOptEval() : SpecialOptObj("eval") {} void SpecialOptEval::prepare(Pair *pc) { @@ -357,10 +323,6 @@ Pair *SpecialOptEval::call(Pair *args, Environment * &envt, } } -ReprCons *SpecialOptEval::get_repr_cons() { - return new ReprStr("#<Builtin Macro: eval>"); -} - SpecialOptAnd::SpecialOptAnd() : SpecialOptObj("and") {} void SpecialOptAnd::prepare(Pair *pc) { @@ -405,10 +367,6 @@ Pair *SpecialOptAnd::call(Pair *args, Environment * &envt, throw NormalError(INT_ERR); } -ReprCons *SpecialOptAnd::get_repr_cons() { - return new ReprStr("#<Builtin Macro: and>"); -} - SpecialOptOr::SpecialOptOr() : SpecialOptObj("or") {} void SpecialOptOr::prepare(Pair *pc) { @@ -453,10 +411,6 @@ Pair *SpecialOptOr::call(Pair *args, Environment * &envt, throw NormalError(INT_ERR); } -ReprCons *SpecialOptOr::get_repr_cons() { - return new ReprStr("#<Builtin Macro: or>"); -} - SpecialOptApply::SpecialOptApply() : SpecialOptObj("apply") {} void SpecialOptApply::prepare(Pair *pc) {} @@ -499,10 +453,6 @@ Pair *SpecialOptApply::call(Pair *args, Environment * &envt, return NULL; // force the invocation } -ReprCons *SpecialOptApply::get_repr_cons() { - return new ReprStr("#<Builtin Macro: apply>"); -} - SpecialOptForce::SpecialOptForce() : SpecialOptObj("force") {} void SpecialOptForce::prepare(Pair *pc) { @@ -544,10 +494,6 @@ Pair *SpecialOptForce::call(Pair *args, Environment * &envt, } } -ReprCons *SpecialOptForce::get_repr_cons() { - return new ReprStr("#<Builtin Macro: force>"); -} - SpecialOptDelay::SpecialOptDelay() : SpecialOptObj("delay") {} void SpecialOptDelay::prepare(Pair *pc) { @@ -565,10 +511,26 @@ Pair *SpecialOptDelay::call(Pair *args, Environment * &envt, return ret_addr->next; // Move to the next instruction } -ReprCons *SpecialOptDelay::get_repr_cons() { - return new ReprStr("#<Builtin Macro: delay>"); -} +/*************************************************************************/ +/* The following lines are the implementation of various simple built-in + * procedures. Some library procdures are implemented here for the sake of + * efficiency. */ + +#define ARGS_EXACTLY_TWO \ + if (args == empty_list || \ + args->cdr == empty_list || \ + TO_PAIR(args->cdr)->cdr != empty_list) \ + throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS) + +#define ARGS_EXACTLY_ONE \ + if (args == empty_list || \ + args->cdr != empty_list ) \ + throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS) + +#define ARGS_AT_LEAST_ONE \ + if (args == empty_list) \ + throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS) BUILTIN_PROC_DEF(make_pair) { ARGS_EXACTLY_TWO; @@ -12,161 +12,186 @@ const int EQUAL_QUEUE_SIZE = 262144; /** @class SpecialOptIf * The implementation of `if` operator */ -class SpecialOptIf: public SpecialOptObj { +class SpecialOptIf: public SpecialOptObj {/*{{{*/ private: unsigned char state; /**< 0 for prepared, 1 for pre_called */ /** * The evaluator will call this after the <condition> exp is evaluated. * And this function tells the evaluator which of <consequence> and * <alternative> should be evaluted. */ - void pre_call(Pair *args, Pair *pc, - Environment *envt); + void pre_call(Pair *args, Pair *pc, Environment *envt); /** The system will call this again after the desired result is * evaluated, so just return it to let the evaluator know the it's the * answer. */ - EvalObj *post_call(Pair *args, Pair *pc, - Environment *envt); + EvalObj *post_call(Pair *args, Pair *pc, Environment *envt); public: + /** Construct a `if` operator */ SpecialOptIf(); + /** Prevent <condition> and <consequence> from being evaluated */ void prepare(Pair *pc); + /** When it's invoked at the first time, it will determined which of + * <condition> and <consequence> should be evaluated. Then when it's + * invoked again, it will tell the system the corresponding result.*/ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; + Continuation * &cont, FrameObj ** &top_ptr); +};/*}}}*/ /** @class SpecialOptLambda * The implementation of `lambda` operator */ -class SpecialOptLambda: public SpecialOptObj { +class SpecialOptLambda: public SpecialOptObj {/*{{{*/ public: + /** Construct a `lambda` operator */ SpecialOptLambda(); + /** Prevent all parts of the expression being evaluated */ void prepare(Pair *pc); + /** Make up a ProcObj and push into the stack */ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); + Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; +};/*}}}*/ /** @class SpecialOptDefine * The implementation of `define` operator */ -class SpecialOptDefine: public SpecialOptObj { +class SpecialOptDefine: public SpecialOptObj {/*{{{*/ public: + /** Construct a `define` operator */ SpecialOptDefine(); + /** Prevent some parts from being evaluated */ void prepare(Pair *pc); + /** See `SpecialOptLambda` */ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; + Continuation * &cont, FrameObj ** &top_ptr); +};/*}}}*/ /** @class SpecialOptSet * The implementation of `set!` operator */ -class SpecialOptSet: public SpecialOptObj { +class SpecialOptSet: public SpecialOptObj {/*{{{*/ public: + /** Construct a `set!` operator */ SpecialOptSet(); + /** See `SpecialOptDefine */ void prepare(Pair *pc); + /** See `SpecialOptDefine */ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; + Continuation * &cont, FrameObj ** &top_ptr); +};/*}}}*/ /** @class SpecialOptLambda * The implementation of `lambda` operator */ -class SpecialOptQuote: public SpecialOptObj { +class SpecialOptQuote: public SpecialOptObj {/*{{{*/ public: + /** Construct a `quote` operator */ SpecialOptQuote(); + /** Prevent the literal part from being evaluated */ void prepare(Pair *pc); + /** Return the literal */ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); + Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; +};/*}}}*/ /** @class SpecialOptEval * The implementation of `eval` operator */ -class SpecialOptEval: public SpecialOptObj { +class SpecialOptEval: public SpecialOptObj {/*{{{*/ private: unsigned char state; /**< 0 for prepared, 1 for pre_called */ public: + /** Construct an `eval` operator */ SpecialOptEval(); + /** Set state to 0 */ void prepare(Pair *pc); + /** Behaves like the one in `SpecialOptIf` */ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); + Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; +};/*}}}*/ /** @class SpecialOptAnd * The implementation of `and` operator */ -class SpecialOptAnd: public SpecialOptObj { +class SpecialOptAnd: public SpecialOptObj {/*{{{*/ public: + /** Construct an `and` operator */ SpecialOptAnd(); + /** Prevent all parts from being evaluated */ void prepare(Pair *pc); + /** Acts like `SpecialOptIf` */ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); + Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; +};/*}}}*/ /** @class SpecialOptOr * The implementation of `and` operator */ -class SpecialOptOr: public SpecialOptObj { +class SpecialOptOr: public SpecialOptObj {/*{{{*/ public: + /** Construct an `or` operator */ SpecialOptOr(); + /** See `SpecialOptAnd` */ void prepare(Pair *pc); + /** See `SpecialOptAnd` */ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); + Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; +};/*}}}*/ /** @class SpecialOptApply * The implementation of `apply` operator */ -class SpecialOptApply: public SpecialOptObj { +class SpecialOptApply: public SpecialOptObj {/*{{{*/ public: + /** Construct an `apply` operator */ SpecialOptApply(); + /** Do nothing */ void prepare(Pair *pc); + /** Provoke the <proc> with args */ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); + Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; +};/*}}}*/ /** @class SpecialOptDelay * The implementation of `delay` operator */ -class SpecialOptDelay: public SpecialOptObj { +class SpecialOptDelay: public SpecialOptObj {/*{{{*/ public: + /** Construct a `delay` operator */ SpecialOptDelay(); + /** Do nothing */ void prepare(Pair *pc); + /** Make up a PromObj and push into the stack */ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); + Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; +};/*}}}*/ /** @class SpecialOptForce * The implementation of `force` operator */ -class SpecialOptForce: public SpecialOptObj { +class SpecialOptForce: public SpecialOptObj {/*{{{*/ private: - bool state; + unsigned char state; PromObj* prom; public: + /** Construct a `force` operator */ SpecialOptForce(); + /** Set the state to 0 */ void prepare(Pair *pc); + /** Force the evaluation of a promise. If the promise has not been + * evaluated yet, then evaluate and feed the result to its memory, + * while if it has already been evaluated, just push the result into + * the stack */ Pair *call(Pair *args, Environment * &envt, - Continuation * &cont, FrameObj ** &top_ptr); + Continuation * &cont, FrameObj ** &top_ptr); - ReprCons *get_repr_cons(); -}; +};/*}}}*/ #define BUILTIN_PROC_DEF(func)\ EvalObj *(func)(Pair *args, const string &name) @@ -89,7 +89,21 @@ Evaluator::Evaluator() { add_builtin_routines(); } -void push(Pair * &pc, FrameObj ** &top_ptr, Environment *envt) { +inline bool make_exec(Pair *ptr) { + if (ptr == empty_list) return true; + EvalObj *nptr; + for (;;) + if ((nptr = ptr->cdr)->is_pair_obj()) + { + ptr->next = TO_PAIR(nptr); + ptr = ptr->next; + } + else break; + ptr->next = NULL; + return ptr->cdr == empty_list; +} + +inline void push(Pair * &pc, FrameObj ** &top_ptr, Environment *envt) { if (pc->car->is_simple_obj()) // Not an opt invocation { *top_ptr = envt->get_obj(pc->car); // Objectify the symbol @@ -125,20 +125,3 @@ string EvalObj::ext_repr() { res = "(" + res + ")"; return res; } - - - -bool make_exec(Pair *ptr) { - if (ptr == empty_list) return true; - EvalObj *nptr; - for (;;) - if ((nptr = ptr->cdr)->is_pair_obj()) - { - ptr->next = TO_PAIR(nptr); - ptr = ptr->next; - } - else break; - ptr->next = NULL; - return ptr->cdr == empty_list; -} - @@ -95,10 +95,8 @@ class EvalObj : public FrameObj { string ext_repr(); /** Always true for all EvalObjs except BoolObj */ virtual bool is_true(); + /** External representation construction */ virtual ReprCons *get_repr_cons() = 0; }; - -bool make_exec(Pair *ptr); - #endif @@ -82,6 +82,9 @@ ReprCons *ProcObj::get_repr_cons() { } SpecialOptObj::SpecialOptObj(string _name) : OptObj(), name(_name) {} +ReprCons *SpecialOptObj::get_repr_cons() { + return new ReprStr("#<Built-in Opt: " + name + ">"); +} BoolObj::BoolObj(bool _val) : EvalObj(CLS_SIM_OBJ | CLS_BOOL_OBJ), val(_val) {} @@ -184,6 +184,7 @@ class SpecialOptObj: public OptObj {/*{{{*/ string name; public: SpecialOptObj(string name); + ReprCons *get_repr_cons(); };/*}}}*/ /** @class BuiltinProcObj |