aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-10-15 16:50:14 +0000
committerDavid Robillard <d@drobilla.net>2009-10-15 16:50:14 +0000
commit0ee5ad002dbe88c791bfa48e392094bade72a12c (patch)
tree918300d71be5f8b18ce6274ec9bcb2de986916c1
parent9fe6831a3f9f0b9c062f3cd570327bfb828667d9 (diff)
downloadresp-0ee5ad002dbe88c791bfa48e392094bade72a12c.tar.gz
resp-0ee5ad002dbe88c791bfa48e392094bade72a12c.tar.bz2
resp-0ee5ad002dbe88c791bfa48e392094bade72a12c.zip
Clean up function type system.
Unify function types globally, rather than construct a "generic type" locally, since this didn't take into consideration captured bindings, leaving the generic type not as solved as it could be. git-svn-id: http://svn.drobilla.net/resp/tuplr@226 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--src/c.cpp5
-rw-r--r--src/constrain.cpp87
-rw-r--r--src/llvm.cpp6
-rw-r--r--src/tuplr.hpp10
4 files changed, 44 insertions, 64 deletions
diff --git a/src/c.cpp b/src/c.cpp
index 1237979..795a57f 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -168,10 +168,7 @@ CEngine::compileLiteral(CEnv& cenv, AST* lit)
CFunc
CEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT)
{
- //TEnv::GenericTypes::const_iterator gt = cenv.tenv.genericTypes.find(fn);
- //assert(gt != cenv.tenv.genericTypes.end());
CEngine* engine = reinterpret_cast<CEngine*>(cenv.engine());
- //AType* genericType = new AType(*gt->second);
AType* genericType = cenv.type(fn);
AType* thisType = genericType;
Subst argsSubst;
@@ -204,7 +201,7 @@ CEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT)
cenv.push();
Subst oldSubst = cenv.tsubst;
- cenv.tsubst = Subst::compose(cenv.tsubst, Subst::compose(argsSubst, fn->subst));
+ cenv.tsubst = Subst::compose(cenv.tsubst, argsSubst);
// Bind argument values in CEnv
vector<Value*> args;
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
diff --git a/src/llvm.cpp b/src/llvm.cpp
index d022413..1b01e4d 100644
--- a/src/llvm.cpp
+++ b/src/llvm.cpp
@@ -224,10 +224,8 @@ LLVMEngine::compileLiteral(CEnv& cenv, AST* lit)
CFunc
LLVMEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT)
{
- TEnv::GenericTypes::const_iterator gt = cenv.tenv.genericTypes.find(fn);
- assert(gt != cenv.tenv.genericTypes.end());
LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
- AType* genericType = new AType(*gt->second);
+ AType* genericType = cenv.type(cenv.resolve(fn));
AType* thisType = genericType;
Subst argsSubst;
@@ -259,7 +257,7 @@ LLVMEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT)
cenv.push();
Subst oldSubst = cenv.tsubst;
- cenv.tsubst = Subst::compose(cenv.tsubst, Subst::compose(argsSubst, fn->subst));
+ cenv.tsubst = Subst::compose(cenv.tsubst, argsSubst);
// Bind argument values in CEnv
vector<Value*> args;
diff --git a/src/tuplr.hpp b/src/tuplr.hpp
index 947a62c..a89b612 100644
--- a/src/tuplr.hpp
+++ b/src/tuplr.hpp
@@ -375,9 +375,8 @@ struct AFn : public ATuple {
return NULL;
}
};
- Impls impls;
- mutable Subst subst;
- string name;
+ Impls impls;
+ string name;
};
/// Function call/application, e.g. "(func arg1 arg2)"
@@ -564,10 +563,9 @@ struct TEnv : public Env<const ASymbol*, AType*> {
}
static Subst buildSubst(AType* fnT, const AType& argsT);
- typedef map<const AST*, AType*> Vars;
- typedef map<const AFn*, const AType*> GenericTypes;
+ typedef map<const AST*, AType*> Vars;
+
Vars vars;
- GenericTypes genericTypes;
PEnv& penv;
unsigned varID;
};