aboutsummaryrefslogtreecommitdiffstats
path: root/src/constrain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/constrain.cpp')
-rw-r--r--src/constrain.cpp87
1 files changed, 37 insertions, 50 deletions
diff --git a/src/constrain.cpp b/src/constrain.cpp
index 97af0af..b4afe09 100644
--- a/src/constrain.cpp
+++ b/src/constrain.cpp
@@ -61,62 +61,49 @@ ATuple::constrain(TEnv& tenv, Constraints& c) const
void
AFn::constrain(TEnv& tenv, Constraints& c) const
{
- const AType* genericType;
- TEnv::GenericTypes::const_iterator gt = tenv.genericTypes.find(this);
- if (gt != tenv.genericTypes.end()) {
- genericType = gt->second;
- } else {
- set<const ASymbol*> defs;
- TEnv::Frame frame;
-
- // Add parameters to environment frame
- AType* protT = tup<AType>(loc, NULL);
- 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,
- (format("duplicate parameter `%1%'") % sym->str()).str());
- defs.insert(sym);
- AType* tvar = tenv.fresh(sym);
- frame.push_back(make_pair(sym, tvar));
- protT->push_back(tvar);
- }
- c.constrain(tenv, at(1), protT);
-
- // Add internal definitions to environment frame
- size_t e = 2;
- for (; e < size(); ++e) {
- const AST* exp = at(e);
- const ADef* def = exp->to<const ADef*>();
- if (def) {
- const ASymbol* sym = def->sym();
- THROW_IF(defs.count(sym) != 0, def->loc,
- (format("`%1%' defined twice") % sym->str()).str());
- defs.insert(def->sym());
- frame.push_back(make_pair(def->sym(), (AType*)NULL));
- }
+ set<const ASymbol*> defs;
+ TEnv::Frame frame;
+
+ // Add parameters to environment frame
+ AType* protT = tup<AType>(loc, NULL);
+ 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,
+ (format("duplicate parameter `%1%'") % sym->str()).str());
+ defs.insert(sym);
+ AType* tvar = tenv.fresh(sym);
+ frame.push_back(make_pair(sym, tvar));
+ protT->push_back(tvar);
+ }
+ c.constrain(tenv, at(1), protT);
+
+ // Add internal definitions to environment frame
+ for (const_iterator i = begin() + 2; i != end(); ++i) {
+ const AST* exp = *i;
+ const ADef* def = exp->to<const ADef*>();
+ if (def) {
+ const ASymbol* sym = def->sym();
+ THROW_IF(defs.count(sym) != 0, def->loc,
+ (format("`%1%' defined twice") % sym->str()).str());
+ defs.insert(def->sym());
+ frame.push_back(make_pair(def->sym(), (AType*)NULL));
}
+ }
- tenv.push(frame);
-
- Constraints cp;
- cp.push_back(Constraint(tenv.var(this), tenv.var(), loc));
+ tenv.push(frame);
- for (size_t i = 2; i < size(); ++i)
- at(i)->constrain(tenv, cp);
+ c.constrain(tenv, this, tenv.var());
+ for (size_t i = 2; i < size(); ++i)
+ at(i)->constrain(tenv, c);
- AType* bodyT = tenv.var(at(e-1));
- subst = unify(cp);
- genericType = tup<AType>(loc, tenv.penv.sym("Fn"),
- subst.apply(protT), subst.apply(bodyT), 0);
- tenv.genericTypes.insert(make_pair(this, genericType));
- Object::pool.addRoot(genericType);
+ AType* bodyT = tenv.var(at(size() - 1));
+ AType* fnT = tup<AType>(loc, tenv.penv.sym("Fn"), protT, bodyT, 0);
+ Object::pool.addRoot(fnT);
- tenv.pop();
- }
+ tenv.pop();
- AType* t = new AType(*genericType); // FIXME: deep copy
- c.constrain(tenv, this, t);
+ c.constrain(tenv, this, fnT);
}
void