aboutsummaryrefslogtreecommitdiffstats
path: root/src/c.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/c.cpp')
-rw-r--r--src/c.cpp64
1 files changed, 30 insertions, 34 deletions
diff --git a/src/c.cpp b/src/c.cpp
index 7dbb6c2..c456132 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -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;
}