diff options
Diffstat (limited to 'src/simplify.cpp')
-rw-r--r-- | src/simplify.cpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/simplify.cpp b/src/simplify.cpp index 31eb83a..35178ac 100644 --- a/src/simplify.cpp +++ b/src/simplify.cpp @@ -26,6 +26,34 @@ using namespace std; static const AST* +simplify_if(CEnv& cenv, const ATuple* aif) throw() +{ + List<ATuple, const AST> copy(aif->loc, cenv.penv.sym("if"), NULL); + copy.push_back(aif->list_ref(1)); + copy.push_back(aif->list_ref(2)); + + ATuple* tail = copy.tail; + ATuple::const_iterator i = aif->iter_at(3); + for (; ; ++i) { + ATuple::const_iterator next = i; + if (++next == aif->end()) + break; + + List<ATuple, const AST> inner_if((*i)->loc, cenv.penv.sym("if"), *i, *next, NULL); + tail->last(new ATuple(inner_if.head, NULL, Cursor())); + tail = inner_if.tail; + + cenv.setTypeSameAs(inner_if, aif); + + i = next; // jump 2 elements (to the next predicate) + } + + tail->last(new ATuple(*i, NULL, Cursor())); + cenv.setTypeSameAs(copy, aif); + return copy; +} + +static const AST* simplify_match(CEnv& cenv, const ATuple* match) throw() { List<ATuple, const AST> copy(match->loc, cenv.penv.sym("let"), NULL); @@ -57,9 +85,8 @@ simplify_match(CEnv& cenv, const ATuple* match) throw() copyIf.push_back(resp_simplify(cenv, body)); } copyIf.push_back(cenv.penv.sym("__unreachable")); - copy.push_back(copyIf); - cenv.setTypeSameAs(copyIf, match); + copy.push_back(simplify_if(cenv, copyIf)); cenv.setTypeSameAs(copy, match); return copy; @@ -89,6 +116,8 @@ resp_simplify(CEnv& cenv, const AST* ast) throw() if (form == "match") return simplify_match(cenv, list); + else if (form == "if") + return simplify_if(cenv, list); else return simplify_list(cenv, list); } |