diff options
author | David Robillard <d@drobilla.net> | 2010-04-13 02:28:56 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-04-13 02:28:56 +0000 |
commit | 8675beae4f7a8415fc2e88451da95dc068719194 (patch) | |
tree | 599de9b6730a14035a25f7d9e0467f96866185ed /src/c.cpp | |
parent | 1f988f420ba3827941886962680f3e2ad6f01740 (diff) | |
download | resp-8675beae4f7a8415fc2e88451da95dc068719194.tar.gz resp-8675beae4f7a8415fc2e88451da95dc068719194.tar.bz2 resp-8675beae4f7a8415fc2e88451da95dc068719194.zip |
Restructure as a source translation based compiler.
Implement support for closures (via lambda lifting phase).
git-svn-id: http://svn.drobilla.net/resp/resp@254 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/c.cpp')
-rw-r--r-- | src/c.cpp | 64 |
1 files changed, 30 insertions, 34 deletions
@@ -42,7 +42,9 @@ static inline Function* llFunc(CFunc f) { return static_cast<Function*>(f); } static const Type* llType(const AType* t) { - if (t->kind == AType::PRIM) { + if (t == NULL) { + return NULL; + } else if (t->kind == AType::PRIM) { if (t->head()->str() == "Nothing") return new string("void"); if (t->head()->str() == "Bool") return new string("bool"); if (t->head()->str() == "Int") return new string("int"); @@ -66,8 +68,19 @@ llType(const AType* t) *ret += ")"; return ret; + } else if (t->kind == AType::EXPR && t->head()->str() == "Tup") { + Type* ret = new Type("struct { void* me; "); + for (AType::const_iterator i = t->begin() + 1; i != t->end(); ++i) { + const Type* lt = llType((*i)->to<const AType*>()); + if (!lt) + return NULL; + ret->append("; "); + ret->append(*lt); + } + ret->append("}*"); + return ret; } - return NULL; // non-primitive type + return new Type("void*"); } @@ -116,7 +129,7 @@ struct CEngine : public Engine { return f; } - void finishFunction(CEnv& cenv, CFunc f, const AType* retT, CVal ret) { + void finishFunction(CEnv& cenv, CFunc f, CVal ret) { out += "return " + *(Value*)ret + ";\n}\n\n"; } @@ -124,7 +137,7 @@ struct CEngine : public Engine { cenv.err << "C backend does not support JIT (eraseFunction)" << endl; } - CVal compileCall(CEnv& cenv, CFunc func, const vector<CVal>& args) { + CVal compileCall(CEnv& cenv, CFunc func, const AType* funcT, const vector<CVal>& args) { Value* varname = new string(cenv.penv.gensymstr("x")); Function* f = llFunc(func); out += (format("const %s %s = %s(") % f->returnType % *varname % f->name).str(); @@ -134,21 +147,21 @@ struct CEngine : public Engine { return varname; } - CFunc compileFunction(CEnv& cenv, AFn* fn, const AType& argsT); + CFunc compileFunction(CEnv& cenv, AFn* fn, const AType* type); CVal compileTup(CEnv& cenv, const AType* type, const vector<CVal>& fields); CVal compileDot(CEnv& cenv, CVal tup, int32_t index); CVal compileLiteral(CEnv& cenv, AST* lit); CVal compilePrimitive(CEnv& cenv, APrimitive* prim); CVal compileIf(CEnv& cenv, AIf* aif); - CVal compileGlobal(CEnv& cenv, AType* type, const string& name, CVal val); + CVal compileGlobal(CEnv& cenv, const AType* type, const string& name, CVal val); CVal getGlobal(CEnv& cenv, CVal val); void writeModule(CEnv& cenv, std::ostream& os) { os << out; } - const string call(CEnv& cenv, CFunc f, AType* retT) { + const string call(CEnv& cenv, CFunc f, const AType* retT) { cenv.err << "C backend does not support JIT (call)" << endl; return ""; } @@ -185,28 +198,14 @@ CEngine::compileLiteral(CEnv& cenv, AST* lit) } CFunc -CEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT) +CEngine::compileFunction(CEnv& cenv, AFn* fn, const AType* type) { - CEngine* engine = reinterpret_cast<CEngine*>(cenv.engine()); - AType* genericType = cenv.type(fn); - AType* thisType = genericType; - Subst argsSubst; - - // Build and apply substitution to get concrete type for this call - if (!genericType->concrete()) { - argsSubst = cenv.tenv.buildSubst(genericType, argsT); - thisType = argsSubst.apply(genericType)->as<AType*>(); - } - - THROW_IF(!thisType->concrete(), fn->loc, - string("call has non-concrete type %1%\n") + thisType->str()); - - Object::pool.addRoot(thisType); - CFunc f = fn->impls.find(thisType); - if (f) - return f; + assert(type->concrete()); - ATuple* protT = thisType->prot(); + CEngine* engine = reinterpret_cast<CEngine*>(cenv.engine()); + const AType* argsT = type->prot()->as<const AType*>(); + const AType* retT = type->last()->as<const AType*>(); + Subst argsSubst = cenv.tenv.buildSubst(type, *argsT); vector<string> argNames; for (ATuple::const_iterator i = fn->prot()->begin(); i != fn->prot()->end(); ++i) @@ -214,9 +213,7 @@ CEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT) // Write function declaration const string name = (fn->name == "") ? cenv.penv.gensymstr("_fn") : fn->name; - f = llFunc(cenv.engine()->startFunction(cenv, name, - thisType->last()->to<AType*>(), - *protT, argNames)); + Function* f = llFunc(cenv.engine()->startFunction(cenv, name, retT, *argsT, argNames)); cenv.push(); Subst oldSubst = cenv.tsubst; @@ -225,7 +222,7 @@ CEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT) // Bind argument values in CEnv vector<Value*> args; AFn::const_iterator p = fn->prot()->begin(); - ATuple::const_iterator pT = protT->begin(); + ATuple::const_iterator pT = argsT->begin(); for (; p != fn->prot()->end(); ++p, ++pT) { AType* t = (*pT)->as<AType*>(); const Type* lt = llType(t); @@ -235,11 +232,10 @@ CEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT) // Write function body try { - fn->impls.push_back(make_pair(thisType, f)); CVal retVal = NULL; for (AFn::iterator i = fn->begin() + 2; i != fn->end(); ++i) retVal = (*i)->compile(cenv); - cenv.engine()->finishFunction(cenv, f, cenv.type(fn->last()), retVal); + cenv.engine()->finishFunction(cenv, f, retVal); } catch (Error& e) { cenv.pop(); throw e; @@ -314,7 +310,7 @@ CEngine::compilePrimitive(CEnv& cenv, APrimitive* prim) } CVal -CEngine::compileGlobal(CEnv& cenv, AType* type, const string& name, CVal val) +CEngine::compileGlobal(CEnv& cenv, const AType* type, const string& name, CVal val) { return NULL; } |