aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <[email protected]>2013-08-08 20:18:23 +0800
committerTeddy <[email protected]>2013-08-08 20:18:23 +0800
commit3753b3c4bed58949588a46d4c807a0c0045e8f22 (patch)
treeb08898c19eb7ad9fce46316924651b30bc86c476
parent2c9f05a38ef64cbaeeae6429cd0e245c27944660 (diff)
new ext_repr() approach
-rw-r--r--Makefile2
-rw-r--r--builtin.cpp96
-rw-r--r--builtin.h20
-rw-r--r--main.cpp6
-rw-r--r--model.cpp127
-rw-r--r--model.h64
-rw-r--r--parser.cpp2
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<RealNumObj*>(_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<IntNumObj*>(_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("#<Builtin Macro: if>"); }
+ReprCons *SpecialOptIf::get_repr_cons() {
+ return new ReprStr("#<Builtin Macro: if>");
+}
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("#<Builtin Macro: lambda>"); }
+ReprCons *SpecialOptLambda::get_repr_cons() {
+ return new ReprStr("#<Builtin Macro: lambda>");
+}
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("#<Builtin Macro: define>"); }
+ReprCons *SpecialOptDefine::get_repr_cons() {
+ return new ReprStr("#<Builtin Macro: define>");
+}
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("#<Builtin Macro: set!>"); }
+ReprCons *SpecialOptSet::get_repr_cons() {
+ return new ReprStr("#<Builtin Macro: set!>");
+}
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("#<Builtin Macro: quote>"); }
+ReprCons *SpecialOptQuote::get_repr_cons() {
+ return new ReprStr("#<Builtin Macro: quote>");
+}
SpecialOptEval::SpecialOptEval() : SpecialOptObj("eval") {}
@@ -858,7 +868,9 @@ Pair *SpecialOptEval::call(ArgList *args, Environment * &envt,
}
}
-string SpecialOptEval::ext_repr() { return string("#<Builtin Macro: eval>"); }
+ReprCons *SpecialOptEval::get_repr_cons() {
+ return new ReprStr("#<Builtin Macro: eval>");
+}
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 <cstdio>
-#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("#<Unspecified>"); }
+ReprCons *UnspecObj::get_repr_cons() {
+ return new ReprStr("#<Unspecified>");
+}
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<SymObj*> 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("#<Procedure>"); }
+ReprCons *ProcObj::get_repr_cons() {
+ return new ReprStr("#<Procedure>");
+}
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 "#<Builtin Procedure: " + name + ">";
+ReprCons *BuiltinProcObj::get_repr_cons() {
+ return new ReprStr("#<Builtin Procedure: " + name + ">");
}
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<Pair*>(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<string, EvalObj*> 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;
}
}