aboutsummaryrefslogtreecommitdiffstats
path: root/src/tuplr.hpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-07-04 03:44:06 +0000
committerDavid Robillard <d@drobilla.net>2009-07-04 03:44:06 +0000
commit9e12b8536648a30377040f407e06ea0713db91b4 (patch)
treec3ff6258e0858fdde484a5b8fa174f76ba8bbc1b /src/tuplr.hpp
parent54cee059a533433091a4b65cf47b821bcbb0840c (diff)
downloadresp-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.hpp54
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;
};