| ... | ... | @@ -464,6 +464,8 @@ const Writer = struct { |
| 464 | 464 | .switch_block_ref, |
| 465 | 465 | => try self.writeSwitchBlock(stream, inst), |
| 466 | 466 | |
| 467 | .switch_block_err_union => try self.writeSwitchBlockErrUnion(stream, inst), |
| 468 | |
| 467 | 469 | .field_val, |
| 468 | 470 | .field_ptr, |
| 469 | 471 | => try self.writePlNodeField(stream, inst), |
| ... | ... | @@ -2026,6 +2028,132 @@ const Writer = struct { |
| 2026 | 2028 | try self.writeSrc(stream, inst_data.src()); |
| 2027 | 2029 | } |
| 2028 | 2030 | |
| 2031 | fn writeSwitchBlockErrUnion(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { |
| 2032 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2033 | const extra = self.code.extraData(Zir.Inst.SwitchBlockErrUnion, inst_data.payload_index); |
| 2034 | |
| 2035 | var extra_index: usize = extra.end; |
| 2036 | |
| 2037 | const multi_cases_len = if (extra.data.bits.has_multi_cases) blk: { |
| 2038 | const multi_cases_len = self.code.extra[extra_index]; |
| 2039 | extra_index += 1; |
| 2040 | break :blk multi_cases_len; |
| 2041 | } else 0; |
| 2042 | |
| 2043 | try self.writeInstRef(stream, extra.data.operand); |
| 2044 | |
| 2045 | self.indent += 2; |
| 2046 | |
| 2047 | { |
| 2048 | const info = @as(Zir.Inst.SwitchBlock.ProngInfo, @bitCast(self.code.extra[extra_index])); |
| 2049 | extra_index += 1; |
| 2050 | |
| 2051 | assert(!info.is_inline); |
| 2052 | const body = self.code.bodySlice(extra_index, info.body_len); |
| 2053 | extra_index += body.len; |
| 2054 | |
| 2055 | try stream.writeAll(",\n"); |
| 2056 | try stream.writeByteNTimes(' ', self.indent); |
| 2057 | try stream.writeAll("non_err => "); |
| 2058 | try self.writeBracedBody(stream, body); |
| 2059 | } |
| 2060 | |
| 2061 | if (extra.data.bits.has_else) { |
| 2062 | const info = @as(Zir.Inst.SwitchBlock.ProngInfo, @bitCast(self.code.extra[extra_index])); |
| 2063 | extra_index += 1; |
| 2064 | const capture_text = switch (info.capture) { |
| 2065 | .none => "", |
| 2066 | .by_val => "by_val ", |
| 2067 | .by_ref => "by_ref ", |
| 2068 | }; |
| 2069 | const inline_text = if (info.is_inline) "inline " else ""; |
| 2070 | const body = self.code.bodySlice(extra_index, info.body_len); |
| 2071 | extra_index += body.len; |
| 2072 | |
| 2073 | try stream.writeAll(",\n"); |
| 2074 | try stream.writeByteNTimes(' ', self.indent); |
| 2075 | try stream.print("{s}{s}else => ", .{ capture_text, inline_text }); |
| 2076 | try self.writeBracedBody(stream, body); |
| 2077 | } |
| 2078 | |
| 2079 | { |
| 2080 | const scalar_cases_len = extra.data.bits.scalar_cases_len; |
| 2081 | var scalar_i: usize = 0; |
| 2082 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 2083 | const item_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index])); |
| 2084 | extra_index += 1; |
| 2085 | const info = @as(Zir.Inst.SwitchBlock.ProngInfo, @bitCast(self.code.extra[extra_index])); |
| 2086 | extra_index += 1; |
| 2087 | const body = self.code.bodySlice(extra_index, info.body_len); |
| 2088 | extra_index += info.body_len; |
| 2089 | |
| 2090 | try stream.writeAll(",\n"); |
| 2091 | try stream.writeByteNTimes(' ', self.indent); |
| 2092 | switch (info.capture) { |
| 2093 | .none => {}, |
| 2094 | .by_val => try stream.writeAll("by_val "), |
| 2095 | .by_ref => try stream.writeAll("by_ref "), |
| 2096 | } |
| 2097 | if (info.is_inline) try stream.writeAll("inline "); |
| 2098 | try self.writeInstRef(stream, item_ref); |
| 2099 | try stream.writeAll(" => "); |
| 2100 | try self.writeBracedBody(stream, body); |
| 2101 | } |
| 2102 | } |
| 2103 | { |
| 2104 | var multi_i: usize = 0; |
| 2105 | while (multi_i < multi_cases_len) : (multi_i += 1) { |
| 2106 | const items_len = self.code.extra[extra_index]; |
| 2107 | extra_index += 1; |
| 2108 | const ranges_len = self.code.extra[extra_index]; |
| 2109 | extra_index += 1; |
| 2110 | const info = @as(Zir.Inst.SwitchBlock.ProngInfo, @bitCast(self.code.extra[extra_index])); |
| 2111 | extra_index += 1; |
| 2112 | const items = self.code.refSlice(extra_index, items_len); |
| 2113 | extra_index += items_len; |
| 2114 | |
| 2115 | try stream.writeAll(",\n"); |
| 2116 | try stream.writeByteNTimes(' ', self.indent); |
| 2117 | switch (info.capture) { |
| 2118 | .none => {}, |
| 2119 | .by_val => try stream.writeAll("by_val "), |
| 2120 | .by_ref => try stream.writeAll("by_ref "), |
| 2121 | } |
| 2122 | if (info.is_inline) try stream.writeAll("inline "); |
| 2123 | |
| 2124 | for (items, 0..) |item_ref, item_i| { |
| 2125 | if (item_i != 0) try stream.writeAll(", "); |
| 2126 | try self.writeInstRef(stream, item_ref); |
| 2127 | } |
| 2128 | |
| 2129 | var range_i: usize = 0; |
| 2130 | while (range_i < ranges_len) : (range_i += 1) { |
| 2131 | const item_first = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index])); |
| 2132 | extra_index += 1; |
| 2133 | const item_last = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index])); |
| 2134 | extra_index += 1; |
| 2135 | |
| 2136 | if (range_i != 0 or items.len != 0) { |
| 2137 | try stream.writeAll(", "); |
| 2138 | } |
| 2139 | try self.writeInstRef(stream, item_first); |
| 2140 | try stream.writeAll("..."); |
| 2141 | try self.writeInstRef(stream, item_last); |
| 2142 | } |
| 2143 | |
| 2144 | const body = self.code.bodySlice(extra_index, info.body_len); |
| 2145 | extra_index += info.body_len; |
| 2146 | try stream.writeAll(" => "); |
| 2147 | try self.writeBracedBody(stream, body); |
| 2148 | } |
| 2149 | } |
| 2150 | |
| 2151 | self.indent -= 2; |
| 2152 | |
| 2153 | try stream.writeAll(") "); |
| 2154 | try self.writeSrc(stream, inst_data.src()); |
| 2155 | } |
| 2156 | |
| 2029 | 2157 | fn writeSwitchBlock(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { |
| 2030 | 2158 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 2031 | 2159 | const extra = self.code.extraData(Zir.Inst.SwitchBlock, inst_data.payload_index); |