diff options
Diffstat (limited to 'src/constrain.cpp')
-rw-r--r-- | src/constrain.cpp | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/src/constrain.cpp b/src/constrain.cpp index cb7b700..2e23f7c 100644 --- a/src/constrain.cpp +++ b/src/constrain.cpp @@ -65,15 +65,17 @@ ATuple::constrain(TEnv& tenv, Constraints& c) const throw(Error) c.constrain(tenv, this, t); } -void -AFn::constrain(TEnv& tenv, Constraints& c) const throw(Error) +static void +constrain_fn(TEnv& tenv, Constraints& c, const ACall* call) throw(Error) { set<const ASymbol*> defs; TEnv::Frame frame; + const ATuple* const prot = call->prot(); + // Add parameters to environment frame TList protT; - for (ATuple::const_iterator i = prot()->begin(); i != prot()->end(); ++i) { + for (ATuple::const_iterator i = prot->begin(); i != prot->end(); ++i) { const ASymbol* sym = (*i)->to<const ASymbol*>(); THROW_IF(!sym, (*i)->loc, "parameter name is not a symbol"); THROW_IF(defs.count(sym) != 0, sym->loc, @@ -83,13 +85,13 @@ AFn::constrain(TEnv& tenv, Constraints& c) const throw(Error) frame.push_back(make_pair(sym, tvar)); protT.push_back(const_cast<AType*>(tvar)); } - protT.head->loc = loc; + protT.head->loc = call->loc; - const_iterator i = iter_at(1); + ATuple::const_iterator i = call->iter_at(1); c.constrain(tenv, *i, protT); // Add internal definitions to environment frame - for (++i; i != end(); ++i) { + for (++i; i != call->end(); ++i) { const AST* exp = *i; const ACall* call = exp->to<const ACall*>(); if (call && is_form(call, "def")) { @@ -104,18 +106,18 @@ AFn::constrain(TEnv& tenv, Constraints& c) const throw(Error) tenv.push(frame); const AST* exp = NULL; - for (i = iter_at(2); i != end(); ++i) { + for (i = call->iter_at(2); i != call->end(); ++i) { exp = *i; exp->constrain(tenv, c); } const AType* bodyT = tenv.var(exp); - const AType* fnT = tup<const AType>(loc, tenv.Fn, protT.head, bodyT, 0); + const AType* fnT = tup<const AType>(call->loc, tenv.Fn, protT.head, bodyT, 0); Object::pool.addRoot(fnT); tenv.pop(); - c.constrain(tenv, this, fnT); + c.constrain(tenv, call, fnT); } static void @@ -364,6 +366,8 @@ ACall::constrain(TEnv& tenv, Constraints& c) const throw(Error) const std::string form = sym->cppstr; if (is_primitive(tenv.penv, this)) constrain_primitive(tenv, c, this); + else if (form == "fn") + constrain_fn(tenv, c, this); else if (form == "def") constrain_def(tenv, c, this); else if (form == "def-type") |