mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 08:33:06 +00:00
stage2: switch: fix Sema bugs and implement AIR printing
This commit is contained in:
parent
495e60d641
commit
a97e5e119a
@ -442,9 +442,9 @@ fn analyzeInst(
|
||||
return trackOperands(a, new_set, inst, main_tomb, .{ condition, .none, .none });
|
||||
},
|
||||
.switch_br => {
|
||||
const inst_data = inst_datas[inst].pl_op;
|
||||
const condition = inst_data.operand;
|
||||
const switch_br = a.air.extraData(Air.SwitchBr, inst_data.payload);
|
||||
const pl_op = inst_datas[inst].pl_op;
|
||||
const condition = pl_op.operand;
|
||||
const switch_br = a.air.extraData(Air.SwitchBr, pl_op.payload);
|
||||
|
||||
const Table = std.AutoHashMapUnmanaged(Air.Inst.Index, void);
|
||||
const case_tables = try gpa.alloc(Table, switch_br.data.cases_len + 1); // +1 for else
|
||||
@ -456,8 +456,8 @@ fn analyzeInst(
|
||||
var air_extra_index: usize = switch_br.end;
|
||||
for (case_tables[0..switch_br.data.cases_len]) |*case_table| {
|
||||
const case = a.air.extraData(Air.SwitchBr.Case, air_extra_index);
|
||||
const case_body = a.air.extra[case.end..][0..case.data.body_len];
|
||||
air_extra_index = case.end + case_body.len;
|
||||
const case_body = a.air.extra[case.end + case.data.items_len ..][0..case.data.body_len];
|
||||
air_extra_index = case.end + case.data.items_len + case_body.len;
|
||||
try analyzeWithContext(a, case_table, case_body);
|
||||
|
||||
// Reset the table back to its state from before the case.
|
||||
|
@ -4213,6 +4213,7 @@ fn analyzeSwitch(
|
||||
var prev_then_body: []const Air.Inst.Index = &.{};
|
||||
defer gpa.free(prev_then_body);
|
||||
|
||||
var cases_len = scalar_cases_len;
|
||||
var multi_i: usize = 0;
|
||||
while (multi_i < multi_cases_len) : (multi_i += 1) {
|
||||
const items_len = sema.code.extra[extra_index];
|
||||
@ -4232,6 +4233,8 @@ fn analyzeSwitch(
|
||||
// else prong. Otherwise, we can take advantage of multiple items
|
||||
// mapping to the same body.
|
||||
if (ranges_len == 0) {
|
||||
cases_len += 1;
|
||||
|
||||
const body = sema.code.extra[extra_index..][0..body_len];
|
||||
extra_index += body_len;
|
||||
_ = try sema.analyzeBody(&case_block, body);
|
||||
@ -4239,7 +4242,7 @@ fn analyzeSwitch(
|
||||
try cases_extra.ensureUnusedCapacity(gpa, 2 + items.len +
|
||||
case_block.instructions.items.len);
|
||||
|
||||
cases_extra.appendAssumeCapacity(1); // items_len
|
||||
cases_extra.appendAssumeCapacity(@intCast(u32, items.len));
|
||||
cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len));
|
||||
|
||||
for (items) |item_ref| {
|
||||
@ -4352,12 +4355,12 @@ fn analyzeSwitch(
|
||||
}
|
||||
|
||||
try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr).Struct.fields.len +
|
||||
cases_extra.items.len);
|
||||
cases_extra.items.len + final_else_body.len);
|
||||
|
||||
_ = try child_block.addInst(.{ .tag = .switch_br, .data = .{ .pl_op = .{
|
||||
.operand = operand,
|
||||
.payload = sema.addExtraAssumeCapacity(Air.SwitchBr{
|
||||
.cases_len = @intCast(u32, scalar_cases_len + multi_cases_len),
|
||||
.cases_len = @intCast(u32, cases_len),
|
||||
.else_body_len = @intCast(u32, final_else_body.len),
|
||||
}),
|
||||
} } });
|
||||
|
@ -300,33 +300,44 @@ const Writer = struct {
|
||||
|
||||
fn writeSwitchBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
|
||||
const extra = w.air.extraData(Air.SwitchBr, pl_op.payload);
|
||||
const cases = w.air.extra[extra.end..][0..extra.data.cases_len];
|
||||
const else_body = w.air.extra[extra.end + cases.len ..][0..extra.data.else_body_len];
|
||||
const switch_br = w.air.extraData(Air.SwitchBr, pl_op.payload);
|
||||
var extra_index: usize = switch_br.end;
|
||||
var case_i: u32 = 0;
|
||||
|
||||
try w.writeInstRef(s, pl_op.operand);
|
||||
try s.writeAll(", {\n");
|
||||
|
||||
const old_indent = w.indent;
|
||||
if (else_body.len != 0) {
|
||||
w.indent += 2;
|
||||
try w.writeBody(s, else_body);
|
||||
try s.writeByteNTimes(' ', old_indent);
|
||||
try s.writeAll("}, {\n");
|
||||
w.indent = old_indent;
|
||||
}
|
||||
w.indent += 2;
|
||||
|
||||
for (cases) |case_index| {
|
||||
const case = w.air.extraData(Air.SwitchBr.Case, case_index);
|
||||
const case_body = w.air.extra[case.end..][0..case.data.body_len];
|
||||
while (case_i < switch_br.data.cases_len) : (case_i += 1) {
|
||||
const case = w.air.extraData(Air.SwitchBr.Case, extra_index);
|
||||
const items = @bitCast([]const Air.Inst.Ref, w.air.extra[case.end..][0..case.data.items_len]);
|
||||
const case_body = w.air.extra[case.end + items.len ..][0..case.data.body_len];
|
||||
extra_index = case.end + case.data.items_len + case_body.len;
|
||||
|
||||
try s.writeAll(", [");
|
||||
for (items) |item, item_i| {
|
||||
if (item_i != 0) try s.writeAll(", ");
|
||||
try w.writeInstRef(s, item);
|
||||
}
|
||||
try s.writeAll("] => {\n");
|
||||
w.indent += 2;
|
||||
try w.writeBody(s, case_body);
|
||||
try s.writeByteNTimes(' ', old_indent);
|
||||
try s.writeAll("}, {\n");
|
||||
w.indent = old_indent;
|
||||
w.indent -= 2;
|
||||
try s.writeByteNTimes(' ', w.indent);
|
||||
try s.writeAll("}");
|
||||
}
|
||||
|
||||
const else_body = w.air.extra[extra_index..][0..switch_br.data.else_body_len];
|
||||
if (else_body.len != 0) {
|
||||
try s.writeAll(", else => {\n");
|
||||
w.indent += 2;
|
||||
try w.writeBody(s, else_body);
|
||||
w.indent -= 2;
|
||||
try s.writeByteNTimes(' ', w.indent);
|
||||
try s.writeAll("}");
|
||||
}
|
||||
|
||||
try s.writeAll("\n");
|
||||
try s.writeByteNTimes(' ', old_indent);
|
||||
try s.writeAll("}");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user