From 14a96af1b4554e75506621c3cc9b2c107f01a119 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 27 Jun 2009 03:07:33 +0000 Subject: Fix substitution of call argument types to generic function type to work with expressions (e.g. fix inferring return type from the return type of a parameter). git-svn-id: http://svn.drobilla.net/resp/tuplr@154 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- gc.cpp | 2 ++ llvm.cpp | 21 +++++++++++++++++++-- tuplr.cpp | 3 ++- tuplr.hpp | 6 +++++- typing.cpp | 3 ++- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/gc.cpp b/gc.cpp index 6311058..3964324 100644 --- a/gc.cpp +++ b/gc.cpp @@ -77,9 +77,11 @@ GC::collect(const Roots& roots) break; case GC::TAG_AST: AST* ast = (AST*)*i; + if (!ast->to()) { // FIXME (ast)->~AST(); free((char*)(*i) - sizeof(Object::Header)); _heap.erase(i); + } break; } } diff --git a/llvm.cpp b/llvm.cpp index e963336..65632a4 100644 --- a/llvm.cpp +++ b/llvm.cpp @@ -234,12 +234,29 @@ AFn::liftCall(CEnv& cenv, const AType& argsT) assert(gt != cenv.tenv.genericTypes.end()); AType* thisType = new AType(*gt->second); Subst argsSubst; + if (!thisType->concrete()) { // Build substitution to apply to generic type assert(argsT.size() == prot()->size()); ATuple* genericProtT = gt->second->at(1)->as(); - for (size_t i = 0; i < argsT.size(); ++i) - argsSubst[genericProtT->at(i)->to()] = argsT.at(i)->to(); + for (size_t i = 0; i < argsT.size(); ++i) { + const AType* genericArgT = genericProtT->at(i)->to(); + AType* callArgT = argsT.at(i)->to(); + assert(genericArgT); + assert(callArgT); + if (callArgT->kind == AType::EXPR) { + assert(genericArgT->kind == AType::EXPR); + assert(callArgT->size() == genericArgT->size()); + for (size_t i = 0; i < callArgT->size(); ++i) { + AType* gT = genericArgT->at(i)->to(); + AType* aT = callArgT->at(i)->to(); + if (gT && aT) + argsSubst[gT] = aT; + } + } else { + argsSubst[genericArgT] = callArgT; + } + } // Apply substitution to get concrete type for this call thisType = argsSubst.apply(thisType)->as(); diff --git a/tuplr.cpp b/tuplr.cpp index 7dd3e9b..5aaf54a 100644 --- a/tuplr.cpp +++ b/tuplr.cpp @@ -250,7 +250,8 @@ eval(CEnv& cenv, const string& name, istream& is) result->constrain(cenv.tenv, c); // Constrain types cenv.tsubst = Subst::compose(cenv.tsubst, TEnv::unify(c)); // Solve type constraints resultType = cenv.type(result); - result->lift(cenv); // Lift functions + if (resultType->concrete()) + result->lift(cenv); // Lift functions exprs.push_back(make_pair(exp, result)); // Add definitions as GC roots diff --git a/tuplr.hpp b/tuplr.hpp index 69f6bfd..382b9d4 100644 --- a/tuplr.hpp +++ b/tuplr.hpp @@ -345,7 +345,11 @@ struct Subst : public map { } else { const_iterator i = find(in); if (i != end()) { - return i->second; + AST* out = i->second; + AType* outT = out->to(); + if (outT && outT->kind == AType::EXPR && !outT->concrete()) + out = apply(out); + return out; } else { return in; } diff --git a/typing.cpp b/typing.cpp index 4781b2e..cfc1104 100644 --- a/typing.cpp +++ b/typing.cpp @@ -115,7 +115,8 @@ AFn::constrain(TEnv& tenv, Constraints& c) const subst = tsubst; } - c.constrain(tenv, this, new AType(*genericType)); + AType* t = new AType(*genericType); // FIXME: deep copy + c.constrain(tenv, this, t); } void -- cgit v1.2.1