diff options
Diffstat (limited to 'src/unify.cpp')
-rw-r--r-- | src/unify.cpp | 102 |
1 files changed, 51 insertions, 51 deletions
diff --git a/src/unify.cpp b/src/unify.cpp index 52a3265..a7f7822 100644 --- a/src/unify.cpp +++ b/src/unify.cpp @@ -26,29 +26,25 @@ * with a specific set of argument types */ Subst -TEnv::buildSubst(const AType* genericT, const AType& argsT) +TEnv::buildSubst(const AST* genericT, const AST& argsT) { Subst subst; // Build substitution to apply to generic type - const ATuple* genericProtT = genericT->list_ref(1)->as_tuple(); + const ATuple* genericProtT = genericT->as_tuple()->list_ref(1)->as_tuple(); ATuple::const_iterator g = genericProtT->begin(); - ATuple::const_iterator a = argsT.begin(); - for (; a != argsT.end(); ++a, ++g) { - const AType* genericArgT = (*g)->to_type(); - const AType* callArgT = (*a)->to_type(); - if (callArgT->kind == AType::EXPR) { - assert(genericArgT->kind == AType::EXPR); - ATuple::const_iterator gi = genericArgT->begin(); - ATuple::const_iterator ci = callArgT->begin(); - for (; gi != genericArgT->end(); ++gi, ++ci) { - const AType* gT = (*gi)->to_type(); - const AType* aT = (*ci)->to_type(); - if (gT && aT) - subst.add(gT, aT); + ATuple::const_iterator a = argsT.as_tuple()->begin(); + for (; a != argsT.as_tuple()->end(); ++a, ++g) { + if (AType::is_expr(*a)) { + assert(AType::is_expr(*g)); + ATuple::const_iterator gi = (*g)->as_tuple()->begin(); + ATuple::const_iterator ci = (*a)->as_tuple()->begin(); + for (; gi != (*g)->as_tuple()->end(); ++gi, ++ci) { + if ((*gi) && (*ci)) + subst.add(*gi, *ci); } } else { - subst.add(genericArgT, callArgT); + subst.add(*g, *a); } } @@ -56,29 +52,34 @@ TEnv::buildSubst(const AType* genericT, const AType& argsT) } void -Constraints::constrain(TEnv& tenv, const AST* o, const AType* t) +Constraints::constrain(TEnv& tenv, const AST* o, const AST* t) { assert(o); assert(t); push_back(Constraint(tenv.var(o), t)); } -static const AType* -substitute(const AType* tup, const AType* from, const AType* to) +static const AST* +substitute(const AST* in, const AST* from, const AST* to) { - if (!tup) return NULL; - TList ret; - FOREACHP(AType::const_iterator, i, tup) { + if (in == from) + return to; + + const ATuple* tup = in->to_tuple(); + if (!tup) + return from; + + List ret; + FOREACHP(ATuple::const_iterator, i, tup->as_tuple()) { if (**i == *from) { - ret.push_back(new AType(*to, (*i)->loc)); + ret.push_back(to); // FIXME: should be a copy w/ (*i)->loc } else if (*i != to) { - const AType* elem = (*i)->as_type(); - if (elem->kind == AType::EXPR) - ret.push_back(substitute(elem, from, to)); + if (AType::is_expr(*i)) + ret.push_back(substitute(*i, from, to)); else - ret.push_back(elem); + ret.push_back(*i); } else { - ret.push_back((*i)->as_type()); + ret.push_back(*i); } } return ret.head; @@ -102,17 +103,17 @@ Subst::compose(const Subst& delta, const Subst& gamma) /// Replace all occurrences of @a s with @a t Constraints& -Constraints::replace(const AType* s, const AType* t) +Constraints::replace(const AST* s, const AST* t) { for (Constraints::iterator c = begin(); c != end(); ++c) { if (*c->first == *s) { - c->first = new AType(*t, c->first->loc); - } else if (c->first->kind == AType::EXPR) { + c->first = t; // FIXME: should be copy w/ c->first->loc; + } else if (AType::is_expr(c->first)) { c->first = substitute(c->first, s, t); } if (*c->second == *s) { - c->second = new AType(*t, c->second->loc); - } else if (c->second->kind == AType::EXPR) { + c->second = t; // FIXME: should be copy w/ c->second->loc; + } else if (AType::is_expr(c->second)) { c->second = substitute(c->second, s, t); } } @@ -120,10 +121,9 @@ Constraints::replace(const AType* s, const AType* t) } static inline bool -is_dots(const AST* ast) +is_dots(const AST* type) { - const AType* type = ast->as_type(); - return (type->kind == AType::NAME && type->head()->str() == "..."); + return (AType::is_name(type) && type->as_symbol()->str() == "..."); } /// Unify a type constraint set (TAPL 22.4) @@ -134,30 +134,30 @@ unify(const Constraints& constraints) return Subst(); Constraints::const_iterator i = constraints.begin(); - const AType* s = i->first; - const AType* t = i->second; + const AST* s = i->first; + const AST* t = i->second; Constraints cp(++i, constraints.end()); if (*s == *t) { return unify(cp); - } else if (s->kind == AType::VAR && !list_contains(t, s)) { + } else if (AType::is_var(s) && !list_contains(t->to_tuple(), s)) { return Subst::compose(unify(cp.replace(s, t)), Subst(s, t)); - } else if (t->kind == AType::VAR && !list_contains(s, t)) { + } else if (AType::is_var(t) && !list_contains(s->to_tuple(), t)) { return Subst::compose(unify(cp.replace(t, s)), Subst(t, s)); - } else if (s->kind == AType::EXPR && t->kind == AType::EXPR) { - AType::const_iterator si = s->begin(); - AType::const_iterator ti = t->begin(); - for (; si != s->end() && ti != t->end(); ++si, ++ti) { - const AType* st = (*si)->as_type(); - const AType* tt = (*ti)->as_type(); - if (is_dots(st) || is_dots(tt)) + } else if (AType::is_expr(s) && AType::is_expr(t)) { + const ATuple* const st = s->as_tuple(); + const ATuple* const tt = t->as_tuple(); + ATuple::const_iterator si = st->begin(); + ATuple::const_iterator ti = tt->begin(); + for (; si != st->end() && ti != tt->end(); ++si, ++ti) { + if (is_dots(*si) || is_dots(*ti)) return unify(cp); else - cp.push_back(Constraint(st, tt)); + cp.push_back(Constraint(*si, *ti)); } - if ((si == s->end() && ti == t->end()) - || (si != s->end() && is_dots(*si)) - || (ti != t->end() && is_dots(*ti))) + if ((si == st->end() && ti == tt->end()) + || (si != st->end() && is_dots(*si)) + || (ti != tt->end() && is_dots(*ti))) return unify(cp); } throw Error(s->loc, |