aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-07-04 01:06:07 +0000
committerDavid Robillard <d@drobilla.net>2009-07-04 01:06:07 +0000
commit8ec662aa4e6c7443cfca82e3085f71c5f944ec1a (patch)
tree5083df03f03909320f919dc6865132fa5824cf93 /src
parent959f8bd0b7016dad794ba0907b544c1cfc49d09f (diff)
downloadresp-8ec662aa4e6c7443cfca82e3085f71c5f944ec1a.tar.gz
resp-8ec662aa4e6c7443cfca82e3085f71c5f944ec1a.tar.bz2
resp-8ec662aa4e6c7443cfca82e3085f71c5f944ec1a.zip
Safer Exp.
git-svn-id: http://svn.drobilla.net/resp/tuplr@179 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src')
-rw-r--r--src/tuplr.hpp47
1 files changed, 28 insertions, 19 deletions
diff --git a/src/tuplr.hpp b/src/tuplr.hpp
index 5deff71..aaa0867 100644
--- a/src/tuplr.hpp
+++ b/src/tuplr.hpp
@@ -64,21 +64,30 @@ struct Error {
/// Expression ::= Atom | (Expression*)
template<typename 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) {}
+ 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); }
+ enum { ATOM, LIST } type;
- bool empty() const { return vector< Exp<Atom> >::empty(); }
- const Exp<Atom>& front() const { return vector< Exp<Atom> >::front(); }
+ inline const Atom& atom() const { assert(type == ATOM); return _atom; }
- 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(); }
+private:
+ typedef std::vector< Exp<Atom> > ListImpl;
- enum { ATOM, LIST } type;
- Cursor loc;
- Atom atom;
+public:
+ void push_back(const Exp<Atom>& exp) { assert(type == LIST); ListImpl::push_back(exp); }
+
+ bool empty() const { assert(type == LIST); return ListImpl::empty(); }
+ const Exp<Atom>& front() const { assert(type == LIST); return ListImpl::front(); }
+
+ typedef typename ListImpl::const_iterator const_iterator;
+ const_iterator begin() const { assert(type == LIST); return ListImpl::begin(); }
+ const_iterator end() const { assert(type == LIST); return ListImpl::end(); }
+
+ Cursor loc;
+
+private:
+ Atom _atom;
};
template<typename Atom>
@@ -527,25 +536,25 @@ struct PEnv : private map<const string, ASymbol*> {
if (exp.type == SExp::LIST) {
if (exp.empty()) throw Error(exp.loc, "call to empty list");
if (exp.front().type == SExp::ATOM) {
- MF mf = mac(exp.front().atom);
+ MF mf = mac(exp.front().atom());
SExp expanded = (mf ? mf(*this, exp) : exp);
- const PEnv::Handler* h = handler(true, expanded.front().atom);
+ const PEnv::Handler* h = handler(true, expanded.front().atom());
if (h)
return h->func(*this, expanded, h->arg);
}
return new ACall(exp, parseTuple(exp)); // Parse as regular call
- } else if (isdigit(exp.atom[0])) {
- if (exp.atom.find('.') == string::npos)
- return new ALiteral<int32_t>(strtol(exp.atom.c_str(), NULL, 10), exp.loc);
+ } else if (isdigit(exp.atom()[0])) {
+ if (exp.atom().find('.') == string::npos)
+ return new ALiteral<int32_t>(strtol(exp.atom().c_str(), NULL, 10), exp.loc);
else
- return new ALiteral<float>(strtod(exp.atom.c_str(), NULL), exp.loc);
+ return new ALiteral<float>(strtod(exp.atom().c_str(), NULL), exp.loc);
} else {
- const PEnv::Handler* h = handler(false, exp.atom);
+ const PEnv::Handler* h = handler(false, exp.atom());
if (h)
return h->func(*this, exp, h->arg);
}
- return sym(exp.atom, exp.loc);
+ return sym(exp.atom(), exp.loc);
}
unsigned symID;
};