aboutsummaryrefslogtreecommitdiffstats
path: root/src/constrain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/constrain.cpp')
-rw-r--r--src/constrain.cpp35
1 files changed, 15 insertions, 20 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);
}