diff options
author | David Robillard <d@drobilla.net> | 2009-07-04 03:44:06 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-07-04 03:44:06 +0000 |
commit | 9e12b8536648a30377040f407e06ea0713db91b4 (patch) | |
tree | c3ff6258e0858fdde484a5b8fa174f76ba8bbc1b /src/tuplr.hpp | |
parent | 54cee059a533433091a4b65cf47b821bcbb0840c (diff) | |
download | resp-9e12b8536648a30377040f407e06ea0713db91b4.tar.gz resp-9e12b8536648a30377040f407e06ea0713db91b4.tar.bz2 resp-9e12b8536648a30377040f407e06ea0713db91b4.zip |
Lex to AST with AString type.
git-svn-id: http://svn.drobilla.net/resp/tuplr@181 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/tuplr.hpp')
-rw-r--r-- | src/tuplr.hpp | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/src/tuplr.hpp b/src/tuplr.hpp index 57481bb..087ce77 100644 --- a/src/tuplr.hpp +++ b/src/tuplr.hpp @@ -64,31 +64,30 @@ struct Error { /// Expression ::= Atom | (Expression*) template<typename Atom> -struct Exp : private std::vector< Exp<Atom> > { - Exp(Cursor c) : type(LIST), loc(c) {} +struct Exp { + typedef std::vector< Exp<Atom> > Vec; + + Exp(Cursor c) : type(LIST), loc(c), _vec(new Vec()) {} Exp(Cursor c, const Atom& a) : type(ATOM), loc(c), _atom(a) {} enum { ATOM, LIST } type; inline const Atom& atom() const { assert(type == ATOM); return _atom; } -private: - typedef std::vector< Exp<Atom> > ListImpl; - -public: - void push_back(const Exp<Atom>& exp) { assert(type == LIST); ListImpl::push_back(exp); } + void push_back(const Exp<Atom>& exp) { assert(type == LIST); _vec->push_back(exp); } - bool empty() const { assert(type == LIST); return ListImpl::empty(); } - const Exp<Atom>& front() const { assert(type == LIST); return ListImpl::front(); } + bool empty() const { assert(type == LIST); return _vec->empty(); } + const Exp<Atom>& front() const { assert(type == LIST); return _vec->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(); } + typedef typename Vec::const_iterator const_iterator; + const_iterator begin() const { assert(type == LIST); return _vec->begin(); } + const_iterator end() const { assert(type == LIST); return _vec->end(); } Cursor loc; private: Atom _atom; + Vec* _vec; }; template<typename Atom> @@ -144,7 +143,8 @@ struct Env : public list< vector< pair<K,V> > > { * Lexer: Text (istream) -> S-Expressions (SExp) * ***************************************************************************/ -typedef Exp<string> SExp; ///< Textual S-Expression +class AString; +typedef Exp<AString*> SExp; ///< Textual S-Expression SExp readExpression(Cursor& cur, std::istream& in); @@ -266,6 +266,15 @@ struct ALiteral : public AST { const T val; }; +/// String, e.g. ""a"" +struct AString : public AST, public std::string { + AString(Cursor c, const string& s) : AST(c), std::string(s) {} + AString& operator=(const AString& rhs) { *this = rhs; return *this; } + bool operator==(const AST& rhs) const { return this == &rhs; } + void constrain(TEnv& tenv, Constraints& c) const {} + CValue compile(CEnv& cenv) { return NULL; } +}; + /// Symbol, e.g. "a" struct ASymbol : public AST { bool operator==(const AST& rhs) const { return this == &rhs; } @@ -523,7 +532,7 @@ struct PEnv : private map<const string, ASymbol*> { void defmac(const string& s, const MF f) { macros.insert(make_pair(s, f)); } - MF mac(const string& s) const { + MF mac(const AString& s) const { map<string, MF>::const_iterator i = macros.find(s); return (i != macros.end()) ? i->second : NULL; } @@ -549,25 +558,26 @@ 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])) { + const std::string& s = *exp.atom(); + if (s.find('.') == string::npos) + return new ALiteral<int32_t>(strtol(s.c_str(), NULL, 10), exp.loc); else - return new ALiteral<float>(strtod(exp.atom().c_str(), NULL), exp.loc); + return new ALiteral<float>(strtod(s.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; }; |