aboutsummaryrefslogtreecommitdiffstats
path: root/src/constrain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/constrain.cpp')
-rw-r--r--src/constrain.cpp22
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")