diff options
author | Teddy <[email protected]> | 2013-08-04 10:00:30 +0800 |
---|---|---|
committer | Teddy <[email protected]> | 2013-08-04 10:00:30 +0800 |
commit | 9c1af3a6e77d7a0e1dc66aa9166d0ead6a56d963 (patch) | |
tree | b12624f6170e77c1e7c0d8d0885838176dadc186 | |
parent | 9e834528d38a89eb4075b09b35fb7b6e7636740d (diff) |
modified the API of Env: add_binding
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | TODO.rst | 1 | ||||
-rw-r--r-- | builtin.cpp | 4 | ||||
-rw-r--r-- | eval.cpp | 2 | ||||
-rw-r--r-- | model.cpp | 15 | ||||
-rw-r--r-- | model.h | 14 |
6 files changed, 18 insertions, 21 deletions
@@ -10,3 +10,6 @@ clean: db: gdb main + +cdb: + cgdb main @@ -1,3 +1,2 @@ -- Better judgement of continuation exit - Better inherit relationship between Cons and EvalObj - Replace many `dynamic_cast` with `static_cast` diff --git a/builtin.cpp b/builtin.cpp index 19516bd..75f470e 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -195,8 +195,8 @@ Cons *SpecialOptSet::call(ArgList *args, Environment * &envt, Cons *ret_addr = dynamic_cast<RetAddr*>(*top_ptr)->addr; Cons *pc = dynamic_cast<Cons*>(ret_addr->car); SymObj *id = dynamic_cast<SymObj*>(pc->cdr->car); - if (envt->has_obj(id)) - envt->add_binding(id, args->cdr->car); + bool flag = envt->add_binding(id, args->cdr->car, false); + // TODO: throw an exc "unbound variable" *top_ptr++ = new UnspecObj(); return ret_addr->next; } @@ -22,7 +22,7 @@ void Evaluator::add_builtin_routines() { ADD_ENTRY("if", new SpecialOptIf()); ADD_ENTRY("lambda", new SpecialOptLambda()); ADD_ENTRY("define", new SpecialOptDefine()); - ADD_ENTRY("set", new SpecialOptSet()); + ADD_ENTRY("set!", new SpecialOptSet()); } Evaluator::Evaluator() { @@ -131,8 +131,11 @@ string BuiltinProcObj::_debug_repr() { return ext_repr(); } Environment::Environment(Environment *_prev_envt) : prev_envt(_prev_envt) {} -void Environment::add_binding(SymObj *sym_obj, EvalObj *eval_obj) { +bool Environment::add_binding(SymObj *sym_obj, EvalObj *eval_obj, bool def) { + bool has_key = binding.count(sym_obj->val); + if (!def && !has_key) return false; binding[sym_obj->val] = eval_obj; + return true; } EvalObj *Environment::get_obj(EvalObj *obj) { @@ -145,15 +148,7 @@ EvalObj *Environment::get_obj(EvalObj *obj) { bool has_key = ptr->binding.count(name); if (has_key) return ptr->binding[name]; } - //TODO: exc key not found -} - -bool Environment::has_obj(SymObj *sym_obj) { - string name(sym_obj->val); - for (Environment *ptr = this; ptr; ptr = ptr->prev_envt) - if (ptr->binding.count(name)) - return true; - return false; + return NULL; // Object not found } Continuation::Continuation(Environment *_envt, Cons *_pc, @@ -253,19 +253,19 @@ class Environment { public: /** Create an runtime environment * @param prev_envt the outer environment - * */ + */ Environment(Environment *prev_envt); - /** Add a binding entry which binds sym_obj to eval_obj */ - void add_binding(SymObj *sym_obj, EvalObj *eval_obj); + /** Add a binding entry which binds sym_obj to eval_obj + * @param def true to force the assignment + * @return when def is set to false, this return value is true iff. the + * assignment carried out successfully + */ + bool add_binding(SymObj *sym_obj, EvalObj *eval_obj, bool def = true); /** Extract the corresponding EvalObj if obj is a SymObj, or just * simply return obj as it is * @param obj the object as request * */ EvalObj *get_obj(EvalObj *obj); - /** Check if the desired obj exists - * @return true for yes - */ - bool has_obj(SymObj *); }; /** @class Continuation |