diff options
| -rw-r--r-- | Variables.zig | 39 | ||||
| -rw-r--r-- | synth.zig | 61 |
2 files changed, 50 insertions, 50 deletions
diff --git a/Variables.zig b/Variables.zig index 9732afa..d23f1f4 100644 --- a/Variables.zig +++ b/Variables.zig @@ -140,23 +140,10 @@ pub const Query = union(enum) { register: RegisterEnum, stack: usize, - pub fn all(allocator: Allocator) Allocator.Error![]Query { - const constants = tags(ConstantEnum); - const registers = tags(RegisterEnum); - const n = constants.len + registers.len; - const queries = try allocator.alloc(Query, n); - for (queries[0..constants.len], constants) |*dest, src| - dest.* = .{ .constant = src }; - for (queries[constants.len..][0..registers.len], - registers) |*dest, src| - dest.* = .{ .register = src }; - return queries; - } - pub fn skip(q: Query, r: Query, s: Query) bool { - return eql(q, r) or eql(r, s) or eql(s, q) - or q == .constant and r == .constant and s == .constant - or q != .constant and r != .constant and s != .constant; + return eql(r, s) + or r == .constant and s == .constant + or (r == .constant or s == .constant) and q.constant != .max1; } pub fn format(query: Query, writer: *Writer) Writer.Error!void { @@ -168,6 +155,26 @@ pub const Query = union(enum) { } }; +pub fn constantQueries() []Query { + var queries: [tags(ConstantEnum).len]Query = undefined; + for (&queries, tags(ConstantEnum)) |*dest, src| + dest.* = .{ .constant = src }; + return &queries; +} + +pub fn allQueries(allocator: Allocator) Allocator.Error![]Query { + const constants = tags(ConstantEnum); + const registers = tags(RegisterEnum); + const n = constants.len + registers.len; + const queries = try allocator.alloc(Query, n); + for (queries[0..constants.len], constants) |*dest, src| + dest.* = .{ .constant = src }; + for (queries[constants.len..][0..registers.len], + registers) |*dest, src| + dest.* = .{ .register = src }; + return queries; +} + pub fn get(variables: Variables, query: Query, tmp: []Register) ![]const Register { switch (query) { diff --git a/synth.zig b/synth.zig index e82f85b..5f33c6a 100644 --- a/synth.zig +++ b/synth.zig @@ -89,9 +89,9 @@ const ArithmeticOperator = enum { }; const Arithmetic = struct { - lhs: Unary, + lhs: Variables.Query, op: ArithmeticOperator, - rhs: Unary, + rhs: Variables.Query, pub fn format(arith: Arithmetic, writer: *Writer) Writer.Error!void { try writer.print("{f} {s} {f}", .{ @@ -103,19 +103,17 @@ const Arithmetic = struct { }; const Comparison = struct { - lhs: Unary, + lhs: Arithmetic, op: CompareOperator, - rhs: Arithmetic, + rhs: Unary, fn check(cmp: Comparison, vars: Variables, expected: bool, tmp: Temporaries) !bool { - for (try vars.get(cmp.lhs.val, tmp[0]), - try vars.get(cmp.rhs.lhs.val, tmp[1]), - try vars.get(cmp.rhs.rhs.val, tmp[2])) |v0, v1, v2| { - const arith = cmp.rhs.op.apply(cmp.rhs.lhs.op.apply(v1), - cmp.rhs.lhs.op.apply(v2)) catch - return false; - const actual = compare(cmp.lhs.op.apply(v0), cmp.op, arith); + for (try vars.get(cmp.lhs.lhs, tmp[0]), + try vars.get(cmp.lhs.rhs, tmp[1]), + try vars.get(cmp.rhs.val, tmp[2])) |v0, v1, v2| { + const arith = cmp.lhs.op.apply(v0, v1) catch return false; + const actual = compare(arith, cmp.op, cmp.rhs.op.apply(v2)); if (if (expected) !actual else actual) return false; } @@ -141,18 +139,14 @@ const Comparison = struct { const Temporaries = [3][]Register; fn process(writer: *Writer, bot: Variables, top: Variables, - v0: Variables.Query, v1: Variables.Query, v2: Variables.Query, - o0: UnaryOperator, o1: UnaryOperator, o2: UnaryOperator, - arith: ArithmeticOperator, cmp: CompareOperator, - bot_tmp: Temporaries, top_tmp: Temporaries) !void { + bot_tmp: Temporaries, top_tmp: Temporaries, + v0: Variables.Query, arith: ArithmeticOperator, + v1: Variables.Query, cmp: CompareOperator, + unary: UnaryOperator, v2: Variables.Query) !void { const predicate = Comparison{ - .lhs = .{ .op = o0, .val = v0 }, + .lhs = .{ .lhs = v0, .op = arith, .rhs = v1 }, .op = cmp, - .rhs = .{ - .lhs = .{ .op = o1, .val = v1 }, - .op = arith, - .rhs = .{ .op = o2, .val = v2 }, - }, + .rhs = .{ .op = unary, .val = v2 }, }; if (try predicate.check(bot, false, bot_tmp)) return; @@ -162,15 +156,14 @@ fn process(writer: *Writer, bot: Variables, top: Variables, } fn mineOperator(writer: *Writer, bot: Variables, top: Variables, - v0: Variables.Query, v1: Variables.Query, v2: Variables.Query, - bot_tmp: Temporaries, top_tmp: Temporaries) !void { - for (tags(UnaryOperator)) |o0| - for (tags(UnaryOperator)) |o1| - for (tags(UnaryOperator)) |o2| - for (tags(ArithmeticOperator)) |arith| - for (tags(CompareOperator)) |cmp| - try process(writer, bot, top, v0, v1, v2, o0, o1, o2, - arith, cmp, bot_tmp, top_tmp); + bot_tmp: Temporaries, top_tmp: Temporaries, + v0: Variables.Query, v1: Variables.Query, + v2: Variables.Query) !void { + for (tags(ArithmeticOperator)) |arith| + for (tags(UnaryOperator)) |unary| + for (tags(CompareOperator)) |cmp| + try process(writer, bot, top, bot_tmp, top_tmp, + v0, arith, v1, cmp, unary, v2); } fn alloc_tmp(allocator: Allocator, len: usize) Allocator.Error!Temporaries { @@ -193,11 +186,11 @@ fn mine(allocator: Allocator, writer: *Writer, const top_tmp = try alloc_tmp(allocator, top.samples); defer free_tmp(allocator, top_tmp); - const variables = try Variables.Query.all(allocator); + const variables = try Variables.allQueries(allocator); defer allocator.free(variables); - for (variables) |v0| for (variables) |v1| for (variables) |v2| - if (!v0.skip(v1, v2)) - try mineOperator(writer, bot, top, v0, v1, v2, bot_tmp, top_tmp); + inline for (comptime Variables.constantQueries()) |v2| + for (variables) |v0| for (variables) |v1| if (!v2.skip(v0, v1)) + try mineOperator(writer, bot, top, bot_tmp, top_tmp, v0, v1, v2); try writer.flush(); } |
