aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--TODO.rst1
-rw-r--r--builtin.cpp4
-rw-r--r--eval.cpp2
-rw-r--r--model.cpp15
-rw-r--r--model.h14
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<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;
}
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