zig reduce proof of concept
This commit is contained in:
@@ -3,20 +3,38 @@ const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const usage =
|
||||
\\zig reduce [source_file] [transformation]
|
||||
\\zig reduce [source_file] [interestingness]
|
||||
\\
|
||||
;
|
||||
|
||||
const Interestingness = enum { interesting, boring, unknown };
|
||||
|
||||
// Roadmap:
|
||||
// - add the main loop that checks for interestingness
|
||||
// - add transformations
|
||||
// - add thread pool
|
||||
// - add support for `@import` detection and other files
|
||||
// - more fancy transformations
|
||||
// - reduce flags sent to the compiler
|
||||
// - @import inlining
|
||||
// - deleting unused functions and other globals
|
||||
// - removing statements or blocks of code
|
||||
// - replacing operands of `and` and `or` with `true` and `false`
|
||||
// - replacing if conditions with `true` and `false`
|
||||
// - integrate the build system?
|
||||
|
||||
pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||
const file_path = args[2];
|
||||
const transformation_index = try std.fmt.parseInt(u32, args[3], 0);
|
||||
const interestingness_argv_template = args[3..];
|
||||
|
||||
var interestingness_argv: std.ArrayListUnmanaged([]const u8) = .{};
|
||||
try interestingness_argv.ensureUnusedCapacity(arena, interestingness_argv_template.len + 1);
|
||||
interestingness_argv.appendSliceAssumeCapacity(interestingness_argv_template);
|
||||
interestingness_argv.appendAssumeCapacity(file_path);
|
||||
|
||||
var rendered = std.ArrayList(u8).init(gpa);
|
||||
defer rendered.deinit();
|
||||
|
||||
var prev_rendered = std.ArrayList(u8).init(gpa);
|
||||
defer prev_rendered.deinit();
|
||||
|
||||
const source_code = try std.fs.cwd().readFileAllocOptions(
|
||||
arena,
|
||||
@@ -33,19 +51,56 @@ pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||
if (tree.errors.len != 0) {
|
||||
@panic("syntax errors occurred");
|
||||
}
|
||||
var rendered = std.ArrayList(u8).init(gpa);
|
||||
defer rendered.deinit();
|
||||
rendered.clearRetainingCapacity();
|
||||
|
||||
var gut_functions: std.AutoHashMapUnmanaged(u32, void) = .{};
|
||||
try gut_functions.put(arena, transformation_index, {});
|
||||
var next_gut_fn_index: u32 = 0;
|
||||
var fixups: std.zig.Ast.Fixups = .{};
|
||||
|
||||
try tree.renderToArrayList(&rendered, .{
|
||||
.gut_functions = gut_functions,
|
||||
});
|
||||
while (true) {
|
||||
try fixups.gut_functions.put(arena, next_gut_fn_index, {});
|
||||
|
||||
const stdout = std.io.getStdOut();
|
||||
try stdout.writeAll(rendered.items);
|
||||
rendered.clearRetainingCapacity();
|
||||
try tree.renderToArrayList(&rendered, fixups);
|
||||
|
||||
if (std.mem.eql(u8, rendered.items, prev_rendered.items)) {
|
||||
std.debug.print("no remaining transformations\n", .{});
|
||||
break;
|
||||
}
|
||||
prev_rendered.clearRetainingCapacity();
|
||||
try prev_rendered.appendSlice(rendered.items);
|
||||
|
||||
try std.fs.cwd().writeFile(file_path, rendered.items);
|
||||
|
||||
const result = try std.process.Child.run(.{
|
||||
.allocator = arena,
|
||||
.argv = interestingness_argv.items,
|
||||
});
|
||||
if (result.stderr.len != 0)
|
||||
std.debug.print("{s}", .{result.stderr});
|
||||
const interestingness: Interestingness = switch (result.term) {
|
||||
.Exited => |code| switch (code) {
|
||||
0 => .interesting,
|
||||
1 => .unknown,
|
||||
else => .boring,
|
||||
},
|
||||
else => b: {
|
||||
std.debug.print("interestingness check aborted unexpectedly\n", .{});
|
||||
break :b .boring;
|
||||
},
|
||||
};
|
||||
std.debug.print("{s}\n", .{@tagName(interestingness)});
|
||||
switch (interestingness) {
|
||||
.interesting => {
|
||||
next_gut_fn_index += 1;
|
||||
},
|
||||
.unknown, .boring => {
|
||||
// revert the change and try the next transformation
|
||||
assert(fixups.gut_functions.remove(next_gut_fn_index));
|
||||
next_gut_fn_index += 1;
|
||||
|
||||
rendered.clearRetainingCapacity();
|
||||
try tree.renderToArrayList(&rendered, fixups);
|
||||
},
|
||||
}
|
||||
}
|
||||
return std.process.cleanExit();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user