diff options
Diffstat (limited to 'src/c.cpp')
-rw-r--r-- | src/c.cpp | 67 |
1 files changed, 39 insertions, 28 deletions
@@ -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")); |