diff options
author | David Robillard <d@drobilla.net> | 2009-06-28 03:06:22 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-06-28 03:06:22 +0000 |
commit | 87778a3526c38e0570a9462bf28ae87d38cf8ad1 (patch) | |
tree | ba8b3b95d398b889e6009c6cfa84e9990e7bc726 | |
parent | 7ee03dcd4fa9bdbd94678f044133ba852c152532 (diff) | |
download | resp-87778a3526c38e0570a9462bf28ae87d38cf8ad1.tar.gz resp-87778a3526c38e0570a9462bf28ae87d38cf8ad1.tar.bz2 resp-87778a3526c38e0570a9462bf28ae87d38cf8ad1.zip |
Fix type substitution.
git-svn-id: http://svn.drobilla.net/resp/tuplr@158 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r-- | llvm.cpp | 39 | ||||
-rw-r--r-- | tuplr.hpp | 27 | ||||
-rw-r--r-- | typing.cpp | 4 |
3 files changed, 49 insertions, 21 deletions
@@ -47,6 +47,25 @@ llType(const AType* t) if (t->at(0)->str() == "Int") return Type::Int32Ty; if (t->at(0)->str() == "Float") return Type::FloatTy; throw Error(t->loc, string("Unknown primitive type `") + t->str() + "'"); + /*} else if (t->kind == AType::EXPR && t->at(0)->str() == "Fn") { + AType* retT = t->at(2)->as<AType*>(); + if (!llType(retT)) + return NULL; + + vector<const Type*> cprot; + const ATuple* prot = t->at(1)->to<ATuple*>(); + for (size_t i = 0; i < prot->size(); ++i) { + AType* at = prot->at(i)->to<AType*>(); + const Type* lt = llType(at); + if (lt) + cprot.push_back(lt); + else + return NULL; + } + + FunctionType* fT = FunctionType::get(llType(retT), cprot, false); + return PointerType::get(fT, 0); + */ } return NULL; // non-primitive type } @@ -120,6 +139,9 @@ struct LLVMEngine : public Engine { builder.CreateRetVoid(); } + /*std::cerr << "MODULE {" << endl; + module->dump(); + std::cerr << "}" << endl;*/ verifyFunction(*static_cast<Function*>(f)); if (cenv.args.find("-g") == cenv.args.end()) opt.run(*static_cast<Function*>(f)); @@ -230,10 +252,11 @@ AFn::liftCall(CEnv& cenv, const AType& argsT) { TEnv::GenericTypes::const_iterator gt = cenv.tenv.genericTypes.find(this); assert(gt != cenv.tenv.genericTypes.end()); - AType* thisType = new AType(*gt->second); + AType* genericType = new AType(*gt->second); + AType* thisType = genericType; Subst argsSubst; - if (!thisType->concrete()) { + if (!genericType->concrete()) { // Build substitution to apply to generic type assert(argsT.size() == prot()->size()); ATuple* genericProtT = gt->second->at(1)->as<ATuple*>(); @@ -249,18 +272,18 @@ AFn::liftCall(CEnv& cenv, const AType& argsT) AType* gT = genericArgT->at(i)->to<AType*>(); AType* aT = callArgT->at(i)->to<AType*>(); if (gT && aT) - argsSubst[gT] = aT; + argsSubst.add(gT, aT); } } else { - argsSubst[genericArgT] = callArgT; + argsSubst.add(genericArgT, callArgT); } } // Apply substitution to get concrete type for this call - thisType = argsSubst.apply(thisType)->as<AType*>(); - if (!thisType->concrete()) - throw Error(loc, string("unable to resolve concrete type for function :: ") - + thisType->str() + "\n" + this->str()); + thisType = argsSubst.apply(genericType)->as<AType*>(); + THROW_IF(!thisType->concrete(), loc, + string("unable to resolve concrete type for function :: ") + + thisType->str() + "\n" + this->str()); } Object::pool.addRoot(thisType); @@ -307,9 +307,6 @@ struct AType : public ATuple { } return true; } - bool operator<(const AType& rhs) const { - return kind < rhs.kind || id < rhs.id; - } bool operator==(const AST& rhs) const { const AType* rt = rhs.to<const AType*>(); if (!rt || kind != rt->kind) @@ -326,14 +323,17 @@ struct AType : public ATuple { unsigned id; }; -struct typeLessThan { - inline bool operator()(const AType* a, const AType* b) const { return *a < *b; } -}; - /// Type substitution -struct Subst : public map<const AType*,AType*,typeLessThan> { - Subst(AType* s=0, AType* t=0) { if (s && t) { assert(s != t); insert(make_pair(s, t)); } } +struct Subst : public list< pair<const AType*,AType*> > { + Subst(AType* s=0, AType* t=0) { if (s && t) { assert(s != t); push_back(make_pair(s, t)); } } static Subst compose(const Subst& delta, const Subst& gamma); + void add(const AType* from, AType* to) { push_back(make_pair(from, to)); } + const_iterator find(const AType* t) const { + for (const_iterator j = begin(); j != end(); ++j) + if (*j->first == *t) + return j; + return end(); + } AST* apply(AST* ast) const { AType* in = ast->to<AType*>(); if (!in) return ast; @@ -357,6 +357,12 @@ struct Subst : public map<const AType*,AType*,typeLessThan> { } }; +inline ostream& operator<<(ostream& out, const Subst& s) { + for (Subst::const_iterator i = s.begin(); i != s.end(); ++i) + out << i->first << " => " << i->second << endl; + return out; +} + /// Fn (first-class function with captured lexical bindings) struct AFn : public ATuple { AFn(Cursor c, AST* ast, va_list args) : ATuple(c, ast, args) {} @@ -598,8 +604,7 @@ struct CEnv { ~CEnv() { Object::pool.collect(GC::Roots()); } - typedef Env<const ASymbol*, AST*> Code; - typedef Env<const AST*, CValue> Vals; + typedef Env<const AST*, CValue> Vals; Engine* engine() { return _engine; } void push() { tenv.push(); vals.push(); } @@ -252,11 +252,11 @@ Subst::compose(const Subst& delta, const Subst& gamma) // TAPL 22.1.1 Subst r; for (Subst::const_iterator g = gamma.begin(); g != gamma.end(); ++g) { Subst::const_iterator d = delta.find(g->second); - r.insert(make_pair(g->first, ((d != delta.end()) ? d : g)->second)); + r.add(g->first, ((d != delta.end()) ? d : g)->second); } for (Subst::const_iterator d = delta.begin(); d != delta.end(); ++d) { if (gamma.find(d->first) == gamma.end()) - r.insert(*d); + r.add(d->first, d->second); } return r; } |