diff options
-rw-r--r-- | src/parse.cpp | 30 | ||||
-rw-r--r-- | src/tuplr.hpp | 14 |
2 files changed, 29 insertions, 15 deletions
diff --git a/src/parse.cpp b/src/parse.cpp index e37f095..a6af50c 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -31,22 +31,27 @@ using namespace std; inline SExp macDef(PEnv& penv, const SExp& exp) { - THROW_IF(exp.size() < 3, exp.loc, "[MAC] `def' requires at least 2 arguments") - if (exp.at(1).type == SExp::ATOM) { + 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; } else { // (def (f x) y) => (def f (fn (x) y)) SExp argsExp(exp.loc); - for (size_t i = 1; i < exp.at(1).size(); ++i) - argsExp.push_back(exp.at(1).at(i)); - SExp fnExp(exp.at(2).loc); - fnExp.push_back(SExp(exp.at(2).loc, "fn")); + 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, "fn")); fnExp.push_back(argsExp); - for (size_t i = 2; i < exp.size(); ++i) - fnExp.push_back(exp.at(i)); + for (; i != exp.end(); ++i) + fnExp.push_back(*i); SExp ret(exp.loc); - ret.push_back(exp.at(0)); - ret.push_back(exp.at(1).at(0)); + ret.push_back(exp.front()); + ret.push_back(name.front()); ret.push_back(fnExp); return ret; } @@ -74,9 +79,8 @@ parseLiteral(PEnv& penv, const SExp& exp, void* arg) inline AST* parseFn(PEnv& penv, const SExp& exp, void* arg) { - THROW_IF(exp.size() < 2,exp.loc, "Missing function parameters and body"); - THROW_IF(exp.size() < 3, exp.loc, "Missing function body"); - SExp::const_iterator a = exp.begin(); ++a; + 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()) ret->push_back(penv.parse(*a++)); diff --git a/src/tuplr.hpp b/src/tuplr.hpp index de025b7..5deff71 100644 --- a/src/tuplr.hpp +++ b/src/tuplr.hpp @@ -61,11 +61,21 @@ struct Error { string msg; }; -/// Expression ::= Atom | (SubExp*) +/// Expression ::= Atom | (Expression*) template<typename Atom> -struct Exp : public std::vector< Exp<Atom> > { +struct Exp : private std::vector< Exp<Atom> > { Exp(Cursor c) : type(LIST), loc(c) {} Exp(Cursor c, const Atom& a) : type(ATOM), loc(c), atom(a) {} + + void push_back(const Exp<Atom>& exp) { vector< Exp<Atom> >::push_back(exp); } + + bool empty() const { return vector< Exp<Atom> >::empty(); } + const Exp<Atom>& front() const { return vector< Exp<Atom> >::front(); } + + typedef typename vector< Exp<Atom> >::const_iterator const_iterator; + const_iterator begin() const { return vector< Exp<Atom> >::begin(); } + const_iterator end() const { return vector< Exp<Atom> >::end(); } + enum { ATOM, LIST } type; Cursor loc; Atom atom; |