Loop return else
This commit is contained in:
parent
a86f990a5f
commit
3ad8cbe3ec
1
TODOLIST
1
TODOLIST
@ -1,4 +1,3 @@
|
|||||||
returns inside loops (if conditional)
|
|
||||||
returns inside loops (else conditional)
|
returns inside loops (else conditional)
|
||||||
returns inside loops (non-conditional)
|
returns inside loops (non-conditional)
|
||||||
function pointers
|
function pointers
|
||||||
|
@ -1349,26 +1349,10 @@ const Parser = struct{
|
|||||||
_ = analyzer.exit_blocks.append(exit_block);
|
_ = analyzer.exit_blocks.append(exit_block);
|
||||||
const exit_block_count = analyzer.exit_blocks.length;
|
const exit_block_count = analyzer.exit_blocks.length;
|
||||||
|
|
||||||
const branch = thread.branches.append(.{
|
const branch_emission = emit_branch(analyzer, thread, compare, taken_block, exit_block);
|
||||||
.instruction = .{
|
_ = branch_emission; // autofix
|
||||||
.value = .{
|
|
||||||
.sema = .{
|
|
||||||
.thread = thread.get_index(),
|
|
||||||
.resolved = true,
|
|
||||||
.id = .instruction,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.id = .branch,
|
|
||||||
},
|
|
||||||
.condition = compare,
|
|
||||||
.taken = taken_block,
|
|
||||||
.not_taken = exit_block,
|
|
||||||
});
|
|
||||||
_ = analyzer.current_basic_block.instructions.append(&branch.instruction);
|
|
||||||
analyzer.current_basic_block.is_terminated = true;
|
|
||||||
|
|
||||||
analyzer.current_basic_block = branch.taken;
|
analyzer.current_basic_block = taken_block;
|
||||||
_ = branch.taken.predecessors.append(original_block);
|
|
||||||
|
|
||||||
var if_terminated = false;
|
var if_terminated = false;
|
||||||
var else_terminated = false;
|
var else_terminated = false;
|
||||||
@ -1390,7 +1374,7 @@ const Parser = struct{
|
|||||||
if (src[parser.i] == 'e' and byte_equal(src[parser.i..][0.."else".len], "else")) {
|
if (src[parser.i] == 'e' and byte_equal(src[parser.i..][0.."else".len], "else")) {
|
||||||
// TODO: create not taken block
|
// TODO: create not taken block
|
||||||
parser.i += "else".len;
|
parser.i += "else".len;
|
||||||
analyzer.current_basic_block = branch.not_taken;
|
analyzer.current_basic_block = exit_block;
|
||||||
|
|
||||||
parser.skip_space(src);
|
parser.skip_space(src);
|
||||||
|
|
||||||
@ -1410,24 +1394,29 @@ const Parser = struct{
|
|||||||
else => @panic((src.ptr + parser.i)[0..1]),
|
else => @panic((src.ptr + parser.i)[0..1]),
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!if_terminated and !else_terminated) {
|
if (!if_terminated or !else_terminated) {
|
||||||
const new_exit_block = create_basic_block(thread);
|
const new_exit_block = create_basic_block(thread);
|
||||||
|
const not_taken_block = exit_block;
|
||||||
// Fix jump
|
// Fix jump
|
||||||
|
|
||||||
assert(if_jump_emission.jump.basic_block == branch.not_taken);
|
if (!if_terminated) {
|
||||||
|
assert(if_jump_emission.jump.basic_block == not_taken_block);
|
||||||
if_jump_emission.jump.basic_block.predecessors.length = 0;
|
if_jump_emission.jump.basic_block.predecessors.length = 0;
|
||||||
_ = if_jump_emission.jump.basic_block.predecessors.append(original_block);
|
_ = if_jump_emission.jump.basic_block.predecessors.append(original_block);
|
||||||
_ = new_exit_block.predecessors.append(if_jump_emission.jump.basic_block);
|
_ = new_exit_block.predecessors.append(if_jump_emission.jump.basic_block);
|
||||||
if_jump_emission.jump.basic_block = new_exit_block;
|
if_jump_emission.jump.basic_block = new_exit_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!else_terminated) {
|
||||||
// Emit jump to the new exit block
|
// Emit jump to the new exit block
|
||||||
_ = emit_jump(analyzer, thread, new_exit_block);
|
_ = emit_jump(analyzer, thread, new_exit_block);
|
||||||
|
}
|
||||||
|
|
||||||
analyzer.current_basic_block = new_exit_block;
|
analyzer.current_basic_block = new_exit_block;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_ = branch.not_taken.predecessors.append(original_block);
|
_ = exit_block.predecessors.append(original_block);
|
||||||
analyzer.current_basic_block = branch.not_taken;
|
analyzer.current_basic_block = exit_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!if_terminated and !else_terminated) {
|
if (!if_terminated and !else_terminated) {
|
||||||
@ -6084,3 +6073,5 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, return_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
21
retest/standalone/loop_return_else/main.nat
Normal file
21
retest/standalone/loop_return_else/main.nat
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
>n: s32 = 10;
|
||||||
|
>m: s32 = 3;
|
||||||
|
|
||||||
|
fn foo(arg: s32) s32 {
|
||||||
|
>i: s32 = 0;
|
||||||
|
loop (i < arg) {
|
||||||
|
if (i < m) {
|
||||||
|
i += 1;
|
||||||
|
} else {
|
||||||
|
return i - 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 321;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn[cc(.c)] main[export]() s32 {
|
||||||
|
>a = foo(n);
|
||||||
|
>b = foo(n);
|
||||||
|
return (a - b) + (a + 97) + (b + 97);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user