aboutsummaryrefslogtreecommitdiffstats
path: root/src/c.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/c.cpp')
-rw-r--r--src/c.cpp67
1 files changed, 39 insertions, 28 deletions
diff --git a/src/c.cpp b/src/c.cpp
index 74dceb2..2dc51d5 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -49,14 +49,15 @@ llType(const AType* t)
if (t->head()->str() == "Float") return new string("float");
throw Error(t->loc, string("Unknown primitive type `") + t->str() + "'");
} else if (t->kind == AType::EXPR && t->head()->str() == "Fn") {
- const AType* retT = t->at(2)->as<const AType*>();
+ AType::const_iterator i = t->begin();
+ const ATuple* protT = (*++i)->to<const ATuple*>();
+ const AType* retT = (*i)->as<const AType*>();
if (!llType(retT))
return NULL;
Type* ret = new Type(*llType(retT) + " (*)(");
- const ATuple* prot = t->at(1)->to<const ATuple*>();
- for (size_t i = 0; i < prot->size(); ++i) {
- const AType* at = prot->at(i)->to<const AType*>();
+ FOREACHP(ATuple::const_iterator, i, protT) {
+ const AType* at = (*i)->to<const AType*>();
const Type* lt = llType(at);
if (!lt)
return NULL;
@@ -102,10 +103,12 @@ struct CEngine : public Engine {
f->returnType = *llType(retT);
f->name = name;
f->text += f->returnType + "\n" + f->name + "(";
- for (size_t i = 0; i != argsT.size(); ++i) {
- if (i > 0)
+ ATuple::const_iterator ai = argsT.begin();
+ vector<string>::const_iterator ni = argNames.begin();
+ for (; ai != argsT.end(); ++ai, ++ni) {
+ if (ai != argsT.begin())
f->text += ", ";
- f->text += *llType(argsT.at(i)->as<const AType*>()) + " " + argNames.at(i);
+ f->text += *llType((*ai)->as<const AType*>()) + " " + *ni;
}
f->text += ")\n{\n";
@@ -187,16 +190,16 @@ CEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT)
if (f)
return f;
- ATuple* protT = thisType->at(1)->as<ATuple*>();
+ ATuple* protT = thisType->prot();
vector<string> argNames;
- for (size_t i = 0; i < fn->prot()->size(); ++i)
- argNames.push_back(fn->prot()->at(i)->str());
+ for (ATuple::const_iterator i = fn->prot()->begin(); i != fn->prot()->end(); ++i)
+ argNames.push_back((*i)->str());
// Write function declaration
const string name = (fn->name == "") ? cenv.penv.gensymstr("_fn") : fn->name;
f = llFunc(cenv.engine()->startFunction(cenv, name,
- thisType->at(thisType->size()-1)->to<AType*>(),
+ thisType->last()->to<AType*>(),
*protT, argNames));
cenv.push();
@@ -205,22 +208,22 @@ CEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT)
// Bind argument values in CEnv
vector<Value*> args;
- AFn::const_iterator p = fn->prot()->begin();
- size_t i = 0;
- for (; p != fn->prot()->end(); ++p, ++i) {
- AType* t = protT->at(i)->as<AType*>();
+ AFn::const_iterator p = fn->prot()->begin();
+ ATuple::const_iterator pT = protT->begin();
+ for (; p != fn->prot()->end(); ++p, ++pT) {
+ AType* t = (*pT)->as<AType*>();
const Type* lt = llType(t);
THROW_IF(!lt, fn->loc, "untyped parameter\n");
- cenv.def((*p)->as<ASymbol*>(), *p, t, new string(fn->prot()->at(i)->str()));
+ cenv.def((*p)->as<ASymbol*>(), *p, t, new string((*p)->str()));
}
// Write function body
try {
fn->impls.push_back(make_pair(thisType, f));
CVal retVal = NULL;
- for (size_t i = 2; i < fn->size(); ++i)
- retVal = fn->at(i)->compile(cenv);
- cenv.engine()->finishFunction(cenv, f, cenv.type(fn->at(fn->size() - 1)), retVal);
+ 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);
} catch (Error& e) {
cenv.pop();
throw e;
@@ -236,20 +239,25 @@ CEngine::compileIf(CEnv& cenv, AIf* aif)
CEngine* engine = reinterpret_cast<CEngine*>(cenv.engine());
Value* varname = new string(cenv.penv.gensymstr("if"));
out += (format("%s %s;\n") % *llType(cenv.type(aif)) % *varname).str();
- for (size_t i = 1; i < aif->size() - 1; i += 2) {
- if (i > 1)
+ size_t idx = 1;
+ for (AIf::iterator i = aif->begin() + 1; ; ++i, idx += 2) {
+ AIf::iterator next = i;
+ if (++next == aif->end())
+ break;
+
+ if (idx > 1)
out += "else {\n";
- Value* condV = llVal(aif->at(i)->compile(cenv));
+ Value* condV = llVal((*i)->compile(cenv));
out += (format("if (%s) {\n") % *condV).str();
- Value* thenV = llVal(aif->at(i + 1)->compile(cenv));
+ Value* thenV = llVal((*next)->compile(cenv));
out += (format("%s = %s;\n}\n") % *varname % *thenV).str();
}
// Emit final else block
out += "else {\n";
- Value* elseV = llVal(aif->at(aif->size() - 1)->compile(cenv));
+ Value* elseV = llVal(aif->last()->compile(cenv));
out += (format("%s = %s;\n}\n") % *varname % *elseV).str();
for (size_t i = 1; i < (aif->size() - 1) / 2; ++i)
@@ -261,9 +269,12 @@ CEngine::compileIf(CEnv& cenv, AIf* aif)
CVal
CEngine::compilePrimitive(CEnv& cenv, APrimitive* prim)
{
+ APrimitive::iterator i = prim->begin();
+ ++i;
+
CEngine* engine = reinterpret_cast<CEngine*>(cenv.engine());
- Value* a = llVal(prim->at(1)->compile(cenv));
- Value* b = llVal(prim->at(2)->compile(cenv));
+ Value* a = llVal((*i++)->compile(cenv));
+ Value* b = llVal((*i++)->compile(cenv));
const string n = prim->head()->to<ASymbol*>()->str();
string op = n;
@@ -277,8 +288,8 @@ CEngine::compilePrimitive(CEnv& cenv, APrimitive* prim)
string val("(");
val += *a + op + *b;
- for (size_t i = 3; i < prim->size(); ++i)
- val += op + *llVal(prim->at(i)->compile(cenv));
+ while (i != prim->end())
+ val += op + *llVal((*i++)->compile(cenv));
val += ")";
Value* varname = new string(cenv.penv.gensymstr("x"));