diff options
-rw-r--r-- | gc.cpp | 2 | ||||
-rw-r--r-- | llvm.cpp | 21 | ||||
-rw-r--r-- | tuplr.cpp | 3 | ||||
-rw-r--r-- | tuplr.hpp | 6 | ||||
-rw-r--r-- | typing.cpp | 3 |
5 files changed, 30 insertions, 5 deletions
@@ -77,9 +77,11 @@ GC::collect(const Roots& roots) break; case GC::TAG_AST: AST* ast = (AST*)*i; + if (!ast->to<AType*>()) { // FIXME (ast)->~AST(); free((char*)(*i) - sizeof(Object::Header)); _heap.erase(i); + } break; } } @@ -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<ATuple*>(); - for (size_t i = 0; i < argsT.size(); ++i) - argsSubst[genericProtT->at(i)->to<AType*>()] = argsT.at(i)->to<AType*>(); + for (size_t i = 0; i < argsT.size(); ++i) { + const AType* genericArgT = genericProtT->at(i)->to<const AType*>(); + AType* callArgT = argsT.at(i)->to<AType*>(); + 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*>(); + AType* aT = callArgT->at(i)->to<AType*>(); + if (gT && aT) + argsSubst[gT] = aT; + } + } else { + argsSubst[genericArgT] = callArgT; + } + } // Apply substitution to get concrete type for this call thisType = argsSubst.apply(thisType)->as<AType*>(); @@ -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 @@ -345,7 +345,11 @@ struct Subst : public map<const AType*,AType*,typeLessThan> { } else { const_iterator i = find(in); if (i != end()) { - return i->second; + AST* out = i->second; + AType* outT = out->to<AType*>(); + if (outT && outT->kind == AType::EXPR && !outT->concrete()) + out = apply(out); + return out; } else { return in; } @@ -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 |