diff options
-rw-r--r-- | src/parse.cpp | 48 | ||||
-rw-r--r-- | src/resp.hpp | 39 |
2 files changed, 47 insertions, 40 deletions
diff --git a/src/parse.cpp b/src/parse.cpp index 2c59c56..3184f8a 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -23,6 +23,50 @@ using namespace std; +ATuple* +parseTuple(PEnv& penv, const ATuple* e) +{ + ATuple* ret = new ATuple(e->loc); + FOREACHP(ATuple::const_iterator, i, e) + ret->push_back(penv.parse(*i)); + return ret; +} + +AST* +PEnv::parse(const AST* exp) +{ + const ATuple* tup = exp->to<const ATuple*>(); + if (tup) { + if (tup->empty()) throw Error(exp->loc, "call to empty list"); + if (!tup->head()->to<const ATuple*>()) { + MF mf = mac(*tup->head()->to<const ALexeme*>()); + const AST* expanded = (mf ? mf(*this, exp) : exp); + const ATuple* expanded_tup = expanded->to<const ATuple*>(); + const PEnv::Handler* h = handler(true, *expanded_tup->head()->to<const ALexeme*>()); + if (h) + return h->func(*this, expanded, h->arg); + } + ATuple* parsed_tup = parseTuple(*this, tup); + return new ACall(parsed_tup); // Parse as regular call + } + const ALexeme* lex = exp->to<const ALexeme*>(); + assert(lex); + if (isdigit((*lex)[0])) { + const std::string& s = *lex; + if (s.find('.') == string::npos) + return new ALiteral<int32_t>(strtol(s.c_str(), NULL, 10), exp->loc); + else + return new ALiteral<float>(strtod(s.c_str(), NULL), exp->loc); + } else if ((*lex)[0] == '\"') { + return new AString(exp->loc, lex->substr(1, lex->length() - 2)); + } else { + const PEnv::Handler* h = handler(false, *lex); + if (h) + return h->func(*this, exp, h->arg); + } + return sym(*lex, exp->loc); +} + /*************************************************************************** * Macro Functions * @@ -69,7 +113,7 @@ template<typename C> inline AST* parseCall(PEnv& penv, const AST* exp, void* arg) { - return new C(penv.parseTuple(exp->to<const ATuple*>())); + return new C(parseTuple(penv, exp->to<const ATuple*>())); } template<typename T> @@ -85,7 +129,7 @@ parseFn(PEnv& penv, const AST* exp, void* arg) const ATuple* texp = exp->to<const ATuple*>(); ATuple::const_iterator a = texp->begin(); THROW_IF(++a == texp->end(), exp->loc, "Unexpected end of `fn' form"); - ATuple* prot = penv.parseTuple((*a++)->to<const ATuple*>()); + ATuple* prot = parseTuple(penv, (*a++)->to<const ATuple*>()); AFn* ret = tup<AFn>(exp->loc, penv.sym("fn"), prot, 0); while (a != texp->end()) ret->push_back(penv.parse(*a++)); diff --git a/src/resp.hpp b/src/resp.hpp index 4be28bd..e551c0c 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -521,44 +521,7 @@ struct PEnv : private map<const string, ASymbol*> { return sym; } } - ATuple* parseTuple(const ATuple* e) { - ATuple* ret = new ATuple(e->loc); - FOREACHP(ATuple::const_iterator, i, e) - ret->push_back(parse(*i)); - return ret; - } - AST* parse(const AST* exp) { - const ATuple* tup = exp->to<const ATuple*>(); - if (tup) { - if (tup->empty()) throw Error(exp->loc, "call to empty list"); - if (!tup->head()->to<const ATuple*>()) { - MF mf = mac(*tup->head()->to<const ALexeme*>()); - const AST* expanded = (mf ? mf(*this, exp) : exp); - const ATuple* expanded_tup = expanded->to<const ATuple*>(); - const PEnv::Handler* h = handler(true, *expanded_tup->head()->to<const ALexeme*>()); - if (h) - return h->func(*this, expanded, h->arg); - } - ATuple* parsed_tup = parseTuple(tup); - return new ACall(parsed_tup); // Parse as regular call - } - const ALexeme* lex = exp->to<const ALexeme*>(); - assert(lex); - if (isdigit((*lex)[0])) { - const std::string& s = *lex; - if (s.find('.') == string::npos) - return new ALiteral<int32_t>(strtol(s.c_str(), NULL, 10), exp->loc); - else - return new ALiteral<float>(strtod(s.c_str(), NULL), exp->loc); - } else if ((*lex)[0] == '\"') { - return new AString(exp->loc, lex->substr(1, lex->length() - 2)); - } else { - const PEnv::Handler* h = handler(false, *lex); - if (h) - return h->func(*this, exp, h->arg); - } - return sym(*lex, exp->loc); - } + AST* parse(const AST* exp); unsigned symID; }; |