aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm.cpp4
-rw-r--r--tuplr.hpp71
2 files changed, 33 insertions, 42 deletions
diff --git a/llvm.cpp b/llvm.cpp
index e08d4fb..8357f6d 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -514,7 +514,7 @@ eval(CEnv& cenv, const string& name, istream& is)
if (exp.type == SExp::LIST && exp.list.empty())
break;
- result = parseExpression(cenv.penv, exp); // Parse input
+ result = cenv.penv.parse(exp); // Parse input
result->constrain(cenv.tenv); // Constrain types
cenv.tenv.solve(); // Solve and apply type constraints
resultType = cenv.tenv.type(result);
@@ -560,7 +560,7 @@ repl(CEnv& cenv)
if (exp.type == SExp::LIST && exp.list.empty())
break;
- AST* body = parseExpression(cenv.penv, exp); // Parse input
+ AST* body = cenv.penv.parse(exp); // Parse input
body->constrain(cenv.tenv); // Constrain types
cenv.tenv.solve(); // Solve and apply type constraints
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++));
}