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