From 66f9dac5a68bd05c38744398c932dbcebbf7dde3 Mon Sep 17 00:00:00 2001 From: Sofia Date: Fri, 10 Apr 2026 18:09:55 +0300 Subject: [PATCH] Codegen if-statements --- src/ast.cpp | 9 +++++---- src/codegen.cpp | 43 +++++++++++++++++++++++++++++++++++++++++-- src/main.cpp | 12 +++++++++--- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/ast.cpp b/src/ast.cpp index 2a3e88e..5cd00a3 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -29,11 +29,12 @@ namespace AST { } std::string IfStatement::formatted() { - std::stringstream out{ "if " }; - out << this->m_condition->formatted(); - out << "\n then " << this->m_then->formatted(); + std::stringstream out{ "" }; + out << "if "; + out << "(" << this->m_condition->formatted() << ")"; + out << "\n then " << this->m_then->formatted(); if (this->m_else.has_value()) - out << "\n else " << (*this->m_else)->formatted(); + out << "\n else " << (*this->m_else)->formatted(); return out.str(); } diff --git a/src/codegen.cpp b/src/codegen.cpp index 6af695c..2ed29ee 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -39,7 +39,7 @@ namespace AST { } } else { - throw new std::runtime_error("Value " + this->m_name + " not found"); + throw std::runtime_error("Value " + this->m_name + " not found"); } } @@ -114,7 +114,35 @@ namespace AST { if (!builder.block) return; - // TODO + builder.builder->SetInsertPoint(builder.block); + + auto condition = this->m_condition->codegen(builder, scope); + + auto function = builder.block->getParent(); + auto then_block = llvm::BasicBlock::Create(*builder.context, "then", function); + + std::optional else_block{}; + if (this->m_else.has_value()) + else_block = llvm::BasicBlock::Create(*builder.context, "else", function); + + auto after_block = llvm::BasicBlock::Create(*builder.context, "after", function); + + builder.builder->CreateCondBr(condition.value, then_block, else_block.value_or(after_block)); + + builder.block = then_block; + builder.builder->SetInsertPoint(then_block); + this->m_then->codegen(builder, scope); + builder.builder->CreateBr(after_block); + + if (else_block.has_value()) { + builder.block = *else_block; + builder.builder->SetInsertPoint(*else_block); + this->m_else->get()->codegen(builder, scope); + builder.builder->CreateBr(after_block); + } + + builder.block = after_block; + builder.builder->SetInsertPoint(after_block); } @@ -123,6 +151,7 @@ namespace AST { auto ret_ty = this->m_return_ty->codegen(builder); std::vector params{}; + for (auto& param : this->m_params) { params.push_back(param.second->codegen(builder)); } @@ -138,6 +167,16 @@ namespace AST { auto BB = llvm::BasicBlock::Create(*builder.context, "entry", function, nullptr); builder.block = BB; + int counter = 0; + for (auto& param : this->m_params) { + auto arg = function->getArg(counter++); + arg->setName(param.first); + inner_scope.values[param.first] = codegen::StackValue{ + arg, + std::move(param.second), + }; + } + for (auto& statement : this->m_statements) { statement->codegen(builder, inner_scope); } diff --git a/src/main.cpp b/src/main.cpp index 93bf301..3571a97 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -79,9 +79,15 @@ int main() { codegen::Scope scope{}; - for (auto& tls : statements) { - std::cout << tls->formatted() << std::endl; - tls->codegen(builder, scope); + try { + for (auto& tls : statements) { + std::cout << tls->formatted() << std::endl; + tls->codegen(builder, scope); + } + } + catch (std::runtime_error error) { + std::cerr << "FATAL: " << error.what() << std::endl; + return 1; } llvm::InitializeAllTargetInfos();