aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm.cpp39
-rw-r--r--tuplr.hpp27
-rw-r--r--typing.cpp4
3 files changed, 49 insertions, 21 deletions
diff --git a/llvm.cpp b/llvm.cpp
index 053e2e2..b5e397e 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -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);
diff --git a/tuplr.hpp b/tuplr.hpp
index 382b9d4..5275dfd 100644
--- a/tuplr.hpp
+++ b/tuplr.hpp
@@ -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(); }
diff --git a/typing.cpp b/typing.cpp
index cfc1104..0e63f26 100644
--- a/typing.cpp
+++ b/typing.cpp
@@ -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;
}