From c66dc142d240ec2e2ae78201d9614de76535be38 Mon Sep 17 00:00:00 2001 From: Teddy Date: Sat, 3 Aug 2013 23:09:59 +0800 Subject: C++ version now works! --- model.cpp | 63 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 28 deletions(-) (limited to 'model.cpp') diff --git a/model.cpp b/model.cpp index 6f49871..951c9e0 100644 --- a/model.cpp +++ b/model.cpp @@ -1,6 +1,7 @@ #include #include "model.h" +FrameObj::FrameObj(ClassType _ftype) : ftype(_ftype) {} EmptyList *empty_list = new EmptyList(); EmptyList::EmptyList() : Cons(NULL, NULL) {} @@ -13,7 +14,7 @@ bool FrameObj::is_ret_addr() { return ftype == CLS_RET_ADDR; } -EvalObj::EvalObj() : FrameObj() { ftype = CLS_EVAL_OBJ; } +EvalObj::EvalObj(ClassType _otype) : FrameObj(CLS_EVAL_OBJ), otype(_otype) {} void EvalObj::prepare(Cons *pc) {} bool EvalObj::is_simple_obj() { return otype == CLS_SIM_OBJ; @@ -28,24 +29,24 @@ bool EvalObj::is_true() { } Cons::Cons(EvalObj *_car, Cons *_cdr) : - EvalObj(), car(_car), cdr(_cdr), skip(false), next(cdr) {} + EvalObj(CLS_CONS_OBJ), car(_car), cdr(_cdr), skip(false), + next(cdr == empty_list ? NULL : cdr) {} string Cons::ext_repr() { return string("#"); } #ifdef DEBUG string Cons::_debug_repr() { return ext_repr(); } void Cons::_debug_print() { - printf("mem: 0x%llX 0x%llX 0x%llX\n%s\n", + printf("mem: 0x%llX (0x%llX . 0x%llX) | 0x%llX\n%s\n", (unsigned long long)this, (unsigned long long)car, (unsigned long long)cdr, + (unsigned long long)next, ("car: " + car -> ext_repr() + "\n" + \ "cdr: " + cdr -> ext_repr() + "\n").c_str()); } #endif -RetAddr::RetAddr(Cons *_addr) : FrameObj(), addr(_addr) { - ftype = CLS_RET_ADDR; -} +RetAddr::RetAddr(Cons *_addr) : FrameObj(CLS_RET_ADDR), addr(_addr) {} #ifdef DEBUG string RetAddr::_debug_repr() { return string("#"); } #endif @@ -69,22 +70,22 @@ ProcObj::ProcObj(ASTList *_body, SymbolList *_para_list) : OptObj(), body(_body), envt(_envt), para_list(_para_list) {} -Cons *ProcObj::call(ArgList *arg_list, Environment * &envt, +Cons *ProcObj::call(ArgList *args, Environment * &_envt, Continuation * &cont, FrameObj ** &top_ptr) { // Create a new continuation - Cons *ret_addr = dynamic_cast(*top_ptr); - Continuation *ncont = new Continuation(envt, ret_addr, cont, body); + Cons *ret_addr = dynamic_cast(*top_ptr)->addr; + Continuation *ncont = new Continuation(_envt, ret_addr, cont, body); cont = ncont; // Add to the cont chain - envt = new Environment(envt); // Create local env and recall the closure + _envt = new Environment(envt); // Create local env and recall the closure // TODO: Compare the arguments to the parameters - for (Cons *ptr = arg_list->cdr, *ppar = para_list; - ptr != empty_list; ptr = ptr->cdr) - envt->add_binding(dynamic_cast(ppar->car), ptr->car); - *top_ptr = new RetAddr(NULL); // Mark the entrance of a cont + for (Cons *ptr = args->cdr, *ppar = para_list; + ptr != empty_list; ptr = ptr->cdr, ppar = ppar->cdr) + _envt->add_binding(dynamic_cast(ppar->car), ptr->car); + *top_ptr++ = new RetAddr(NULL); // Mark the entrance of a cont return body; // Move pc to the proc entry point } -string ProcObj::ext_repr() { return string("#"); } #ifdef DEBUG string ProcObj::_debug_repr() { return ext_repr(); } #endif @@ -93,41 +94,47 @@ SpecialOptObj::SpecialOptObj() : OptObj() {} NumberObj::NumberObj() : EvalObj() {} -BuiltinProcObj::BuiltinProcObj(BuiltinProc f, const string &_name) : +BuiltinProcObj::BuiltinProcObj(BuiltinProc f, string _name) : OptObj(), handler(f), name(_name) {} -Cons *BuiltinProcObj::call(ArgList *arg_list, Environment * &envt, +Cons *BuiltinProcObj::call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr) { - Cons *ret_addr = dynamic_cast(*top_ptr); - *top_ptr = handler(arg_list->cdr); + Cons *ret_addr = dynamic_cast(*top_ptr)->addr; + *top_ptr++ = handler(args->cdr); return ret_addr->next; // Move to the next instruction } +string BuiltinProcObj::ext_repr() { + return "#"; +} +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) { binding[sym_obj->val] = eval_obj; } -EvalObj *Environment::get_obj(SymObj *sym_obj) { +EvalObj *Environment::get_obj(EvalObj *obj) { + SymObj *sym_obj = dynamic_cast(obj); + if (!sym_obj) return obj; // Not a SymObj + string name(sym_obj->val); - for (Environment *ptr = this; ptr; ptr = prev_envt) + for (Environment *ptr = this; ptr; ptr = ptr->prev_envt) { - bool has_key = binding.count(name); - if (has_key) return binding[name]; + 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 = prev_envt) - if (binding.count(name)) + for (Environment *ptr = this; ptr; ptr = ptr->prev_envt) + if (ptr->binding.count(name)) return true; return false; } Continuation::Continuation(Environment *_envt, Cons *_pc, Continuation *_prev_cont, - ASTList *_proc_body, - unsigned int _body_cnt) : + ASTList *_proc_body) : envt(_envt), pc(_pc), prev_cont(_prev_cont), - proc_body(_proc_body), body_cnt(_body_cnt) {} + proc_body(_proc_body) {} -- cgit v1.2.3