From 3753b3c4bed58949588a46d4c807a0c0045e8f22 Mon Sep 17 00:00:00 2001 From: Teddy Date: Thu, 8 Aug 2013 20:18:23 +0800 Subject: new ext_repr() approach --- Makefile | 2 +- builtin.cpp | 96 +++++++++++++++++++++++++-------------------- builtin.h | 20 +++++----- main.cpp | 6 +-- model.cpp | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- model.h | 64 ++++++++++++++++++++++-------- parser.cpp | 2 +- 7 files changed, 225 insertions(+), 92 deletions(-) diff --git a/Makefile b/Makefile index 3a3f37a..07feba0 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ main: main.o parser.o builtin.o model.o eval.o exc.o consts.o g++ -o main $^ -pg -lgmp .cpp.o: - g++ $< -c -g -pg -DDEBUG -DGMP_SUPPORT + g++ $< -c -g -pg -DGMP_SUPPORT clean: rm -f *.o diff --git a/builtin.cpp b/builtin.cpp index 6579e98..adf069d 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -35,7 +35,7 @@ bool is_list(Pair *ptr) { if (ptr == empty_list) return true; EvalObj *nptr; for (;;) - if ((nptr = ptr->cdr)->is_cons_obj()) + if ((nptr = ptr->cdr)->is_pair_obj()) ptr = TO_PAIR(nptr); else break; return ptr->cdr == empty_list; @@ -227,8 +227,8 @@ bool CompNumObj::eq(NumObj *_r) { } -string CompNumObj::ext_repr() { - return double_to_str(real) + double_to_str(imag, true) + "i"; +ReprCons *CompNumObj::get_repr_cons() { + return new ReprStr(double_to_str(real) + double_to_str(imag, true) + "i"); } #undef A @@ -299,8 +299,8 @@ bool RealNumObj::gt(NumObj *_r) { return real > static_cast(_r)->real; } -string RealNumObj::ext_repr() { - return double_to_str(real); +ReprCons *RealNumObj::get_repr_cons() { + return new ReprStr(double_to_str(real)); } ExactNumObj::ExactNumObj(NumLvl level) : NumObj(level, true) {} @@ -448,11 +448,11 @@ bool RatNumObj::eq(NumObj *_r) { #endif } -string RatNumObj::ext_repr() { +ReprCons *RatNumObj::get_repr_cons() { #ifndef GMP_SUPPORT - return int_to_str(A) + "/" + int_to_str(B); + return new ReprStr(int_to_str(A) + "/" + int_to_str(B)); #else - return val.get_str(); + return new ReprStr(val.get_str()); #endif } @@ -529,11 +529,11 @@ bool IntNumObj::eq(NumObj *_r) { return val == static_cast(_r)->val; } -string IntNumObj::ext_repr() { +ReprCons *IntNumObj::get_repr_cons() { #ifndef GMP_SUPPORT - return int_to_str(val); + return new ReprStr(int_to_str(val)); #else - return val.get_str(); + return new ReprStr(val.get_str()); #endif } @@ -544,7 +544,7 @@ void SpecialOptIf::prepare(Pair *pc) { throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS) state = 0; // Prepared - if (pc->cdr->is_cons_obj()) + if (pc->cdr->is_pair_obj()) pc = TO_PAIR(pc->cdr); else IF_EXP_ERR; @@ -553,7 +553,7 @@ void SpecialOptIf::prepare(Pair *pc) { pc->skip = false; - if (pc->cdr->is_cons_obj()) + if (pc->cdr->is_pair_obj()) pc = TO_PAIR(pc->cdr); else IF_EXP_ERR; @@ -563,7 +563,7 @@ void SpecialOptIf::prepare(Pair *pc) { pc->skip = true; if (pc->cdr != empty_list) { - if (pc->cdr->is_cons_obj()) + if (pc->cdr->is_pair_obj()) { TO_PAIR(pc->cdr)->skip = true; if (TO_PAIR(pc->cdr)->cdr != empty_list) @@ -624,7 +624,9 @@ Pair *SpecialOptIf::call(ArgList *args, Environment * &envt, } } -string SpecialOptIf::ext_repr() { return string("#"); } +ReprCons *SpecialOptIf::get_repr_cons() { + return new ReprStr("#"); +} SpecialOptLambda::SpecialOptLambda() : SpecialOptObj("lambda") {} #define FILL_MARKS(pc, flag) \ @@ -634,7 +636,7 @@ do \ Pair *ptr; \ for (ptr = pc;;) \ { \ - if ((nptr = ptr->cdr)->is_cons_obj()) \ + if ((nptr = ptr->cdr)->is_pair_obj()) \ ptr = TO_PAIR(nptr); \ else break; \ ptr->skip = flag; \ @@ -659,7 +661,7 @@ do \ Pair *ptr; \ for (ptr = TO_PAIR(p);;) \ { \ - if ((nptr = ptr->cdr)->is_cons_obj()) \ + if ((nptr = ptr->cdr)->is_pair_obj()) \ ptr = TO_PAIR(nptr); \ else break; \ CHECK_SYMBOL(ptr->car); \ @@ -706,18 +708,20 @@ Pair *SpecialOptLambda::call(ArgList *args, Environment * &envt, return ret_addr->next; // Move to the next instruction } -string SpecialOptLambda::ext_repr() { return string("#"); } +ReprCons *SpecialOptLambda::get_repr_cons() { + return new ReprStr("#"); +} SpecialOptDefine::SpecialOptDefine() : SpecialOptObj("define") {} void SpecialOptDefine::prepare(Pair *pc) { - if (!pc->cdr->is_cons_obj()) + if (!pc->cdr->is_pair_obj()) throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS); if (TO_PAIR(pc->cdr)->car->is_simple_obj()) // Simple value assignment { pc = TO_PAIR(pc->cdr); - if (!pc->cdr->is_cons_obj()) + if (!pc->cdr->is_pair_obj()) throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS); pc->skip = true; // Skip the identifier TO_PAIR(pc->cdr)->skip = false; @@ -773,17 +777,19 @@ Pair *SpecialOptDefine::call(ArgList *args, Environment * &envt, return ret_addr->next; } -string SpecialOptDefine::ext_repr() { return string("#"); } +ReprCons *SpecialOptDefine::get_repr_cons() { + return new ReprStr("#"); +} void SpecialOptSet::prepare(Pair *pc) { - if (!pc->cdr->is_cons_obj()) + if (!pc->cdr->is_pair_obj()) throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS); pc = TO_PAIR(pc->cdr); pc->skip = true; // Skip the identifier - if (!pc->cdr->is_cons_obj()) + if (!pc->cdr->is_pair_obj()) throw TokenError(name, RUN_ERR_WRONG_NUM_OF_ARGS); pc = TO_PAIR(pc->cdr); @@ -811,7 +817,9 @@ Pair *SpecialOptSet::call(ArgList *args, Environment * &envt, SpecialOptSet::SpecialOptSet() : SpecialOptObj("set!") {} -string SpecialOptSet::ext_repr() { return string("#"); } +ReprCons *SpecialOptSet::get_repr_cons() { + return new ReprStr("#"); +} SpecialOptQuote::SpecialOptQuote() : SpecialOptObj("quote") {} @@ -830,7 +838,9 @@ Pair *SpecialOptQuote::call(ArgList *args, Environment * &envt, return ret_addr->next; } -string SpecialOptQuote::ext_repr() { return string("#"); } +ReprCons *SpecialOptQuote::get_repr_cons() { + return new ReprStr("#"); +} SpecialOptEval::SpecialOptEval() : SpecialOptObj("eval") {} @@ -858,7 +868,9 @@ Pair *SpecialOptEval::call(ArgList *args, Environment * &envt, } } -string SpecialOptEval::ext_repr() { return string("#"); } +ReprCons *SpecialOptEval::get_repr_cons() { + return new ReprStr("#"); +} BUILTIN_PROC_DEF(make_pair) { ARGS_EXACTLY_TWO; @@ -867,7 +879,7 @@ BUILTIN_PROC_DEF(make_pair) { BUILTIN_PROC_DEF(pair_car) { ARGS_EXACTLY_ONE; - if (!args->car->is_cons_obj()) + if (!args->car->is_pair_obj()) throw TokenError("pair", RUN_ERR_WRONG_TYPE); return TO_PAIR(args->car)->car; @@ -875,7 +887,7 @@ BUILTIN_PROC_DEF(pair_car) { BUILTIN_PROC_DEF(pair_cdr) { ARGS_EXACTLY_ONE; - if (!args->car->is_cons_obj()) + if (!args->car->is_pair_obj()) throw TokenError("pair", RUN_ERR_WRONG_TYPE); return TO_PAIR(args->car)->cdr; @@ -1054,12 +1066,12 @@ BUILTIN_PROC_DEF(is_boolean) { BUILTIN_PROC_DEF(is_pair) { ARGS_EXACTLY_ONE; - return new BoolObj(args->car->is_cons_obj()); + return new BoolObj(args->car->is_pair_obj()); } BUILTIN_PROC_DEF(pair_set_car) { ARGS_EXACTLY_TWO; - if (!args->car->is_cons_obj()) + if (!args->car->is_pair_obj()) throw TokenError("pair", RUN_ERR_WRONG_TYPE); TO_PAIR(args->car)->car = TO_PAIR(args->cdr)->car; return new UnspecObj(); @@ -1067,7 +1079,7 @@ BUILTIN_PROC_DEF(pair_set_car) { BUILTIN_PROC_DEF(pair_set_cdr) { ARGS_EXACTLY_TWO; - if (!args->car->is_cons_obj()) + if (!args->car->is_pair_obj()) throw TokenError("pair", RUN_ERR_WRONG_TYPE); TO_PAIR(args->car)->cdr = TO_PAIR(args->cdr)->car; return new UnspecObj(); @@ -1082,13 +1094,13 @@ BUILTIN_PROC_DEF(is_list) { ARGS_EXACTLY_ONE; if (args->car == empty_list) return new BoolObj(true); - if (!args->car->is_cons_obj()) + if (!args->car->is_pair_obj()) return new BoolObj(false); args = TO_PAIR(args->car); EvalObj *nptr; for (;;) { - if ((nptr = args->cdr)->is_cons_obj()) + if ((nptr = args->cdr)->is_pair_obj()) args = TO_PAIR(nptr); else break; } @@ -1113,14 +1125,14 @@ BUILTIN_PROC_DEF(length) { ARGS_EXACTLY_ONE; if (args->car == empty_list) return new IntNumObj(mpz_class(0)); - if (!args->car->is_cons_obj()) + if (!args->car->is_pair_obj()) throw TokenError("a list", RUN_ERR_WRONG_TYPE); int num = 0; EvalObj *nptr; for (args = TO_PAIR(args->car);;) { num++; - if ((nptr = args->cdr)->is_cons_obj()) + if ((nptr = args->cdr)->is_pair_obj()) args = TO_PAIR(nptr); else break; @@ -1140,7 +1152,7 @@ Pair *copy_list(Pair *src, EvalObj * &tail) { { TO_PAIR(tail)->cdr = new Pair(*src); tail = TO_PAIR(TO_PAIR(tail)->cdr); - if ((nptr = src->cdr)->is_cons_obj()) + if ((nptr = src->cdr)->is_pair_obj()) src = TO_PAIR(nptr); else break; } @@ -1154,18 +1166,18 @@ BUILTIN_PROC_DEF(append) { if (tail == empty_list) { head = args->car; - if (head->is_cons_obj()) + if (head->is_pair_obj()) head = copy_list(TO_PAIR(head), tail); else tail = head; } else { - if (tail->is_cons_obj()) + if (tail->is_pair_obj()) { Pair *prev = TO_PAIR(tail); if (prev->cdr != empty_list) throw TokenError("empty list", RUN_ERR_WRONG_TYPE); - if (args->car->is_cons_obj()) + if (args->car->is_pair_obj()) prev->cdr = copy_list(TO_PAIR(args->car), tail); else prev->cdr = args->car; @@ -1182,7 +1194,7 @@ BUILTIN_PROC_DEF(reverse) { Pair *tail = empty_list; EvalObj *ptr; for (ptr = args->car; - ptr->is_cons_obj(); ptr = TO_PAIR(ptr)->cdr) + ptr->is_pair_obj(); ptr = TO_PAIR(ptr)->cdr) tail = new Pair(TO_PAIR(ptr)->car, tail); if (ptr != empty_list) throw TokenError("a list", RUN_ERR_WRONG_TYPE); @@ -1200,12 +1212,12 @@ BUILTIN_PROC_DEF(list_tail) { throw TokenError("a non-negative integer", RUN_ERR_WRONG_TYPE); EvalObj *ptr; for (i = 0, ptr = args->car; - ptr->is_cons_obj(); ptr = TO_PAIR(ptr)->cdr, i++) + ptr->is_pair_obj(); ptr = TO_PAIR(ptr)->cdr, i++) if (i == k) break; if (i != k) throw TokenError("a pair", RUN_ERR_WRONG_TYPE); EvalObj *tail; - if (ptr->is_cons_obj()) + if (ptr->is_pair_obj()) return copy_list(TO_PAIR(ptr), tail); else return ptr; diff --git a/builtin.h b/builtin.h index 589e7a9..2633ed8 100644 --- a/builtin.h +++ b/builtin.h @@ -40,7 +40,7 @@ class CompNumObj: public InexactNumObj { bool lt(NumObj *r); bool gt(NumObj *r); bool eq(NumObj *r); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class RealNumObj @@ -65,7 +65,7 @@ class RealNumObj: public InexactNumObj { bool lt(NumObj *r); bool gt(NumObj *r); bool eq(NumObj *r); - string ext_repr(); + ReprCons *get_repr_cons(); }; @@ -105,7 +105,7 @@ class RatNumObj: public ExactNumObj { bool lt(NumObj *r); bool gt(NumObj *r); bool eq(NumObj *r); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class IntNumObj @@ -138,7 +138,7 @@ class IntNumObj: public ExactNumObj { bool lt(NumObj *r); bool gt(NumObj *r); bool eq(NumObj *r); - string ext_repr(); + ReprCons *get_repr_cons(); }; @@ -165,7 +165,7 @@ class SpecialOptIf: public SpecialOptObj { void prepare(Pair *pc); Pair *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class SpecialOptLambda @@ -178,7 +178,7 @@ class SpecialOptLambda: public SpecialOptObj { Pair *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class SpecialOptDefine @@ -190,7 +190,7 @@ class SpecialOptDefine: public SpecialOptObj { void prepare(Pair *pc); Pair *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class SpecialOptSet @@ -202,7 +202,7 @@ class SpecialOptSet: public SpecialOptObj { void prepare(Pair *pc); Pair *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class SpecialOptLambda @@ -215,7 +215,7 @@ class SpecialOptQuote: public SpecialOptObj { Pair *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class SpecialOptEval @@ -230,7 +230,7 @@ class SpecialOptEval: public SpecialOptObj { Pair *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); - string ext_repr(); + ReprCons *get_repr_cons(); }; #define BUILTIN_PROC_DEF(func)\ diff --git a/main.cpp b/main.cpp index 810537d..db635e8 100644 --- a/main.cpp +++ b/main.cpp @@ -5,12 +5,8 @@ #include "exc.h" #include -#ifdef DEBUG -extern Pair *empty_list; -#endif - int main() { - //freopen("in.scm", "r", stdin); + freopen("in.scm", "r", stdin); Tokenizor *tk = new Tokenizor(); ASTGenerator *ast = new ASTGenerator(); Evaluator *eval = new Evaluator(); diff --git a/model.cpp b/model.cpp index b652d47..4502577 100644 --- a/model.cpp +++ b/model.cpp @@ -3,13 +3,15 @@ #include "exc.h" #include "consts.h" +static ReprCons *repr_stack[REPR_STACK_SIZE]; + FrameObj::FrameObj(ClassType _ftype) : ftype(_ftype) {} EmptyList *empty_list = new EmptyList(); EmptyList::EmptyList() : Pair(NULL, NULL) {} -string EmptyList::ext_repr() { return string("()"); } +ReprCons *EmptyList::get_repr_cons() { return new ReprStr("()"); } bool FrameObj::is_ret_addr() { return ftype & CLS_RET_ADDR; @@ -35,7 +37,7 @@ bool EvalObj::is_opt_obj() { return otype & CLS_OPT_OBJ; } -bool EvalObj::is_cons_obj() { +bool EvalObj::is_pair_obj() { return this != empty_list && (otype & CLS_CONS_OBJ); } @@ -57,12 +59,40 @@ bool EvalObj::is_true() { } string EvalObj::ext_repr() { + ReprCons **top_ptr = repr_stack; + *top_ptr++ = this->get_repr_cons(); + //printf("%s\n", (this->get_repr_cons())->repr.c_str()); + EvalObj *obj; + while (!(*repr_stack)->done) + { + if ((*(top_ptr - 1))->done) + { + top_ptr--; + obj = (*(top_ptr - 1))->next((*top_ptr)->repr + " "); + if (obj) + *top_ptr++ = obj->get_repr_cons(); + else + { + *(top_ptr - 1) = new ReprStr((*(top_ptr - 1))->repr); + } + } + else + { + obj = (*(top_ptr - 1))->next(""); + *top_ptr++ = obj->get_repr_cons(); + } + } + return (*repr_stack)->repr; } Pair::Pair(EvalObj *_car, EvalObj *_cdr) : EvalObj(CLS_CONS_OBJ), car(_car), cdr(_cdr), skip(false), next(NULL) {} +ReprCons *Pair::get_repr_cons() { + return new ListReprCons(this); +} + RetAddr::RetAddr(Pair *_addr) : FrameObj(CLS_RET_ADDR), addr(_addr) {} ParseBracket::ParseBracket(unsigned char _btype) : @@ -70,12 +100,16 @@ ParseBracket::ParseBracket(unsigned char _btype) : UnspecObj::UnspecObj() : EvalObj(CLS_SIM_OBJ) {} -string UnspecObj::ext_repr() { return string("#"); } +ReprCons *UnspecObj::get_repr_cons() { + return new ReprStr("#"); +} SymObj::SymObj(const string &str) : EvalObj(CLS_SIM_OBJ | CLS_SYM_OBJ), val(str) {} -string SymObj::ext_repr() { return val; } +ReprCons *SymObj::get_repr_cons() { + return new ReprStr(val); +} OptObj::OptObj() : EvalObj(CLS_SIM_OBJ | CLS_OPT_OBJ) {} @@ -95,7 +129,7 @@ Pair *ProcObj::call(ArgList *args, Environment * &genvt, // static_cast because the params is already checked EvalObj *ppar, *nptr; for (ppar = params; - ppar->is_cons_obj(); + ppar->is_pair_obj(); ppar = TO_PAIR(ppar)->cdr) { if ((nptr = args->cdr) != empty_list) @@ -115,7 +149,9 @@ Pair *ProcObj::call(ArgList *args, Environment * &genvt, return body; // Move pc to the proc entry point } -string ProcObj::ext_repr() { return string("#"); } +ReprCons *ProcObj::get_repr_cons() { + return new ReprStr("#"); +} SpecialOptObj::SpecialOptObj(string _name) : OptObj(), name(_name) {} @@ -123,7 +159,9 @@ BoolObj::BoolObj(bool _val) : EvalObj(CLS_SIM_OBJ | CLS_BOOL_OBJ), val(_val) {} bool BoolObj::is_true() { return val; } -string BoolObj::ext_repr() { return string(val ? "#t" : "#f"); } +ReprCons *BoolObj::get_repr_cons() { + return new ReprStr(val ? "#t" : "#f"); +} BoolObj *BoolObj::from_string(string repr) { if (repr.length() != 2 || repr[0] != '#') @@ -142,7 +180,9 @@ bool NumObj::is_exact() { return exactness; } StrObj::StrObj(string _str) : EvalObj(CLS_SIM_OBJ | CLS_STR_OBJ), str(_str) {} -string StrObj::ext_repr() { return str; } +ReprCons *StrObj::get_repr_cons() { + return new ReprStr(str); +} CharObj::CharObj(char _ch) : EvalObj(CLS_SIM_OBJ | CLS_CHAR_OBJ), ch(_ch) {} @@ -157,16 +197,24 @@ CharObj *CharObj::from_string(string repr) { throw TokenError(char_name, RUN_ERR_UNKNOWN_CHAR_NAME); } -string CharObj::ext_repr() { +ReprCons *CharObj::get_repr_cons() { string val = ""; if (ch == ' ') val = "space"; else if (ch == '\n') val = "newline"; else val += ch; - return "#\\" + val; + return new ReprStr("#\\" + val); } VecObj::VecObj() : EvalObj(CLS_SIM_OBJ | CLS_VECT_OBJ) {} +EvalObj *VecObj::get_obj(int idx) { + return vec[idx]; +} + +int VecObj::get_size() { + return vec.end() - vec.begin(); +} + void VecObj::resize(int new_size) { vec.resize(new_size); } @@ -175,6 +223,10 @@ void VecObj::push_back(EvalObj *new_elem) { vec.push_back(new_elem); } +ReprCons *VecObj::get_repr_cons() { + return new VectReprCons(this); +} + StrObj *StrObj::from_string(string repr) { size_t len = repr.length(); if (repr[0] == '\"' && repr[len - 1] == '\"') @@ -193,8 +245,8 @@ Pair *BuiltinProcObj::call(ArgList *args, Environment * &envt, return ret_addr->next; // Move to the next instruction } -string BuiltinProcObj::ext_repr() { - return "#"; +ReprCons *BuiltinProcObj::get_repr_cons() { + return new ReprStr("#"); } Environment::Environment(Environment *_prev_envt) : prev_envt(_prev_envt) {} @@ -221,7 +273,50 @@ EvalObj *Environment::get_obj(EvalObj *obj) { } Continuation::Continuation(Environment *_envt, Pair *_pc, - Continuation *_prev_cont, - Pair *_proc_body) : - envt(_envt), pc(_pc), prev_cont(_prev_cont), - proc_body(_proc_body) {} + Continuation *_prev_cont, + Pair *_proc_body) : + envt(_envt), pc(_pc), prev_cont(_prev_cont), + proc_body(_proc_body) {} + +ReprCons::ReprCons(bool _done) : done(_done) {} +ReprStr::ReprStr(string _repr) : ReprCons(true) { repr = _repr; } +EvalObj *ReprStr::next(const string &prev) { + throw NormalError(INT_ERR); +} + +ListReprCons::ListReprCons(Pair *_ptr) : + ReprCons(false), ptr(_ptr) { repr = "("; } + +EvalObj *ListReprCons::next(const string &prev) { + repr += prev; + EvalObj *res; + if (ptr->is_simple_obj()) + { + repr += ". "; + res = ptr; + ptr = empty_list; + return res; + } + if (ptr == empty_list) + { + *repr.rbegin() = ')'; + return NULL; + } + + res = TO_PAIR(ptr)->car; + ptr = TO_PAIR(ptr)->cdr; + return res; +} + +VectReprCons::VectReprCons(VecObj *_ptr) : + ReprCons(false), ptr(_ptr), idx(0) { repr = "#("; } + +EvalObj *VectReprCons::next(const string &prev) { + repr += prev; + if (idx == ptr->get_size()) + { + *repr.rbegin() = ')'; + return NULL; + } + else return ptr->get_obj(idx++); +} diff --git a/model.h b/model.h index 32a1785..062a61d 100644 --- a/model.h +++ b/model.h @@ -18,6 +18,8 @@ typedef unsigned char NumLvl; const int CLS_RET_ADDR = 1 << 0; const int CLS_EVAL_OBJ = 1 << 1; const int CLS_PAR_BRA = 1 << 2; +const int CLS_REPR_CONS = 1 << 3; +const int CLS_REPR_STR = 1 << 4; const int CLS_SIM_OBJ = 1 << 0; const int CLS_CONS_OBJ = 1 << 1; @@ -29,6 +31,7 @@ const int CLS_CHAR_OBJ = 1 << 6; const int CLS_STR_OBJ = 1 << 7; const int CLS_VECT_OBJ = 1 << 8; +const int REPR_STACK_SIZE = 65536; #define TO_PAIR(ptr) \ (static_cast(ptr)) @@ -65,6 +68,7 @@ class FrameObj { class Pair; +class ReprCons; /** @class EvalObj * Objects that represents a value in evaluation */ @@ -93,7 +97,7 @@ class EvalObj : public FrameObj { /** Check if the object is an operator */ bool is_opt_obj(); /** Check if the object is a Pair */ - bool is_cons_obj(); + bool is_pair_obj(); /** Check if the object is a number */ bool is_num_obj(); /** Check if the object is a boolean */ @@ -101,11 +105,13 @@ class EvalObj : public FrameObj { ClassType get_otype(); virtual void prepare(Pair *pc); /** Any EvalObj has its external representation */ - virtual string ext_repr(); + string ext_repr(); /** Always true for all EvalObjs except BoolObj */ virtual bool is_true(); + virtual ReprCons *get_repr_cons() = 0; }; +class ListReprCons; /** @class Pair * Pair construct, which can be used to represent a list, or further * more, a syntax tree @@ -119,6 +125,7 @@ class Pair : public EvalObj { Pair* next; /**< The next branch in effect */ Pair(EvalObj *car, EvalObj *cdr); /**< Create a Pair (car . cdr) */ + ReprCons *get_repr_cons(); }; /** @class EmptyList @@ -127,7 +134,7 @@ class Pair : public EvalObj { class EmptyList: public Pair { public: EmptyList(); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class RetAddr @@ -141,13 +148,36 @@ class RetAddr : public FrameObj { RetAddr(Pair *addr); }; -class ReprConstructor : public FrameObj { - virtual EvalObj *next(); +class ReprCons { + public: + bool done; + string repr; + ReprCons(bool done); + virtual EvalObj *next(const string &prev) = 0; +}; + +class ReprStr : public ReprCons { + public: + ReprStr(string repr); + EvalObj *next(const string &prev); }; -class ExtRepr : public FrameObj { +class ListReprCons : public ReprCons { + private: + EvalObj *ptr; public: - string repr; + ListReprCons(Pair *ptr); + EvalObj *next(const string &prev); +}; + +class VecObj; +class VectReprCons : public ReprCons { + private: + VecObj *ptr; + int idx; + public: + VectReprCons(VecObj *ptr); + EvalObj *next(const string &prev); }; /** @class ParseBracket @@ -166,7 +196,7 @@ class ParseBracket : public FrameObj { class UnspecObj: public EvalObj { public: UnspecObj(); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class SymObj @@ -177,10 +207,7 @@ class SymObj: public EvalObj { string val; SymObj(const string &); -#ifdef DEBUG - string _debug_repr(); -#endif - string ext_repr(); + ReprCons *get_repr_cons(); }; // Everything is cons @@ -222,7 +249,7 @@ class ProcObj: public OptObj { ProcObj(Pair *body, Environment *envt, EvalObj *params); Pair *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class SpecialOptObj @@ -253,7 +280,7 @@ class BuiltinProcObj: public OptObj { BuiltinProcObj(BuiltinProc proc, string name); Pair *call(ArgList *args, Environment * &envt, Continuation * &cont, FrameObj ** &top_ptr); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class BoolObj @@ -264,7 +291,7 @@ class BoolObj: public EvalObj { bool val; /**< true for \#t, false for \#f */ BoolObj(bool); /**< Converts a C bool value to a BoolObj*/ bool is_true(); /**< Override EvalObj `is_true()` */ - string ext_repr(); + ReprCons *get_repr_cons(); /** Try to construct an BoolObj object * @return NULL if failed */ @@ -313,7 +340,7 @@ class StrObj: public EvalObj { * @return NULL if failed */ static StrObj *from_string(string repr); - string ext_repr(); + ReprCons *get_repr_cons(); }; /** @class CharObj @@ -329,7 +356,7 @@ class CharObj: public EvalObj { * @return NULL if failed */ static CharObj *from_string(string repr); - string ext_repr(); + ReprCons *get_repr_cons(); }; @@ -344,10 +371,13 @@ class VecObj: public EvalObj { public: /** Construct a vector object */ VecObj(); + int get_size(); + EvalObj *get_obj(int idx); /** Resize the vector */ void resize(int new_size); /** Add a new element to the rear */ void push_back(EvalObj *new_elem); + ReprCons *get_repr_cons(); }; typedef map Str2EvalObj; diff --git a/parser.cpp b/parser.cpp index b6486cc..ff21b7b 100644 --- a/parser.cpp +++ b/parser.cpp @@ -196,7 +196,7 @@ Pair *ASTGenerator::absorb(Tokenizor *tk) { else { Pair *_lst = new Pair(obj, lst); // Collect the list - _lst->next = lst->is_cons_obj() ? TO_PAIR(lst) : NULL; + _lst->next = lst->is_pair_obj() ? TO_PAIR(lst) : NULL; lst = _lst; } } -- cgit v1.2.3-70-g09d2