aboutsummaryrefslogtreecommitdiff
path: root/model.cpp
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2013-08-03 23:09:59 +0800
committerTeddy <ted.sybil@gmail.com>2013-08-03 23:09:59 +0800
commitc66dc142d240ec2e2ae78201d9614de76535be38 (patch)
treec9df286951328d7a477415946e8000beef6843ad /model.cpp
parente462669c3c3cc04ea29420e14dbb589899d201ec (diff)
C++ version now works!
Diffstat (limited to 'model.cpp')
-rw-r--r--model.cpp63
1 files changed, 35 insertions, 28 deletions
diff --git a/model.cpp b/model.cpp
index 6f49871..951c9e0 100644
--- a/model.cpp
+++ b/model.cpp
@@ -1,6 +1,7 @@
#include <cstdio>
#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("#<Cons>"); }
#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("#<Return Address>"); }
#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<Cons*>(*top_ptr);
- Continuation *ncont = new Continuation(envt, ret_addr, cont, body);
+ Cons *ret_addr = dynamic_cast<RetAddr*>(*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<SymObj*>(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<SymObj*>(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("#<Procedure"); }
+string ProcObj::ext_repr() { return string("#<Procedure>"); }
#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<Cons*>(*top_ptr);
- *top_ptr = handler(arg_list->cdr);
+ Cons *ret_addr = dynamic_cast<RetAddr*>(*top_ptr)->addr;
+ *top_ptr++ = handler(args->cdr);
return ret_addr->next; // Move to the next instruction
}
+string BuiltinProcObj::ext_repr() {
+ return "#<Builtin Procedure: " + name + ">";
+}
+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<SymObj*>(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) {}