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! --- Makefile | 7 ++-- TODO.rst | 3 ++ builtin.cpp | 100 ++++++++++++++++++++++++++++++++++++++++------------ builtin.h | 30 +++++++++------- eval.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++++ eval.h | 14 ++++++++ main.cpp | 12 +++++-- model.cpp | 63 ++++++++++++++++++--------------- model.h | 26 ++++++++------ parser.cpp | 2 +- prototype/sketch.py | 2 +- 11 files changed, 270 insertions(+), 80 deletions(-) create mode 100644 TODO.rst create mode 100644 eval.cpp create mode 100644 eval.h diff --git a/Makefile b/Makefile index 847cf3e..596f45f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -main: parser.o builtin.o model.o main.o - g++ -o main $^ +main: main.o parser.o builtin.o model.o eval.o + g++ -o main $^ -g .cpp.o: g++ $< -c -g -DDEBUG @@ -7,3 +7,6 @@ main: parser.o builtin.o model.o main.o clean: rm -f *.o rm -f main + +db: + gdb main diff --git a/TODO.rst b/TODO.rst new file mode 100644 index 0000000..99dccee --- /dev/null +++ b/TODO.rst @@ -0,0 +1,3 @@ +- 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 876c75d..13659f2 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -1,4 +1,5 @@ #include "builtin.h" +#include #include using std::stringstream; @@ -42,12 +43,12 @@ void SpecialOptIf::prepare(Cons *pc) { pc->cdr->cdr->skip = true; } -void SpecialOptIf::pre_call(ArgList *arg_list, Cons *pc, +void SpecialOptIf::pre_call(ArgList *args, Cons *pc, Environment *envt) { pc = dynamic_cast(pc->car); // Condition evaluated and the decision is made state = 1; - if (arg_list->cdr->car->is_true()) + if (args->cdr->car->is_true()) { pc = pc->cdr; pc->skip = true; @@ -65,23 +66,23 @@ void SpecialOptIf::pre_call(ArgList *arg_list, Cons *pc, } } -EvalObj *SpecialOptIf::post_call(ArgList *arg_list, Cons *pc, +EvalObj *SpecialOptIf::post_call(ArgList *args, Cons *pc, Environment *envt) { // Value already evaluated, so just return it - return arg_list->cdr->car; + return args->cdr->car; } -Cons *SpecialOptIf::call(ArgList *arg_list, Environment * &envt, +Cons *SpecialOptIf::call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr) { - Cons *ret_addr = dynamic_cast(*top_ptr); + Cons *ret_addr = dynamic_cast(*top_ptr)->addr; if (state) { - *top_ptr = post_call(arg_list, ret_addr, envt); + *top_ptr++ = post_call(args, ret_addr, envt); return ret_addr->next; // Move to the next instruction } else { - pre_call(arg_list, ret_addr, envt); - top_ptr++; + pre_call(args, ret_addr, envt); + top_ptr += 2; // Undo pop and invoke again return dynamic_cast(ret_addr->car)->next; } @@ -94,8 +95,8 @@ string SpecialOptIf::_debug_repr() { return ext_repr(); } SpecialOptLambda::SpecialOptLambda() : SpecialOptObj() {} #define FILL_MARKS(pc, flag) \ - for (pc = pc->cdr; pc != empty_list; pc = pc->cdr) \ - pc->skip = flag + for (Cons *ptr = pc->cdr; ptr != empty_list; ptr = ptr->cdr) \ + ptr->skip = flag void SpecialOptLambda::prepare(Cons *pc) { //TODO check number of arguments @@ -103,9 +104,9 @@ void SpecialOptLambda::prepare(Cons *pc) { FILL_MARKS(pc, true); } -Cons *SpecialOptLambda::call(ArgList *arg_list, Environment * &envt, +Cons *SpecialOptLambda::call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr) { - Cons *ret_addr = dynamic_cast(*top_ptr); + Cons *ret_addr = dynamic_cast(*top_ptr)->addr; Cons *pc = dynamic_cast(ret_addr->car); SymbolList *para_list = dynamic_cast(pc->cdr->car); // parameter list // Clear the flag to avoid side-effects (e.g. proc calling) @@ -114,9 +115,9 @@ Cons *SpecialOptLambda::call(ArgList *arg_list, Environment * &envt, // store a list of expressions inside ASTList *body = pc->cdr->cdr; // Truncate the expression list for (Cons *ptr = body; ptr != empty_list; ptr = ptr->cdr) - ptr->next = NULL; // Make each expression a orphan + ptr->next = NULL; // Make each expression an orphan - *top_ptr = new ProcObj(body, envt, para_list); + *top_ptr++ = new ProcObj(body, envt, para_list); return ret_addr->next; // Move to the next instruction } @@ -134,9 +135,9 @@ void SpecialOptDefine::prepare(Cons *pc) { } // Procedure definition else FILL_MARKS(pc, true); // Skip all parts } -Cons *SpecialOptDefine::call(ArgList *arg_list, Environment * &envt, +Cons *SpecialOptDefine::call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr) { - Cons *ret_addr = dynamic_cast(*top_ptr); + Cons *ret_addr = dynamic_cast(*top_ptr)->addr; Cons *pc = dynamic_cast(ret_addr->car); EvalObj *obj; SymObj *id; @@ -144,7 +145,7 @@ Cons *SpecialOptDefine::call(ArgList *arg_list, Environment * &envt, if (pc->cdr->car->is_simple_obj()) { id = dynamic_cast(pc->cdr->car); - obj = arg_list->cdr->car; + obj = args->cdr->car; } else { @@ -160,7 +161,7 @@ Cons *SpecialOptDefine::call(ArgList *arg_list, Environment * &envt, obj = new ProcObj(body, envt, para_list); } envt->add_binding(id, obj); - *top_ptr = obj; + *top_ptr++ = new UnspecObj(); return ret_addr->next; } string SpecialOptDefine::ext_repr() { return string("#"); } @@ -174,18 +175,71 @@ void SpecialOptSet::prepare(Cons *pc) { pc->cdr->cdr->skip = false; } -Cons *SpecialOptSet::call(ArgList *arg_list, Environment * &envt, +Cons *SpecialOptSet::call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr) { - Cons *ret_addr = dynamic_cast(*top_ptr); + 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, arg_list->cdr->car); - *top_ptr = new UnspecObj(); + envt->add_binding(id, args->cdr->car); + *top_ptr++ = new UnspecObj(); return ret_addr->next; } +SpecialOptSet::SpecialOptSet() {} string SpecialOptSet::ext_repr() { return string("#"); } #ifdef DEBUG string SpecialOptSet::_debug_repr() { return ext_repr(); } #endif + +EvalObj *builtin_plus(ArgList *args) { + // TODO: type conversion and proper arithmetic + int res = 0; + for (Cons *ptr = args; ptr != empty_list; ptr = ptr->cdr) + res += dynamic_cast(ptr->car)->val; + return new IntObj(res); +} + +EvalObj *builtin_minus(ArgList *args) { + // TODO: type conversion and proper arithmetic + int res = dynamic_cast(args->car)->val; + for (Cons *ptr = args->cdr; ptr != empty_list; ptr = ptr->cdr) + res -= dynamic_cast(ptr->car)->val; + return new IntObj(res); +} + +EvalObj *builtin_times(ArgList *args) { + // TODO: type conversion and proper arithmetic + int res = 1; + for (Cons *ptr = args; ptr != empty_list; ptr = ptr->cdr) + res *= dynamic_cast(ptr->car)->val; + return new IntObj(res); +} + +EvalObj *builtin_div(ArgList *args) { + // TODO: type conversion and proper arithmetic + int res = dynamic_cast(args->car)->val; + for (Cons *ptr = args->cdr; ptr != empty_list; ptr = ptr->cdr) + res /= dynamic_cast(ptr->car)->val; + return new IntObj(res); +} + +EvalObj *builtin_lt(ArgList *args) { + return new BoolObj(dynamic_cast(args->car)->val < + dynamic_cast(args->cdr->car)->val); +} + +EvalObj *builtin_gt(ArgList *args) { + return new BoolObj(dynamic_cast(args->car)->val > + dynamic_cast(args->cdr->car)->val); +} + +EvalObj *builtin_arithmetic_eq(ArgList *args) { + return new BoolObj(dynamic_cast(args->car)->val == + dynamic_cast(args->cdr->car)->val); +} + +EvalObj *builtin_display(ArgList *args) { + printf("%s\n", args->car->ext_repr().c_str()); + return new UnspecObj(); +} diff --git a/builtin.h b/builtin.h index a4468ae..8b448cf 100644 --- a/builtin.h +++ b/builtin.h @@ -10,9 +10,8 @@ using std::string; * Booleans */ class BoolObj: public EvalObj { - private: - bool val; /**< true for #t, false for #f */ public: + bool val; /**< true for #t, false for #f */ BoolObj(bool); bool is_true(); /**< Override EvalObj `is_true()` */ #ifdef DEBUG @@ -26,9 +25,8 @@ class BoolObj: public EvalObj { * Will be removed in the future */ class IntObj: public NumberObj { - private: - int val; public: + int val; IntObj(int); #ifdef DEBUG string _debug_repr(); @@ -40,9 +38,8 @@ class IntObj: public NumberObj { * Floating point numbers */ class FloatObj: public NumberObj { - private: - double val; public: + double val; FloatObj(double); #ifdef DEBUG string _debug_repr(); @@ -61,18 +58,18 @@ class SpecialOptIf: public SpecialOptObj { * The evaluator will call this after the exp is evaluated. * And this function tells the evaluator which of and * should be evaluted. */ - void pre_call(ArgList *arg_list, Cons *pc, + void pre_call(ArgList *args, Cons *pc, Environment *envt); /** The system will call this again after the desired result is * evaluated, so just return it to let the evaluator know the it's the * answer. */ - EvalObj *post_call(ArgList *arg_list, Cons *pc, + EvalObj *post_call(ArgList *args, Cons *pc, Environment *envt); public: SpecialOptIf(); void prepare(Cons *pc); - Cons *call(ArgList *arg_list, Environment * &envt, + Cons *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); #ifdef DEBUG string _debug_repr(); @@ -87,7 +84,7 @@ class SpecialOptLambda: public SpecialOptObj { public: SpecialOptLambda(); void prepare(Cons *pc); - Cons *call(ArgList *arg_list, Environment * &envt, + Cons *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); #ifdef DEBUG @@ -103,7 +100,7 @@ class SpecialOptDefine: public SpecialOptObj { public: SpecialOptDefine(); void prepare(Cons *pc); - Cons *call(ArgList *arg_list, Environment * &envt, + Cons *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); #ifdef DEBUG string _debug_repr(); @@ -118,7 +115,7 @@ class SpecialOptSet: public SpecialOptObj { public: SpecialOptSet(); void prepare(Cons *pc); - Cons *call(ArgList *arg_list, Environment * &envt, + Cons *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); #ifdef DEBUG string _debug_repr(); @@ -126,4 +123,13 @@ class SpecialOptSet: public SpecialOptObj { string ext_repr(); }; +EvalObj *builtin_plus(ArgList *); +EvalObj *builtin_minus(ArgList *); +EvalObj *builtin_times(ArgList *); +EvalObj *builtin_div(ArgList *); +EvalObj *builtin_lt(ArgList *); +EvalObj *builtin_gt(ArgList *); +EvalObj *builtin_arithmetic_eq(ArgList *); +EvalObj *builtin_display(ArgList *); + #endif diff --git a/eval.cpp b/eval.cpp new file mode 100644 index 0000000..279f8c4 --- /dev/null +++ b/eval.cpp @@ -0,0 +1,91 @@ +#include "eval.h" +#include "builtin.h" +#include + +extern Cons *empty_list; +const int EVAL_STACK_SIZE = 65536; +FrameObj *eval_stack[EVAL_STACK_SIZE]; + +void Evaluator::add_builtin_routines() { + +#define ADD_ENTRY(name, rout) \ + envt->add_binding(new SymObj(name), rout) + + ADD_ENTRY("+", new BuiltinProcObj(builtin_plus, "+")); + ADD_ENTRY("-", new BuiltinProcObj(builtin_minus, "-")); + ADD_ENTRY("*", new BuiltinProcObj(builtin_times, "*")); + ADD_ENTRY("/", new BuiltinProcObj(builtin_div, "/")); + ADD_ENTRY(">", new BuiltinProcObj(builtin_gt, ">")); + ADD_ENTRY("<", new BuiltinProcObj(builtin_lt, "<")); + ADD_ENTRY("=", new BuiltinProcObj(builtin_arithmetic_eq, "=")); + ADD_ENTRY("display", new BuiltinProcObj(builtin_display, "display")); + ADD_ENTRY("if", new SpecialOptIf()); + ADD_ENTRY("lambda", new SpecialOptLambda()); + ADD_ENTRY("define", new SpecialOptDefine()); + ADD_ENTRY("set", new SpecialOptSet()); +} + +Evaluator::Evaluator() { + envt = new Environment(); // Top-level Environment + add_builtin_routines(); +} + +void push(Cons * &pc, FrameObj ** &top_ptr, Environment *envt) { + if (pc->car->is_simple_obj()) // Not an opt invocation + { + *top_ptr = envt->get_obj(pc->car); // Objectify the symbol + dynamic_cast(*top_ptr)->prepare(pc); + top_ptr++; + pc = pc->next; // Move to the next instruction + } + else // Operational Invocation + { + *top_ptr++ = new RetAddr(pc); // Push the return address + pc = dynamic_cast(pc->car); // Go deeper to enter the call + } +} + +void stack_print(FrameObj **top_ptr) { + for (FrameObj **ptr = eval_stack; ptr != top_ptr; ptr++) + printf("%s\n", (*ptr)->_debug_repr().c_str()); + puts(""); +} + +EvalObj *Evaluator::run_expr(Cons *prog) { + FrameObj **top_ptr = eval_stack; + Cons *pc = prog; + Continuation *cont = NULL; + // envt is this->envt + push(pc, top_ptr, envt); + + while((*eval_stack)->is_ret_addr()) + { + for (; pc && pc->skip; pc = pc->next); + if (pc) + push(pc, top_ptr, envt); + else + { + Cons *args = empty_list; + while (!(*(--top_ptr))->is_ret_addr()) + args = new Cons(dynamic_cast(*top_ptr), args); + RetAddr *ret_addr = dynamic_cast(*top_ptr); + if (!ret_addr->addr) + { + Cons *nexp = cont->proc_body->cdr; + cont->proc_body = nexp; + if (nexp == empty_list) + { + *top_ptr = args->car; + envt = cont->envt; + pc = cont->pc->next; + cont = cont->prev_cont; + } + else pc = nexp; + top_ptr++; + } + else + pc = dynamic_cast(args->car)->call(args, envt, cont, top_ptr); + } + } + return dynamic_cast(*(eval_stack)); +} diff --git a/eval.h b/eval.h new file mode 100644 index 0000000..0ec08f3 --- /dev/null +++ b/eval.h @@ -0,0 +1,14 @@ +#ifndef EVAL_H +#define EVAL_H +#include "model.h" + +class Evaluator { + private: + Environment *envt; + void add_builtin_routines(); + public: + Evaluator(); + EvalObj *run_expr(Cons *prog); +}; + +#endif diff --git a/main.cpp b/main.cpp index 6a86fe5..f32dac3 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,7 @@ #include "model.h" #include "builtin.h" #include "parser.h" +#include "eval.h" #include #ifdef DEBUG @@ -16,6 +17,13 @@ void tree_print(Cons *ptr) { int main() { Tokenizor *tk = new Tokenizor(); ASTGenerator *ast = new ASTGenerator(); - Cons *tree = ast->absorb(tk); - tree_print(tree); + Evaluator *eval = new Evaluator(); + + while (1) + { + Cons *tree = ast->absorb(tk); + if (!tree) break; + //tree_print(tree); + printf("%s\n", eval->run_expr(tree)->ext_repr().c_str()); + } } 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) {} diff --git a/model.h b/model.h index b8cd873..6105119 100644 --- a/model.h +++ b/model.h @@ -23,6 +23,7 @@ class FrameObj { protected: ClassType ftype; // avoid the use of dynamic_cast to improve efficiency public: + FrameObj(ClassType); virtual ~FrameObj() {} bool is_ret_addr(); #ifdef DEBUG @@ -36,10 +37,10 @@ class Cons; * Objects that represents a value in evaluation */ class EvalObj : public FrameObj { - private: - ClassType otype; // avoid the use of dynamic_cast to improve efficiency public: - EvalObj(); + ClassType otype; // avoid the use of dynamic_cast to improve efficiency + + EvalObj(ClassType _otype = CLS_SIM_OBJ); bool is_simple_obj(); /** External representation of this object */ virtual void prepare(Cons *pc); @@ -136,13 +137,13 @@ class OptObj: public EvalObj { OptObj(); /** * The function is called when an operation is needed. - * @param arg_list The argument list (the first one is the opt itself) + * @param args The argument list (the first one is the opt itself) * @param envt The current environment (may be modified) * @param cont The current continuation (may be modified) * @param top_ptr Pointing to the top of the stack (may be modified) * @return New value for pc register */ - virtual Cons *call(ArgList *arg_list, Environment * &envt, + virtual Cons *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr) = 0; }; @@ -159,7 +160,7 @@ class ProcObj: public OptObj { Environment *envt; ProcObj(ASTList *, Environment *, SymbolList *); - Cons *call(ArgList *arg_list, Environment * &envt, + Cons *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); #ifdef DEBUG string _debug_repr(); @@ -185,9 +186,13 @@ class BuiltinProcObj: public OptObj { BuiltinProc handler; string name; public: - BuiltinProcObj(BuiltinProc, const string &); - Cons *call(ArgList *arg_list, Environment * &envt, + BuiltinProcObj(BuiltinProc, string); + Cons *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); +#ifdef DEBUG + string _debug_repr(); +#endif + string ext_repr(); }; /** @class NumberObj @@ -211,7 +216,7 @@ class Environment { public: Environment(Environment * = NULL); void add_binding(SymObj *, EvalObj *); - EvalObj *get_obj(SymObj *); + EvalObj *get_obj(EvalObj *); bool has_obj(SymObj *); }; @@ -221,10 +226,9 @@ class Continuation { Environment *envt; Cons *pc; ASTList *proc_body; - unsigned int body_cnt; Continuation(Environment *, Cons *, Continuation *, - ASTList *, unsigned int = 0); + ASTList *); }; #endif diff --git a/parser.cpp b/parser.cpp index 0143700..e1724c3 100644 --- a/parser.cpp +++ b/parser.cpp @@ -79,7 +79,7 @@ Cons *ASTGenerator::absorb(Tokenizor *tk) { if (top_ptr > parse_stack && *parse_stack) return new Cons(*(top_ptr - 1), empty_list); string token; - tk->get_token(token); + if (!tk->get_token(token)) return NULL; if (token == "(") *top_ptr++ = NULL; // Make the beginning of a new level else if (token == ")") diff --git a/prototype/sketch.py b/prototype/sketch.py index c51dad0..4fd5be1 100755 --- a/prototype/sketch.py +++ b/prototype/sketch.py @@ -535,6 +535,6 @@ while True: cmd = sys.stdin.readline() t.feed(cmd) try: - print e.run_expr(exp).ext_repr() + pdb.run("print e.run_expr(exp).ext_repr()") except Exception as exc: print exc -- cgit v1.2.3-70-g09d2