diff options
Diffstat (limited to 'src/resp.hpp')
-rw-r--r-- | src/resp.hpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/resp.hpp b/src/resp.hpp index e572473..fd861aa 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -490,6 +490,17 @@ ostream& operator<<(ostream& out, const Env<V>& env) { * Parser: S-Expressions (SExp) -> AST Nodes (AST) * ***************************************************************************/ +struct Macro { + struct Rule { + Rule(const ATuple* p, const ATuple* t) : pattern(p), templ(t) {} + const ATuple* pattern; + const ATuple* templ; + }; + + std::set<std::string> keywords; + std::list<Rule> rules; +}; + /// Parse Time Environment (really just a symbol table) struct PEnv : private map<const string, const char*> { PEnv() : symID(0) {} @@ -514,6 +525,9 @@ struct PEnv : private map<const string, const char*> { typedef std::set<std::string> Primitives; Primitives primitives; + typedef std::map<const std::string, Macro> Macros; + Macros macros; + unsigned symID; }; @@ -528,6 +542,11 @@ struct Constraint : public pair<const AST*,const AST*> { : pair<const AST*, const AST*>(a, b) {} }; +static inline bool +is_dots(const AST* exp) { + return (exp->to_symbol() && exp->as_symbol()->str() == "..."); +} + /// Type substitution struct Subst : public list<Constraint> { Subst(const AST* s=0, const AST* t=0) { @@ -550,8 +569,18 @@ struct Subst : public list<Constraint> { if (in->as_tuple()->empty()) return in; List out; - for (ATuple::const_iterator i = in->as_tuple()->begin(); i != in->as_tuple()->end(); ++i) - out.push_back(apply(*i)); + for (auto i : *in->as_tuple()) { + if (is_dots(i)) { + const_iterator o = find(i); + if (o != end()) { + for (auto j : *o->second->as_tuple()) { + out.push_back(apply(j)); + } + } + } else { + out.push_back(apply(i)); + } + } if (out.head) out.head->loc = in->loc; return out.head; |