aboutsummaryrefslogtreecommitdiffstats
path: root/tuplr.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'tuplr.hpp')
-rw-r--r--tuplr.hpp71
1 files changed, 31 insertions, 40 deletions
diff --git a/tuplr.hpp b/tuplr.hpp
index dc0756f..16a9a75 100644
--- a/tuplr.hpp
+++ b/tuplr.hpp
@@ -321,51 +321,42 @@ struct PEnv : private map<const string, ASymbol*> {
? i->second
: insert(make_pair(s, new ASymbol(s, c))).first->second);
}
-};
-
-/// The fundamental parser method
-static AST* parseExpression(PEnv& penv, const SExp& exp);
-
-static ATuple
-pmap(PEnv& penv, const SExp& e)
-{
- assert(e.type == SExp::LIST);
- ATuple ret(e.list.size(), e.loc);
- size_t n = 0;
- FOREACH(SExp::List::const_iterator, i, e.list)
- ret[n++] = parseExpression(penv, *i);
- return ret;
-}
-
-static AST*
-parseExpression(PEnv& penv, const SExp& exp)
-{
- if (exp.type == SExp::LIST) {
- if (exp.list.empty()) throw Error("call to empty list", exp.loc);
- if (exp.list.front().type == SExp::ATOM) {
- const PEnv::Handler* handler = penv.handler(true, exp.list.front().atom);
- if (handler) // Dispatch to list parse function
- return handler->func(penv, exp, handler->arg);
+ ATuple parseTuple(const SExp& e) {
+ ATuple ret(e.list.size(), e.loc);
+ size_t n = 0;
+ FOREACH(SExp::List::const_iterator, i, e.list)
+ ret[n++] = parse(*i);
+ return ret;
+ }
+ AST* parse(const SExp& exp) {
+ if (exp.type == SExp::LIST) {
+ if (exp.list.empty()) throw Error("call to empty list", exp.loc);
+ if (exp.list.front().type == SExp::ATOM) {
+ const PEnv::Handler* h = handler(true, exp.list.front().atom);
+ if (h)
+ return h->func(*this, exp, 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
+ return new ALiteral<float>(strtod(exp.atom.c_str(), NULL), exp.loc);
+ } else {
+ const PEnv::Handler* h = handler(false, exp.atom);
+ if (h)
+ return h->func(*this, exp, h->arg);
}
- return new ACall(exp, pmap(penv, 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
- return new ALiteral<float>(strtod(exp.atom.c_str(), NULL), exp.loc);
- } else {
- const PEnv::Handler* handler = penv.handler(false, exp.atom);
- if (handler) // Dispatch to atom parse function
- return handler->func(penv, exp, handler->arg);
+ return sym(exp.atom, exp.loc);
}
- return penv.sym(exp.atom, exp.loc);
-}
+};
+
template<typename C>
inline AST*
parseCall(PEnv& penv, const SExp& exp, void* arg)
{
- return new C(exp, pmap(penv, exp));
+ return new C(exp, penv.parseTuple(exp));
}
template<typename T>
@@ -380,8 +371,8 @@ parseFn(PEnv& penv, const SExp& exp, void* arg)
{
SExp::List::const_iterator a = exp.list.begin(); ++a;
return new AClosure(exp.loc, penv.sym("fn"),
- new ATuple(pmap(penv, *a++)),
- parseExpression(penv, *a++));
+ new ATuple(penv.parseTuple(*a++)),
+ penv.parse(*a++));
}