diff --git a/src/codegen.cpp b/src/codegen.cpp index 466afb7..5c48cb7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -596,13 +596,38 @@ namespace AST { builder.builder->SetInsertPoint(after_bb); } - void WhileStatement::codegen(codegen::Builder& builder, codegen::Scope&, codegen::StackAllocator&) { + void WhileStatement::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); + auto function = builder.block->getParent(); + auto cond_bb = llvm::BasicBlock::Create(*builder.context, "while-cond", function); + auto inner_bb = llvm::BasicBlock::Create(*builder.context, "while-inner", function); + auto after_bb = llvm::BasicBlock::Create(*builder.context, "while-after", function); + + builder.builder->CreateBr(cond_bb); + + // While condition + builder.builder->SetInsertPoint(cond_bb); + if (this->m_cond) { + auto cond_value = (*this->m_cond)->codegen(builder, scope, allocator); + builder.builder->CreateCondBr(cond_value.value, inner_bb, after_bb); + } + else { + builder.builder->CreateBr(inner_bb); + } + + // While loop + builder.builder->SetInsertPoint(inner_bb); + builder.block = inner_bb; + this->m_loop->codegen(builder, scope, allocator); + builder.builder->CreateBr(cond_bb); + + // After + builder.builder->SetInsertPoint(after_bb); + builder.block = after_bb; }