From b4dbf18d4a1d0cf2e3d32c232c8c408a660bbb96 Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Thu, 18 Apr 2024 13:25:03 -0600 Subject: [PATCH] Improve handling of block termination in switches --- bootstrap/Compilation.zig | 50 ++++++++++++++++++++++++++++++++++----- src/main.nat | 34 +++++++++++++------------- 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/bootstrap/Compilation.zig b/bootstrap/Compilation.zig index b381599..89d2fa2 100644 --- a/bootstrap/Compilation.zig +++ b/bootstrap/Compilation.zig @@ -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)), } diff --git a/src/main.nat b/src/main.nat index 03a4ad0..65ecc93 100644 --- a/src/main.nat +++ b/src/main.nat @@ -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 {