diff options
Diffstat (limited to 'src/parse.cpp')
-rw-r--r-- | src/parse.cpp | 69 |
1 files changed, 37 insertions, 32 deletions
diff --git a/src/parse.cpp b/src/parse.cpp index a065e64..1f16bfe 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -16,7 +16,7 @@ */ /** @file - * @brief Parsing (build an AST from a SExp) + * @brief Parsing (build a code AST from a textual AST) */ #include "tuplr.hpp" @@ -28,31 +28,34 @@ using namespace std; * Macro Functions * ***************************************************************************/ -inline SExp -macDef(PEnv& penv, const SExp& exp) +inline AST* +macDef(PEnv& penv, const AST* exp) { - SExp::const_iterator i = exp.begin(); - THROW_IF(i == exp.end(), exp.loc, "Unexpected end of `def' macro call"); - const SExp& name = *(++i); - THROW_IF(i == exp.end(), name.loc, "Unexpected end of `def' macro call"); - if (name.type == SExp::ATOM) { - return exp; + const ATuple* tup = exp->to<const ATuple*>(); + ATuple::const_iterator i = tup->begin(); + THROW_IF(i == tup->end(), tup->loc, "Unexpected end of `def' macro call"); + const AST* name = *(++i); + THROW_IF(i == tup->end(), name->loc, "Unexpected end of `def' macro call"); + if (name->to<const AString*>()) { + return const_cast<AST*>(exp); } else { + const ATuple* pat = name->to<const ATuple*>(); + name = pat->at(0); // (def (f x) y) => (def f (fn (x) y)) - SExp argsExp(exp.loc); - SExp::const_iterator j = name.begin(); - for (++j; j != name.end(); ++j) - argsExp.push_back(*j); - const SExp& body = *(++i); - SExp fnExp(body.loc); - fnExp.push_back(SExp(body.loc, new AString(body.loc, "fn"))); - fnExp.push_back(argsExp); - for (; i != exp.end(); ++i) - fnExp.push_back(*i); - SExp ret(exp.loc); - ret.push_back(exp.front()); - ret.push_back(name.front()); - ret.push_back(fnExp); + ATuple* argsExp = new ATuple(exp->loc); + ATuple::const_iterator j = pat->begin(); + for (++j; j != pat->end(); ++j) + argsExp->push_back(*j); + const AST* body = *(++i); + ATuple* fnExp = new ATuple(body->loc); + fnExp->push_back(new AString(exp->loc, "fn")); + fnExp->push_back(argsExp); + for (; i != tup->end(); ++i) + fnExp->push_back(*i); + ATuple* ret = new ATuple(exp->loc); + ret->push_back(const_cast<AST*>(tup->front())); + ret->push_back(const_cast<AST*>(name)); + ret->push_back(fnExp); return ret; } } @@ -64,25 +67,27 @@ macDef(PEnv& penv, const SExp& exp) template<typename C> inline AST* -parseCall(PEnv& penv, const SExp& exp, void* arg) +parseCall(PEnv& penv, const AST* exp, void* arg) { - return new C(exp, penv.parseTuple(exp)); + return new C(penv.parseTuple(exp->to<const ATuple*>())); } template<typename T> inline AST* -parseLiteral(PEnv& penv, const SExp& exp, void* arg) +parseLiteral(PEnv& penv, const AST* exp, void* arg) { - return new ALiteral<T>(*reinterpret_cast<T*>(arg), exp.loc); + return new ALiteral<T>(*reinterpret_cast<T*>(arg), exp->loc); } inline AST* -parseFn(PEnv& penv, const SExp& exp, void* arg) +parseFn(PEnv& penv, const AST* exp, void* arg) { - SExp::const_iterator a = exp.begin(); - THROW_IF(++a == exp.end(), exp.loc, "Unexpected end of `fn' form"); - AFn* ret = tup<AFn>(exp.loc, penv.sym("fn"), new ATuple(penv.parseTuple(*a++)), 0); - while (a != exp.end()) + const ATuple* texp = exp->to<const ATuple*>(); + ATuple::const_iterator a = texp->begin(); + THROW_IF(++a == texp->end(), exp->loc, "Unexpected end of `fn' form"); + ATuple* prot = penv.parseTuple((*a++)->to<const ATuple*>()); + AFn* ret = tup<AFn>(exp->loc, penv.sym("fn"), prot, 0); + while (a != texp->end()) ret->push_back(penv.parse(*a++)); return ret; } |