diff options
| author | Nguyễn Gia Phong <cnx@loang.net> | 2025-10-17 16:27:57 +0900 |
|---|---|---|
| committer | Nguyễn Gia Phong <cnx@loang.net> | 2025-10-17 17:57:44 +0900 |
| commit | f4c491fce28223a09900aafeb6e1e83994df2bbd (patch) | |
| tree | a382e169120eea5e4728348c3e9252fbae724176 /Variables.zig | |
| parent | 3a2e8fd0b06ebb738d9d4677659249e05b09e7cb (diff) | |
| download | taosc-f4c491fce28223a09900aafeb6e1e83994df2bbd.tar.gz | |
Support constants and arithmetic operations in predicates
Diffstat (limited to 'Variables.zig')
| -rw-r--r-- | Variables.zig | 109 |
1 files changed, 92 insertions, 17 deletions
diff --git a/Variables.zig b/Variables.zig index 99f7061..9732afa 100644 --- a/Variables.zig +++ b/Variables.zig @@ -20,27 +20,29 @@ const Allocator = std.mem.Allocator; const Writer = std.io.Writer; const assert = std.debug.assert; const bytesAsSlice = std.mem.bytesAsSlice; +const comptimePrint = std.fmt.comptimePrint; const cwd = std.fs.cwd; const divCeil = std.math.divCeil; -const fields = std.meta.fields; +const eql = std.meta.eql; +const expect = std.testing.expect; +const maxInt = std.math.maxInt; +const minInt = std.math.minInt; const std = @import("std"); +const tags = std.meta.tags; pub const RegisterEnum = enum(u4) { rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp, r8, r9, r10, r11, r12, r13, r14, r15, - - pub fn format(tag: RegisterEnum, writer: *Writer) Writer.Error!void { - try writer.print("{s}", .{ @tagName(tag) }); - } }; -const Register = i64; -const Registers = [fields(RegisterEnum).len]Register; +pub const Register = i64; +const Registers = [tags(RegisterEnum).len]Register; pub const signed_integers = .{ i64, i32, i16, i8 }; const alignment = @alignOf(Register); -comptime { - for (signed_integers) |Int| - assert(alignment >= @alignOf(Int)); + +test alignment { + inline for (signed_integers) |Int| + try expect(alignment >= @alignOf(Int)); } fn alignedSize(T: type, count: usize) !usize { @@ -85,9 +87,9 @@ pub fn init(allocator: Allocator, stack_size: usize, assert(try file.getEndPos() == file_size); assert(try file.read(buffer) == file_size); var offset: usize = 0; - inline for (registers) |reg| { + inline for (registers) |register| { const slice = bytesAsSlice(Register, bytes[offset..]); - slice[index] = reg; + slice[index] = register; offset += try alignedSize(Register, count); } inline for (signed_integers) |Int| { @@ -106,9 +108,82 @@ pub fn deinit(variables: Variables, allocator: Allocator) void { allocator.free(variables.bytes); } -pub fn register(variables: Variables, name: RegisterEnum) ![]const Register { - const aligned_size = try alignedSize(Register, variables.samples); - const offset = aligned_size * @intFromEnum(name); - const slice = bytesAsSlice(Register, variables.bytes[offset..]); - return @alignCast(slice[0..variables.samples]); +const ConstantEnum = enum(i64) { + max1 = maxInt(i1), + min2 = minInt(i2), + max2 = maxInt(i2), + min3 = minInt(i3), + max3 = maxInt(i3), + min4 = minInt(i4), + max4 = maxInt(i4), + min5 = minInt(i5), + max5 = maxInt(i5), + min6 = minInt(i6), + max6 = maxInt(i6), + min7 = minInt(i7), + max7 = maxInt(i7), + min8 = minInt(i8), + max8 = maxInt(i8), + min9 = minInt(i9), + min16 = minInt(i16), + max16 = maxInt(i16), + min17 = minInt(i17), + min32 = minInt(i32), + max32 = maxInt(i32), + min33 = minInt(i33), + min64 = minInt(i64), + max64 = maxInt(i64), +}; + +pub const Query = union(enum) { + constant: ConstantEnum, + 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; + } + + pub fn format(query: Query, writer: *Writer) Writer.Error!void { + switch (query) { + inline .constant, .register => |tag| + try writer.print("{s}", .{ @tagName(tag) }), + .stack => unreachable, + } + } +}; + +pub fn get(variables: Variables, query: Query, + tmp: []Register) ![]const Register { + switch (query) { + .constant => |constant| switch (constant) { + inline else => |tag| { + for (tmp) |*register| + register.* = @intFromEnum(tag); + return tmp; + }, + }, + .register => |tag| { + const aligned_size = try alignedSize(Register, variables.samples); + const offset = aligned_size * @intFromEnum(tag); + const slice = bytesAsSlice(Register, variables.bytes[offset..]); + return @alignCast(slice[0..variables.samples]); + }, + .stack => unreachable, + } } |
