aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-10-14 03:00:25 +0000
committerDavid Robillard <d@drobilla.net>2009-10-14 03:00:25 +0000
commit996faeb3c1fe8e43da77f47ead61179cfb83b5ce (patch)
treec633ca4e5a8fa59a751ad86eee44aa4781e7e81e
parente1ad4069755080e3fe08a0b39b460c6adc39698d (diff)
downloadresp-996faeb3c1fe8e43da77f47ead61179cfb83b5ce.tar.gz
resp-996faeb3c1fe8e43da77f47ead61179cfb83b5ce.tar.bz2
resp-996faeb3c1fe8e43da77f47ead61179cfb83b5ce.zip
Clean up ACall::constrain and stick to type domain for error reporting.
git-svn-id: http://svn.drobilla.net/resp/tuplr@220 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--src/constrain.cpp35
-rw-r--r--src/unify.cpp1
2 files changed, 15 insertions, 21 deletions
diff --git a/src/constrain.cpp b/src/constrain.cpp
index 85f3c35..8d44487 100644
--- a/src/constrain.cpp
+++ b/src/constrain.cpp
@@ -123,32 +123,27 @@ AFn::constrain(TEnv& tenv, Constraints& c) const
void
ACall::constrain(TEnv& tenv, Constraints& c) const
{
- at(0)->constrain(tenv, c);
- for (size_t i = 1; i < size(); ++i)
+ for (size_t i = 0; i < size(); ++i)
at(i)->constrain(tenv, c);
- const AST* callee = tenv.resolve(at(0));
- const AFn* closure = callee->to<const AFn*>();
- if (closure) {
- THROW_IF(size() - 1 != closure->prot()->size(), loc, "incorrect number of arguments");
- TEnv::GenericTypes::iterator gt = tenv.genericTypes.find(closure);
- if (gt != tenv.genericTypes.end()) {
- const ATuple* prot = gt->second->at(1)->to<const ATuple*>();
- const_iterator i = begin();
- const_iterator prot_i = prot->begin();
- for (++i; i != end(); ++i, ++prot_i)
- c.constrain(tenv, *i, (*prot_i)->as<AType*>());
- AType* retT = tenv.var(this);
- c.constrain(tenv, at(0),
- tup<AType>(at(0)->loc, tenv.penv.sym("Fn"), tenv.var(), retT, 0));
- c.constrain(tenv, this, retT);
- return;
- }
+ const AType* fnType = tenv.var(at(0));
+ if (fnType->kind != AType::VAR) {
+ if (fnType == AType::PRIM
+ || fnType->size() < 2
+ || !fnType->at(0)->to<const ASymbol*>()
+ || fnType->at(0)->to<const ASymbol*>()->cppstr != "Fn")
+ throw Error(loc, (format("call to non-function `%1%'") % at(0)->str()).str());
+
+ size_t numArgs = fnType->at(1)->to<const ATuple*>()->size();
+ THROW_IF(numArgs != size() - 1, loc,
+ (format("expected %1% arguments, got %2%") % numArgs % (size() - 1)).str());
}
+
+ AType* retT = tenv.var();
AType* argsT = tup<AType>(loc, 0);
for (size_t i = 1; i < size(); ++i)
argsT->push_back(tenv.var(at(i)));
- AType* retT = tenv.var();
+
c.constrain(tenv, at(0), tup<AType>(at(0)->loc, tenv.penv.sym("Fn"), argsT, retT, 0));
c.constrain(tenv, this, retT);
}
diff --git a/src/unify.cpp b/src/unify.cpp
index eebd75c..8aac926 100644
--- a/src/unify.cpp
+++ b/src/unify.cpp
@@ -125,7 +125,6 @@ unify(const Constraints& constraints)
cp.replace(t, s);
return Subst::compose(unify(cp), Subst(t, s));
} else if (s->kind == AType::EXPR && s->kind == t->kind && s->size() == t->size()) {
- assert(*s->at(0)->to<ASymbol*>() == *t->at(0)->to<ASymbol*>());
for (size_t i = 1; i < s->size(); ++i) {
AType* si = s->at(i)->to<AType*>();
AType* ti = t->at(i)->to<AType*>();