Add broken continue functionality
This commit is contained in:
parent
ddea133138
commit
6ca1641705
@ -11,7 +11,16 @@
|
||||
|
||||
namespace codegen {
|
||||
Scope Scope::with_lvalue() {
|
||||
return Scope{ this->binops, this->unops, this->casts, this->structs, this->values, true };
|
||||
return Scope{
|
||||
.binops = this->binops,
|
||||
.unops = this->unops,
|
||||
.casts = this->casts,
|
||||
.structs = this->structs,
|
||||
.values = this->values,
|
||||
.is_lvalue = true,
|
||||
.continue_bb = this->continue_bb,
|
||||
.break_bb = this->break_bb,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -570,14 +579,19 @@ namespace AST {
|
||||
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);
|
||||
auto done_bb = llvm::BasicBlock::Create(*builder.context, "for-done", function);
|
||||
|
||||
builder.builder->CreateBr(cond_bb);
|
||||
|
||||
codegen::Scope inner_scope{ scope };
|
||||
inner_scope.continue_bb = after_bb;
|
||||
inner_scope.break_bb = done_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);
|
||||
auto cond_res = (*this->m_cond)->codegen(builder, inner_scope, allocator);
|
||||
builder.builder->CreateCondBr(cond_res.value, inner_bb, done_bb);
|
||||
}
|
||||
else {
|
||||
builder.builder->CreateBr(inner_bb);
|
||||
@ -586,14 +600,19 @@ namespace AST {
|
||||
// Loop inner block
|
||||
builder.block = inner_bb;
|
||||
builder.builder->SetInsertPoint(inner_bb);
|
||||
this->m_loop->codegen(builder, scope, allocator);
|
||||
this->m_loop->codegen(builder, inner_scope, allocator);
|
||||
builder.builder->CreateBr(after_bb);
|
||||
|
||||
// Loop after-part
|
||||
builder.block = after_bb;
|
||||
builder.builder->SetInsertPoint(after_bb);
|
||||
if (this->m_after)
|
||||
(*this->m_after)->codegen(builder, scope, allocator);
|
||||
(*this->m_after)->codegen(builder, inner_scope, allocator);
|
||||
builder.builder->CreateBr(cond_bb);
|
||||
|
||||
// Loop after
|
||||
builder.block = after_bb;
|
||||
builder.builder->SetInsertPoint(after_bb);
|
||||
builder.block = done_bb;
|
||||
builder.builder->SetInsertPoint(done_bb);
|
||||
}
|
||||
|
||||
void WhileStatement::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
|
||||
@ -641,22 +660,24 @@ namespace AST {
|
||||
statement->codegen(builder, inner, allocator);
|
||||
}
|
||||
|
||||
void BreakStatement::codegen(codegen::Builder& builder, codegen::Scope&, codegen::StackAllocator&) {
|
||||
void BreakStatement::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator&) {
|
||||
if (!builder.block)
|
||||
return;
|
||||
|
||||
builder.builder->SetInsertPoint(builder.block);
|
||||
|
||||
throw CompileError("TODO", this->m_meta);
|
||||
if (scope.break_bb == nullptr)
|
||||
throw CompileError("No break_bb!", this->m_meta);
|
||||
builder.builder->CreateBr(scope.break_bb);
|
||||
}
|
||||
|
||||
void ContinueStatement::codegen(codegen::Builder& builder, codegen::Scope&, codegen::StackAllocator&) {
|
||||
void ContinueStatement::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator&) {
|
||||
if (!builder.block)
|
||||
return;
|
||||
|
||||
builder.builder->SetInsertPoint(builder.block);
|
||||
|
||||
throw CompileError("TODO", this->m_meta);
|
||||
if (scope.continue_bb == nullptr)
|
||||
throw CompileError("No continue_bb!", this->m_meta);
|
||||
builder.builder->CreateBr(scope.continue_bb);
|
||||
}
|
||||
|
||||
void Function::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||
|
||||
@ -28,6 +28,9 @@ namespace codegen {
|
||||
|
||||
bool is_lvalue;
|
||||
|
||||
llvm::BasicBlock* continue_bb;
|
||||
llvm::BasicBlock* break_bb;
|
||||
|
||||
Scope with_lvalue();
|
||||
};
|
||||
}
|
||||
|
||||
@ -140,6 +140,8 @@ std::optional<CompileOutput> compile(std::string_view in_filename) {
|
||||
.structs = {},
|
||||
.values = {},
|
||||
.is_lvalue = false,
|
||||
.continue_bb = nullptr,
|
||||
.break_bb = nullptr,
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
15
test.c
15
test.c
@ -63,16 +63,13 @@ int main() {
|
||||
printf("for-counter: %d\n", counter);
|
||||
}
|
||||
|
||||
continue;
|
||||
break;
|
||||
|
||||
// Test while-loops
|
||||
int counter = 0;
|
||||
while (1) {
|
||||
if (counter > 10)
|
||||
break;
|
||||
printf("while-counter: %d\n", counter++);
|
||||
}
|
||||
// int counter = 0;
|
||||
// while (1) {
|
||||
// if (counter > 10)
|
||||
// break;
|
||||
// printf("while-counter: %d\n", counter++);
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user