aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lex.cpp6
-rw-r--r--src/parse.cpp2
-rw-r--r--src/tuplr.hpp54
3 files changed, 36 insertions, 26 deletions
diff --git a/src/lex.cpp b/src/lex.cpp
index dc7bd4a..bfdd9c1 100644
--- a/src/lex.cpp
+++ b/src/lex.cpp
@@ -39,8 +39,8 @@ readChar(Cursor& cur, istream& in)
SExp
readExpression(Cursor& cur, istream& in)
{
-#define PUSH(s, t) { if (t != "") { s.top().push_back(SExp(loc, t)); t = ""; } }
-#define YIELD(s, t) { if (s.empty()) { return SExp(loc, t); } else PUSH(s, t) }
+#define PUSH(s, t) { if (t != "") { s.top().push_back(SExp(loc, new AString(loc, t))); t = ""; } }
+#define YIELD(s, t) { if (s.empty()) { return SExp(loc, new AString(loc, t)); } else PUSH(s, t) }
stack<SExp> stk;
string tok;
Cursor loc; // start of tok
@@ -87,7 +87,7 @@ readExpression(Cursor& cur, istream& in)
}
}
switch (stk.size()) {
- case 0: return SExp(loc, tok);
+ case 0: return SExp(loc, new AString(loc, tok));
case 1: return stk.top();
default: throw Error(cur, "missing `)'");
}
diff --git a/src/parse.cpp b/src/parse.cpp
index a6af50c..a065e64 100644
--- a/src/parse.cpp
+++ b/src/parse.cpp
@@ -45,7 +45,7 @@ macDef(PEnv& penv, const SExp& exp)
argsExp.push_back(*j);
const SExp& body = *(++i);
SExp fnExp(body.loc);
- fnExp.push_back(SExp(body.loc, "fn"));
+ fnExp.push_back(SExp(body.loc, new AString(body.loc, "fn")));
fnExp.push_back(argsExp);
for (; i != exp.end(); ++i)
fnExp.push_back(*i);
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;
};