lib/choir/src/core/mapping.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

  1 const std = @import("std");
  2 const Value = @import("value.zig").Value;
  3 const Block = @import("block.zig").Block;
  4 const Operation = @import("operation/root.zig").Operation;
  5 
  6 pub const Mapping = struct {
  7     allocator: std.mem.Allocator,
  8 
  9     values: std.AutoHashMapUnmanaged(*const Value, *Value) = .{},
 10 
 11     blocks: std.AutoHashMapUnmanaged(*const Block, *Block) = .{},
 12 
 13     operations: std.AutoHashMapUnmanaged(*const Operation, *Operation) = .{},
 14 
 15     pub fn init(allocator: std.mem.Allocator) Mapping {
 16         return .{ .allocator = allocator };
 17     }
 18 
 19     pub fn deinit(self: *Mapping) void {
 20         self.values.deinit(self.allocator);
 21         self.blocks.deinit(self.allocator);
 22         self.operations.deinit(self.allocator);
 23     }
 24 
 25     pub fn mapValue(self: *Mapping, source: *const Value, dest: *Value) !void {
 26         try self.values.put(self.allocator, source, dest);
 27     }
 28 
 29     pub fn lookupValue(self: *const Mapping, source: *const Value) ?*Value {
 30         return self.values.get(source);
 31     }
 32 
 33     pub fn lookupOrDefaultValue(self: *const Mapping, source: *Value) *Value {
 34         return self.lookupValue(source) orelse source;
 35     }
 36 
 37     pub fn mapBlock(self: *Mapping, source: *const Block, dest: *Block) !void {
 38         try self.blocks.put(self.allocator, source, dest);
 39     }
 40 
 41     pub fn lookupBlock(self: *const Mapping, source: *const Block) ?*Block {
 42         return self.blocks.get(source);
 43     }
 44 
 45     pub fn lookupOrDefaultBlock(self: *const Mapping, source: *Block) *Block {
 46         return self.lookupBlock(source) orelse source;
 47     }
 48 
 49     pub fn mapOperation(self: *Mapping, source: *const Operation, dest: *Operation) !void {
 50         try self.operations.put(self.allocator, source, dest);
 51     }
 52 
 53     pub fn lookupOperation(self: *const Mapping, source: *const Operation) ?*Operation {
 54         return self.operations.get(source);
 55     }
 56 
 57     pub fn lookupOrDefaultOperation(self: *const Mapping, source: *Operation) *Operation {
 58         return self.lookupOperation(source) orelse source;
 59     }
 60 };
 61 
 62 test "mapping stores value block and operation remaps with identity fallback" {
 63     const testing = std.testing;
 64     const Context = @import("context/root.zig").Context;
 65 
 66     var mapping = Mapping.init(testing.allocator);
 67     defer mapping.deinit();
 68 
 69     var ctx = try Context.init(testing.allocator, Context.Limits.testing);
 70     defer ctx.deinit(testing.allocator);
 71     try ctx.allowUnregistered();
 72     const value_type = try ctx.getDialectTypeFromName("test.value");
 73 
 74     var source_block = Block.init(testing.allocator);
 75     defer source_block.deinit();
 76     var dest_block = Block.init(testing.allocator);
 77     defer dest_block.deinit();
 78     var external_block = Block.init(testing.allocator);
 79     defer external_block.deinit();
 80 
 81     const source_op = try ctx.createOperation(Operation.State.init("test.source", .unknown));
 82     const dest_op = try ctx.createOperation(Operation.State.init("test.dest", .unknown));
 83     const external_op = try ctx.createOperation(Operation.State.init("test.external", .unknown));
 84 
 85     var source_value = Value{
 86         .kind = .{ .block_argument = .{
 87             .owner = &source_block,
 88             .arg_number = 0,
 89         } },
 90         .type = value_type,
 91         .id = 1,
 92     };
 93     var dest_value = Value{
 94         .kind = .{ .block_argument = .{
 95             .owner = &dest_block,
 96             .arg_number = 0,
 97         } },
 98         .type = value_type,
 99         .id = 2,
100     };
101     var external_value = Value{
102         .kind = .{ .block_argument = .{
103             .owner = &external_block,
104             .arg_number = 0,
105         } },
106         .type = value_type,
107         .id = 3,
108     };
109 
110     try mapping.mapValue(&source_value, &dest_value);
111     try mapping.mapBlock(&source_block, &dest_block);
112     try mapping.mapOperation(source_op, dest_op);
113 
114     try testing.expect(mapping.lookupValue(&source_value).? == &dest_value);
115     try testing.expect(mapping.lookupBlock(&source_block).? == &dest_block);
116     try testing.expect(mapping.lookupOperation(source_op).? == dest_op);
117     try testing.expect(mapping.lookupOrDefaultValue(&external_value) == &external_value);
118     try testing.expect(mapping.lookupOrDefaultBlock(&external_block) == &external_block);
119     try testing.expect(mapping.lookupOrDefaultOperation(external_op) == external_op);
120 }