| ... | ... | @@ -5,6 +5,8 @@ const assert = std.debug.assert; |
| 5 | 5 | const fatal = @import("./main.zig").fatal; |
| 6 | 6 | const Ast = std.zig.Ast; |
| 7 | 7 | const Walk = @import("reduce/Walk.zig"); |
| 8 | const AstGen = @import("AstGen.zig"); |
| 9 | const Zir = @import("Zir.zig"); |
| 8 | 10 | |
| 9 | 11 | const usage = |
| 10 | 12 | \\zig reduce [options] ./checker root_source_file.zig [-- [argv]] |
| ... | ... | @@ -39,8 +41,6 @@ const Interestingness = enum { interesting, unknown, boring }; |
| 39 | 41 | // - add support for parsing the module flags |
| 40 | 42 | // - more fancy transformations |
| 41 | 43 | // - @import inlining of modules |
| 42 | | // - @import inlining of files |
| 43 | | // - deleting unused functions and other globals |
| 44 | 44 | // - removing statements or blocks of code |
| 45 | 45 | // - replacing operands of `and` and `or` with `true` and `false` |
| 46 | 46 | // - replacing if conditions with `true` and `false` |
| ... | ... | @@ -109,6 +109,9 @@ pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 109 | 109 | var rendered = std.ArrayList(u8).init(gpa); |
| 110 | 110 | defer rendered.deinit(); |
| 111 | 111 | |
| 112 | var astgen_input = std.ArrayList(u8).init(gpa); |
| 113 | defer astgen_input.deinit(); |
| 114 | |
| 112 | 115 | var tree = try parse(gpa, root_source_file_path); |
| 113 | 116 | defer { |
| 114 | 117 | gpa.free(tree.source); |
| ... | ... | @@ -129,6 +132,10 @@ pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 129 | 132 | |
| 130 | 133 | var fixups: Ast.Fixups = .{}; |
| 131 | 134 | defer fixups.deinit(gpa); |
| 135 | |
| 136 | var more_fixups: Ast.Fixups = .{}; |
| 137 | defer more_fixups.deinit(gpa); |
| 138 | |
| 132 | 139 | var rng = std.rand.DefaultPrng.init(seed); |
| 133 | 140 | |
| 134 | 141 | // 1. Walk the AST of the source file looking for independent |
| ... | ... | @@ -171,8 +178,51 @@ pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 171 | 178 | |
| 172 | 179 | rendered.clearRetainingCapacity(); |
| 173 | 180 | try tree.renderToArrayList(&rendered, fixups); |
| 174 | | try std.fs.cwd().writeFile(root_source_file_path, rendered.items); |
| 175 | 181 | |
| 182 | // The transformations we applied may have resulted in unused locals, |
| 183 | // in which case we would like to add the respective discards. |
| 184 | { |
| 185 | try astgen_input.resize(rendered.items.len); |
| 186 | @memcpy(astgen_input.items, rendered.items); |
| 187 | try astgen_input.append(0); |
| 188 | const source_with_null = astgen_input.items[0 .. astgen_input.items.len - 1 :0]; |
| 189 | var astgen_tree = try Ast.parse(gpa, source_with_null, .zig); |
| 190 | defer astgen_tree.deinit(gpa); |
| 191 | if (astgen_tree.errors.len != 0) { |
| 192 | @panic("syntax errors occurred"); |
| 193 | } |
| 194 | var zir = try AstGen.generate(gpa, astgen_tree); |
| 195 | defer zir.deinit(gpa); |
| 196 | |
| 197 | if (zir.hasCompileErrors()) { |
| 198 | more_fixups.clearRetainingCapacity(); |
| 199 | const payload_index = zir.extra[@intFromEnum(Zir.ExtraIndex.compile_errors)]; |
| 200 | assert(payload_index != 0); |
| 201 | const header = zir.extraData(Zir.Inst.CompileErrors, payload_index); |
| 202 | var extra_index = header.end; |
| 203 | for (0..header.data.items_len) |_| { |
| 204 | const item = zir.extraData(Zir.Inst.CompileErrors.Item, extra_index); |
| 205 | extra_index = item.end; |
| 206 | const msg = zir.nullTerminatedString(item.data.msg); |
| 207 | if (mem.eql(u8, msg, "unused local constant") or |
| 208 | mem.eql(u8, msg, "unused local variable") or |
| 209 | mem.eql(u8, msg, "unused function parameter") or |
| 210 | mem.eql(u8, msg, "unused capture")) |
| 211 | { |
| 212 | const ident_token = item.data.token; |
| 213 | try more_fixups.unused_var_decls.put(gpa, ident_token, {}); |
| 214 | } else { |
| 215 | std.debug.print("found other ZIR error: '{s}'\n", .{msg}); |
| 216 | } |
| 217 | } |
| 218 | if (more_fixups.count() != 0) { |
| 219 | rendered.clearRetainingCapacity(); |
| 220 | try astgen_tree.renderToArrayList(&rendered, more_fixups); |
| 221 | } |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | try std.fs.cwd().writeFile(root_source_file_path, rendered.items); |
| 176 | 226 | //std.debug.print("trying this code:\n{s}\n", .{rendered.items}); |
| 177 | 227 | |
| 178 | 228 | const interestingness = try runCheck(arena, interestingness_argv.items); |