diff options
author | David Robillard <d@drobilla.net> | 2010-04-13 02:28:56 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-04-13 02:28:56 +0000 |
commit | 8675beae4f7a8415fc2e88451da95dc068719194 (patch) | |
tree | 599de9b6730a14035a25f7d9e0467f96866185ed /src/unify.cpp | |
parent | 1f988f420ba3827941886962680f3e2ad6f01740 (diff) | |
download | resp-8675beae4f7a8415fc2e88451da95dc068719194.tar.gz resp-8675beae4f7a8415fc2e88451da95dc068719194.tar.bz2 resp-8675beae4f7a8415fc2e88451da95dc068719194.zip |
Restructure as a source translation based compiler.
Implement support for closures (via lambda lifting phase).
git-svn-id: http://svn.drobilla.net/resp/resp@254 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/unify.cpp')
-rw-r--r-- | src/unify.cpp | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/src/unify.cpp b/src/unify.cpp index 93dd78b..1b25861 100644 --- a/src/unify.cpp +++ b/src/unify.cpp @@ -26,7 +26,7 @@ * with a specific set of argument types */ Subst -TEnv::buildSubst(AType* genericT, const AType& argsT) +TEnv::buildSubst(const AType* genericT, const AType& argsT) { Subst subst; @@ -56,7 +56,7 @@ TEnv::buildSubst(AType* genericT, const AType& argsT) } void -Constraints::constrain(TEnv& tenv, const AST* o, AType* t) +Constraints::constrain(TEnv& tenv, const AST* o, const AType* t) { assert(o); assert(t); @@ -64,15 +64,27 @@ Constraints::constrain(TEnv& tenv, const AST* o, AType* t) push_back(Constraint(tenv.var(o), t, o->loc)); } -static void -substitute(ATuple* tup, const AST* from, AST* to) +template<typename T, typename E> +static const T* +substitute(const T* tup, const E* from, const E* to) { - if (!tup) return; - FOREACHP(ATuple::iterator, i, tup) - if (**i == *from) - *i = to; - else if (*i != to) - substitute((*i)->to<ATuple*>(), from, to); + if (!tup) return NULL; + T* ret = new T(*tup); + typename T::iterator ri = ret->begin(); + FOREACHP(typename T::const_iterator, i, tup) { + if (**i == *from) { + *ri++ = const_cast<E*>(to); + } else if (static_cast<const E*>(*i) != static_cast<const E*>(to)) { + const T* subTup = dynamic_cast<const T*>(*i); + if (subTup) + *ri++ = const_cast<E*>(substitute(subTup, from, to)); + else + *ri++ = *i; + } else { + ++ri; + } + } + return ret; } /// Compose two substitutions (TAPL 22.1.1) @@ -92,15 +104,16 @@ Subst::compose(const Subst& delta, const Subst& gamma) } /// Replace all occurrences of @a s with @a t -Constraints& -Constraints::replace(AType* s, AType* t) +Constraints +Constraints::replace(const AType* s, const AType* t) { + Constraints cp(*this); for (Constraints::iterator c = begin(); c != end();) { Constraints::iterator next = c; ++next; if (*c->first == *s) c->first = t; if (*c->second == *s) c->second = t; - substitute(c->first, s, t); - substitute(c->second, s, t); + c->first = substitute(c->first, s, t); + c->second = substitute(c->second, s, t); c = next; } return *this; @@ -114,8 +127,8 @@ unify(const Constraints& constraints) return Subst(); Constraints::const_iterator i = constraints.begin(); - AType* s = i->first; - AType* t = i->second; + const AType* s = i->first; + const AType* t = i->second; Constraints cp(++i, constraints.end()); if (*s == *t) { @@ -125,8 +138,8 @@ unify(const Constraints& constraints) } else if (t->kind == AType::VAR && !s->contains(t)) { return Subst::compose(unify(cp.replace(t, s)), Subst(t, s)); } else if (s->kind == AType::EXPR && t->kind == AType::EXPR) { - AType::iterator si = s->begin() + 1; - AType::iterator ti = t->begin() + 1; + AType::const_iterator si = s->begin() + 1; + AType::const_iterator ti = t->begin() + 1; for (; si != s->end() && ti != t->end(); ++si, ++ti) { AType* st = (*si)->as<AType*>(); AType* tt = (*ti)->as<AType*>(); |