# HG changeset patch # User lindquist # Date 1191530333 -7200 # Node ID bc641b23a714f9154810784ff32e269cad4bbbfe # Parent a86fe7496b58eaf8c21b77bf34d44646f796e002 [svn r37] * Initial support for foreach on static arrays. Not 100% complete diff -r a86fe7496b58 -r bc641b23a714 gen/statements.c --- a/gen/statements.c Thu Oct 04 18:24:05 2007 +0200 +++ b/gen/statements.c Thu Oct 04 22:38:53 2007 +0200 @@ -659,42 +659,55 @@ assert(0); } - if (op == TOKforeach) - { + if (op == TOKforeach) { new llvm::StoreInst(llvm::ConstantInt::get(keytype,0,false), keyvar, p->scopebb()); } - else if (op == TOKforeach_reverse) - { + else if (op == TOKforeach_reverse) { llvm::Value* v = llvm::BinaryOperator::createSub(numiters, llvm::ConstantInt::get(keytype,1,false),"tmp",p->scopebb()); new llvm::StoreInst(v, keyvar, p->scopebb()); } - else - assert(0); delete arr; llvm::BasicBlock* oldend = gIR->scopeend(); + llvm::BasicBlock* nexbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend); llvm::BasicBlock* begbb = new llvm::BasicBlock("foreachbegin", p->topfunc(), oldend); - llvm::BasicBlock* nexbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend); llvm::BasicBlock* endbb = new llvm::BasicBlock("foreachend", p->topfunc(), oldend); new llvm::BranchInst(begbb, p->scopebb()); + // next + p->scope() = IRScope(nexbb,begbb); + llvm::Value* done = 0; + llvm::Value* load = new llvm::LoadInst(keyvar, "tmp", p->scopebb()); + if (op == TOKforeach) { + load = llvm::BinaryOperator::createAdd(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb()); + new llvm::StoreInst(load, keyvar, p->scopebb()); + done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, numiters, "tmp", p->scopebb()); + } + else if (op == TOKforeach_reverse) { + done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, load, llvm::ConstantInt::get(keytype, 0, false), "tmp", p->scopebb()); + load = llvm::BinaryOperator::createSub(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb()); + new llvm::StoreInst(load, keyvar, p->scopebb()); + } + new llvm::BranchInst(begbb, endbb, done, p->scopebb()); + // begin p->scope() = IRScope(begbb,nexbb); - value->llvmValue = LLVM_DtoGEP(val,llvm::ConstantInt::get(keytype,0,false),keyvar,"tmp",p->scopebb()); + // get value for this iteration + value->llvmValue = LLVM_DtoGEP(val,llvm::ConstantInt::get(keytype,0,false),new llvm::LoadInst(keyvar,"tmp",p->scopebb()),"tmp",p->scopebb()); // body + p->scope() = IRScope(p->scopebb(),endbb); + p->loopbbs.push_back(IRScope(nexbb,endbb)); body->toIR(p); + p->loopbbs.pop_back(); - // next - p->scope() = IRScope(nexbb,endbb); - new llvm::BranchInst(endbb, p->scopebb()); + if (!p->scope().returned) + new llvm::BranchInst(nexbb, p->scopebb()); // end - if (!p->scope().returned) - new llvm::BranchInst(endbb, p->scopebb()); p->scope() = IRScope(endbb,oldend); } diff -r a86fe7496b58 -r bc641b23a714 test/foreach1.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/foreach1.d Thu Oct 04 22:38:53 2007 +0200 @@ -0,0 +1,17 @@ +module foreach1; +import std.stdio; + +void main() +{ + static arr = [1,2,3,4,5]; + + writef("forward"); + foreach(v;arr) { + writef(' ',v); + } + writef("\nreverse"); + foreach_reverse(v;arr) { + writef(' ',v); + } + writef("\n"); +}