aboutsummaryrefslogtreecommitdiffstats
path: root/src/resp.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/resp.hpp')
-rw-r--r--src/resp.hpp33
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;