aboutsummaryrefslogtreecommitdiffstats
path: root/src/parse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse.cpp')
-rw-r--r--src/parse.cpp69
1 files changed, 37 insertions, 32 deletions
diff --git a/src/parse.cpp b/src/parse.cpp
index a065e64..1f16bfe 100644
--- a/src/parse.cpp
+++ b/src/parse.cpp
@@ -16,7 +16,7 @@
*/
/** @file
- * @brief Parsing (build an AST from a SExp)
+ * @brief Parsing (build a code AST from a textual AST)
*/
#include "tuplr.hpp"
@@ -28,31 +28,34 @@ using namespace std;
* Macro Functions *
***************************************************************************/
-inline SExp
-macDef(PEnv& penv, const SExp& exp)
+inline AST*
+macDef(PEnv& penv, const AST* exp)
{
- SExp::const_iterator i = exp.begin();
- THROW_IF(i == exp.end(), exp.loc, "Unexpected end of `def' macro call");
- const SExp& name = *(++i);
- THROW_IF(i == exp.end(), name.loc, "Unexpected end of `def' macro call");
- if (name.type == SExp::ATOM) {
- return exp;
+ const ATuple* tup = exp->to<const ATuple*>();
+ ATuple::const_iterator i = tup->begin();
+ THROW_IF(i == tup->end(), tup->loc, "Unexpected end of `def' macro call");
+ const AST* name = *(++i);
+ THROW_IF(i == tup->end(), name->loc, "Unexpected end of `def' macro call");
+ if (name->to<const AString*>()) {
+ return const_cast<AST*>(exp);
} else {
+ const ATuple* pat = name->to<const ATuple*>();
+ name = pat->at(0);
// (def (f x) y) => (def f (fn (x) y))
- SExp argsExp(exp.loc);
- SExp::const_iterator j = name.begin();
- for (++j; j != name.end(); ++j)
- argsExp.push_back(*j);
- const SExp& body = *(++i);
- SExp fnExp(body.loc);
- fnExp.push_back(SExp(body.loc, new AString(body.loc, "fn")));
- fnExp.push_back(argsExp);
- for (; i != exp.end(); ++i)
- fnExp.push_back(*i);
- SExp ret(exp.loc);
- ret.push_back(exp.front());
- ret.push_back(name.front());
- ret.push_back(fnExp);
+ ATuple* argsExp = new ATuple(exp->loc);
+ ATuple::const_iterator j = pat->begin();
+ for (++j; j != pat->end(); ++j)
+ argsExp->push_back(*j);
+ const AST* body = *(++i);
+ ATuple* fnExp = new ATuple(body->loc);
+ fnExp->push_back(new AString(exp->loc, "fn"));
+ fnExp->push_back(argsExp);
+ for (; i != tup->end(); ++i)
+ fnExp->push_back(*i);
+ ATuple* ret = new ATuple(exp->loc);
+ ret->push_back(const_cast<AST*>(tup->front()));
+ ret->push_back(const_cast<AST*>(name));
+ ret->push_back(fnExp);
return ret;
}
}
@@ -64,25 +67,27 @@ macDef(PEnv& penv, const SExp& exp)
template<typename C>
inline AST*
-parseCall(PEnv& penv, const SExp& exp, void* arg)
+parseCall(PEnv& penv, const AST* exp, void* arg)
{
- return new C(exp, penv.parseTuple(exp));
+ return new C(penv.parseTuple(exp->to<const ATuple*>()));
}
template<typename T>
inline AST*
-parseLiteral(PEnv& penv, const SExp& exp, void* arg)
+parseLiteral(PEnv& penv, const AST* exp, void* arg)
{
- return new ALiteral<T>(*reinterpret_cast<T*>(arg), exp.loc);
+ return new ALiteral<T>(*reinterpret_cast<T*>(arg), exp->loc);
}
inline AST*
-parseFn(PEnv& penv, const SExp& exp, void* arg)
+parseFn(PEnv& penv, const AST* exp, void* arg)
{
- SExp::const_iterator a = exp.begin();
- THROW_IF(++a == exp.end(), exp.loc, "Unexpected end of `fn' form");
- AFn* ret = tup<AFn>(exp.loc, penv.sym("fn"), new ATuple(penv.parseTuple(*a++)), 0);
- while (a != exp.end())
+ 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*>());
+ AFn* ret = tup<AFn>(exp->loc, penv.sym("fn"), prot, 0);
+ while (a != texp->end())
ret->push_back(penv.parse(*a++));
return ret;
}