diff --git a/src/ast.cpp b/src/ast.cpp index bdfa083..f2483a3 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -139,7 +139,7 @@ namespace AST { std::string ForStatement::formatted() { std::stringstream out{ "" }; - out << "("; + out << "for ("; if (this->m_init) out << (*this->m_init)->formatted(); out << ";"; diff --git a/src/codegen.cpp b/src/codegen.cpp index 10b348e..ab3ccec 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -557,13 +557,43 @@ namespace AST { builder.builder->SetInsertPoint(after_block); } - void ForStatement::codegen(codegen::Builder& builder, codegen::Scope&, codegen::StackAllocator&) { + void ForStatement::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) { if (!builder.block) return; builder.builder->SetInsertPoint(builder.block); - throw CompileError("TODO", this->m_meta); + if (this->m_init) + (*this->m_init)->codegen(builder, scope, allocator); + + auto function = builder.block->getParent(); + auto cond_bb = llvm::BasicBlock::Create(*builder.context, "for-cond", function); + auto inner_bb = llvm::BasicBlock::Create(*builder.context, "for-inner", function); + auto after_bb = llvm::BasicBlock::Create(*builder.context, "for-after", function); + + builder.builder->CreateBr(cond_bb); + + // Loop conditional + builder.builder->SetInsertPoint(cond_bb); + if (this->m_cond) { + auto cond_res = (*this->m_cond)->codegen(builder, scope, allocator); + builder.builder->CreateCondBr(cond_res.value, inner_bb, after_bb); + } + else { + builder.builder->CreateBr(inner_bb); + } + + // Loop inner block + builder.block = inner_bb; + builder.builder->SetInsertPoint(inner_bb); + this->m_loop->codegen(builder, scope, allocator); + if (this->m_after) + (*this->m_after)->codegen(builder, scope, allocator); + builder.builder->CreateBr(cond_bb); + + // Loop after + builder.block = after_bb; + builder.builder->SetInsertPoint(after_bb); }