aboutsummaryrefslogtreecommitdiffstats
path: root/src/unify.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-04-13 02:28:56 +0000
committerDavid Robillard <d@drobilla.net>2010-04-13 02:28:56 +0000
commit8675beae4f7a8415fc2e88451da95dc068719194 (patch)
tree599de9b6730a14035a25f7d9e0467f96866185ed /src/unify.cpp
parent1f988f420ba3827941886962680f3e2ad6f01740 (diff)
downloadresp-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.cpp49
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*>();