Merge pull request #152 from birth-software/block-termination

Improve handling of block termination in switches
This commit is contained in:
David 2024-04-18 13:25:43 -06:00 committed by GitHub
commit 428fe7207b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 61 additions and 23 deletions

View File

@ -14427,6 +14427,7 @@ pub const Builder = struct {
};
const before_switch_bb = builder.current_basic_block;
const switch_exit_block = try builder.newBasicBlock(unit, context);
for (case_nodes) |case_node_index| {
builder.current_basic_block = before_switch_bb;
@ -14500,6 +14501,17 @@ pub const Builder = struct {
try phi_instruction.addIncoming(context, v, case_block);
try builder.jump(unit, context, phi.block);
}
} else if (builder.current_basic_block != .null) {
const current_block = unit.basic_blocks.get(builder.current_basic_block);
const v_ty = unit.types.get(v.type);
switch (v_ty.*) {
.void => {
assert(!current_block.terminated);
try builder.jump(unit, context, switch_exit_block);
},
.noreturn => {},
else => |t| @panic(@tagName(t)),
}
}
if (conditions.length > 0) {
@ -14538,12 +14550,38 @@ pub const Builder = struct {
}
}
return V{
.value = .{
.@"comptime" = .void,
},
.type = .void,
};
if (builder.current_basic_block != .null) {
const current_block = unit.basic_blocks.get(builder.current_basic_block);
assert(current_block.terminated);
const sw_exit_block = unit.basic_blocks.get(switch_exit_block);
assert(current_block.terminated);
if (sw_exit_block.predecessors.length > 0) {
builder.current_basic_block = switch_exit_block;
switch (type_expect) {
.type => |ti| switch (ti) {
.void => return V{
.value = .{
.@"comptime" = .void,
},
.type = .void,
},
else => unreachable,
},
else => |t| @panic(@tagName(t)),
}
} else {
return V{
.value = .{
.@"comptime" = .@"unreachable",
},
.type = .noreturn,
};
}
} else {
unreachable;
}
},
else => |t| @panic(@tagName(t)),
}

View File

@ -39,25 +39,25 @@ const lex = fn (arena: &Arena, bytes: []const u8) *!void {
index = 0;
//while (index < length) {
// const start_index = index;
// const start_character = bytes[index];
while (index < length) {
const start_index = index;
const start_character = bytes[index];
// switch (start_character) {
// 'a'...'z', 'A'...'Z', '_' => {
// while (true) {
// const ch = bytes[index];
// if ((ch >= 'a' and ch <= 'z') or (ch >= 'A' and ch <= 'Z') or ch == '_' or (ch >= '0' and ch <= '9')) {
// index += 1;
// continue;
// }
switch (start_character) {
'a'...'z', 'A'...'Z', '_' => {
while (true) {
const ch = bytes[index];
if ((ch >= 'a' and ch <= 'z') or (ch >= 'A' and ch <= 'Z') or ch == '_' or (ch >= '0' and ch <= '9')) {
index += 1;
continue;
}
// break;
// }
// },
// else => unreachable,
// }
//}
break;
}
},
else => index += 1,
}
}
}
const get_argument = fn (real_argument: []const u8, wanted_argument: []const u8, command_arguments: []const [&:0]const u8, i_ptr: &usize) ?[]const u8 {