aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-07-03 22:57:30 +0000
committerDavid Robillard <d@drobilla.net>2009-07-03 22:57:30 +0000
commit959f8bd0b7016dad794ba0907b544c1cfc49d09f (patch)
tree26467f19dbfaf4c92a3e53c792cf108f330e38c5
parentceed0285eed53ef4da6e585e5c029824484e6931 (diff)
downloadresp-959f8bd0b7016dad794ba0907b544c1cfc49d09f.tar.gz
resp-959f8bd0b7016dad794ba0907b544c1cfc49d09f.tar.bz2
resp-959f8bd0b7016dad794ba0907b544c1cfc49d09f.zip
Hide std::vector roots of Exp.
git-svn-id: http://svn.drobilla.net/resp/tuplr@178 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--src/parse.cpp30
-rw-r--r--src/tuplr.hpp14
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;