diff options
author | David Robillard <d@drobilla.net> | 2012-12-25 00:09:34 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2012-12-25 00:09:34 +0000 |
commit | bf757dcc9b66ebb3bf7e2df8e8c7d3a011ddd6dc (patch) | |
tree | 0d49ea2dced45c2535b7050ebd7deefc19bd27ac /src/resp.hpp | |
parent | 67319bf0410196787c753225f46057bc7c94beec (diff) | |
download | resp-bf757dcc9b66ebb3bf7e2df8e8c7d3a011ddd6dc.tar.gz resp-bf757dcc9b66ebb3bf7e2df8e8c7d3a011ddd6dc.tar.bz2 resp-bf757dcc9b66ebb3bf7e2df8e8c7d3a011ddd6dc.zip |
Preliminary syntax-rules macro implementation.
git-svn-id: http://svn.drobilla.net/resp/trunk@443 ad02d1e2-f140-0410-9f75-f8b11f17cedd
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; |