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