From 9c1af3a6e77d7a0e1dc66aa9166d0ead6a56d963 Mon Sep 17 00:00:00 2001 From: Teddy Date: Sun, 4 Aug 2013 10:00:30 +0800 Subject: modified the API of Env: add_binding --- Makefile | 3 +++ TODO.rst | 1 - builtin.cpp | 4 ++-- eval.cpp | 2 +- model.cpp | 15 +++++---------- model.h | 14 +++++++------- 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 0664a27..ea9d9a9 100644 --- a/Makefile +++ b/Makefile @@ -10,3 +10,6 @@ clean: db: gdb main + +cdb: + cgdb main diff --git a/TODO.rst b/TODO.rst index 99dccee..4650ec7 100644 --- a/TODO.rst +++ b/TODO.rst @@ -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(*top_ptr)->addr; Cons *pc = dynamic_cast(ret_addr->car); SymObj *id = dynamic_cast(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; } diff --git a/eval.cpp b/eval.cpp index 07ea00e..44569c1 100644 --- a/eval.cpp +++ b/eval.cpp @@ -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() { diff --git a/model.cpp b/model.cpp index ee578f2..95f70c6 100644 --- a/model.cpp +++ b/model.cpp @@ -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, diff --git a/model.h b/model.h index 13a5af2..ee0e8ae 100644 --- a/model.h +++ b/model.h @@ -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 -- cgit v1.2.3-70-g09d2