From 0ee5ad002dbe88c791bfa48e392094bade72a12c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 15 Oct 2009 16:50:14 +0000 Subject: 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 --- src/c.cpp | 5 +--- src/constrain.cpp | 87 +++++++++++++++++++++++-------------------------------- src/llvm.cpp | 6 ++-- src/tuplr.hpp | 10 +++---- 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(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 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 defs; - TEnv::Frame frame; - - // Add parameters to environment frame - AType* protT = tup(loc, NULL); - for (ATuple::const_iterator i = prot()->begin(); i != prot()->end(); ++i) { - const ASymbol* sym = (*i)->to(); - 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(); - 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 defs; + TEnv::Frame frame; + + // Add parameters to environment frame + AType* protT = tup(loc, NULL); + for (ATuple::const_iterator i = prot()->begin(); i != prot()->end(); ++i) { + const ASymbol* sym = (*i)->to(); + 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(); + 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(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(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(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 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 { } static Subst buildSubst(AType* fnT, const AType& argsT); - typedef map Vars; - typedef map GenericTypes; + typedef map Vars; + Vars vars; - GenericTypes genericTypes; PEnv& penv; unsigned varID; }; -- cgit v1.2.1