diff options
author | David Robillard <d@drobilla.net> | 2012-12-25 20:14:15 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2012-12-25 20:14:15 +0000 |
commit | 32e3bdba4abbd63d7f2a1def7f7000b75c5165fe (patch) | |
tree | 1a83776a4673c3c620ed37d890fa17b56d013640 /src/resp.hpp | |
parent | 77d27b3495bfa98c5e13707903e4f885e8521ab6 (diff) | |
download | resp-32e3bdba4abbd63d7f2a1def7f7000b75c5165fe.tar.gz resp-32e3bdba4abbd63d7f2a1def7f7000b75c5165fe.tar.bz2 resp-32e3bdba4abbd63d7f2a1def7f7000b75c5165fe.zip |
Implement ellipses as in R*RS.
Let macro is now the one from R7RS, but missing the second clause (no letrec yet).
git-svn-id: http://svn.drobilla.net/resp/trunk@446 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/resp.hpp')
-rw-r--r-- | src/resp.hpp | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/src/resp.hpp b/src/resp.hpp index 02d2746..5eb9ef0 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -243,6 +243,7 @@ struct ATuple : public AST { return NULL; } + void set_fst(const AST* ast) { _fst = ast; } void last(ATuple* ast) { _rst = ast; } struct const_iterator { @@ -336,13 +337,16 @@ list_equals(const ATuple* lhs, const ATuple* rhs) ATuple::const_iterator l = lhs->begin(); for (const auto& r : *rhs) - if (!(*(*l++) == *r)) + if (l == lhs->end() || !(*(*l++) == *r)) return false; return true; } inline void list_append(ATuple* head, const AST* child) { + if (!head->fst()) { + head->set_fst(child); + } for (ATuple* i = head; i; i = const_cast<ATuple*>(i->rst())) { if (!i->rst()) { i->last(new ATuple(child, NULL, child->loc)); @@ -593,26 +597,29 @@ struct Subst : public list<Constraint> { return end(); } const AST* apply(const AST* in) const { - if (AType::is_expr(in)) { - if (in->as_tuple()->empty()) - return in; + if (AType::is_expr(in) && !in->as_tuple()->empty()) { + const ATuple* tup = in->as_tuple(); List out; - const AST* prev = NULL; - for (const auto& i : *in->as_tuple()) { - if (is_dots(i)) { - const_iterator o = find_ellipsis(prev); + ATuple::const_iterator next = tup->begin(); + ++next; + for (auto i : *tup) { + if (next != tup->end() && is_dots(*next)) { + const_iterator o = find_ellipsis(i); if (o != end()) { for (auto j : *o->second->as_tuple()) { out.push_back(apply(j)); } } - } else { + } else if (!is_dots(i)) { out.push_back(apply(i)); } - prev = i; + if (next != tup->end()) + ++next; } if (out.head) out.head->loc = in->loc; + else + out.head = new ATuple(NULL, NULL, in->loc); return out.head; } else { const_iterator i = find(in); |