Codegen if-statements

This commit is contained in:
Sofia 2026-04-10 18:09:55 +03:00
parent 97745ffbb0
commit 66f9dac5a6
3 changed files with 55 additions and 9 deletions

View File

@ -29,11 +29,12 @@ namespace AST {
} }
std::string IfStatement::formatted() { std::string IfStatement::formatted() {
std::stringstream out{ "if " }; std::stringstream out{ "" };
out << this->m_condition->formatted(); out << "if ";
out << "\n then " << this->m_then->formatted(); out << "(" << this->m_condition->formatted() << ")";
out << "\n then " << this->m_then->formatted();
if (this->m_else.has_value()) if (this->m_else.has_value())
out << "\n else " << (*this->m_else)->formatted(); out << "\n else " << (*this->m_else)->formatted();
return out.str(); return out.str();
} }

View File

@ -39,7 +39,7 @@ namespace AST {
} }
} }
else { 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) if (!builder.block)
return; 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<llvm::BasicBlock*> 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); auto ret_ty = this->m_return_ty->codegen(builder);
std::vector<llvm::Type*> params{}; std::vector<llvm::Type*> params{};
for (auto& param : this->m_params) { for (auto& param : this->m_params) {
params.push_back(param.second->codegen(builder)); params.push_back(param.second->codegen(builder));
} }
@ -138,6 +167,16 @@ namespace AST {
auto BB = llvm::BasicBlock::Create(*builder.context, "entry", function, nullptr); auto BB = llvm::BasicBlock::Create(*builder.context, "entry", function, nullptr);
builder.block = BB; 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) { for (auto& statement : this->m_statements) {
statement->codegen(builder, inner_scope); statement->codegen(builder, inner_scope);
} }

View File

@ -79,9 +79,15 @@ int main() {
codegen::Scope scope{}; codegen::Scope scope{};
for (auto& tls : statements) { try {
std::cout << tls->formatted() << std::endl; for (auto& tls : statements) {
tls->codegen(builder, scope); 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(); llvm::InitializeAllTargetInfos();