lib/choir/src/core/ops.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

  1 const Operation = @import("operation/root.zig").Operation;
  2 const Value = @import("value.zig").Value;
  3 const Type = @import("type.zig").Type;
  4 const Location = @import("location.zig").Location;
  5 const Context = @import("context/root.zig").Context;
  6 const OperationBuilder = @import("builder.zig").OperationBuilder;
  7 
  8 pub fn NoOperandOp(comptime name: []const u8) type {
  9     return struct {
 10         op: *Operation,
 11         pub const operation_name = name;
 12 
 13         pub fn create(ctx: *Context, loc: Location) !@This() {
 14             var builder = OperationBuilder.init(ctx);
 15             return createWithBuilder(&builder, loc);
 16         }
 17 
 18         pub fn createWithBuilder(builder: anytype, loc: Location) !@This() {
 19             const state = Operation.State.init(operation_name, loc);
 20             const op = try builder.create(state);
 21             return .{ .op = op };
 22         }
 23     };
 24 }
 25 
 26 pub fn UnaryNoResultOp(comptime name: []const u8) type {
 27     return struct {
 28         op: *Operation,
 29         pub const operation_name = name;
 30 
 31         pub fn create(ctx: *Context, loc: Location, operand: *Value) !@This() {
 32             var builder = OperationBuilder.init(ctx);
 33             return createWithBuilder(&builder, loc, operand);
 34         }
 35 
 36         pub fn createWithBuilder(builder: anytype, loc: Location, operand: *Value) !@This() {
 37             var state = Operation.State.init(operation_name, loc);
 38             state.addOperands(&.{operand});
 39             const op = try builder.create(state);
 40             return .{ .op = op };
 41         }
 42     };
 43 }
 44 
 45 pub fn VariadicNoResultOp(comptime name: []const u8) type {
 46     return struct {
 47         op: *Operation,
 48         pub const operation_name = name;
 49 
 50         pub fn create(ctx: *Context, loc: Location, operands: []const *Value) !@This() {
 51             var builder = OperationBuilder.init(ctx);
 52             return createWithBuilder(&builder, loc, operands);
 53         }
 54 
 55         pub fn createWithBuilder(builder: anytype, loc: Location, operands: []const *Value) !@This() {
 56             var state = Operation.State.init(operation_name, loc);
 57             state.addOperands(operands);
 58             const op = try builder.create(state);
 59             return .{ .op = op };
 60         }
 61     };
 62 }
 63 
 64 pub fn UnaryOpSameType(comptime name: []const u8) type {
 65     return struct {
 66         op: *Operation,
 67         pub const operation_name = name;
 68 
 69         pub fn create(ctx: *Context, loc: Location, operand: *Value) !@This() {
 70             var builder = OperationBuilder.init(ctx);
 71             return createWithBuilder(&builder, loc, operand);
 72         }
 73 
 74         pub fn createWithBuilder(builder: anytype, loc: Location, operand: *Value) !@This() {
 75             var state = Operation.State.init(operation_name, loc);
 76             state.addOperands(&.{operand});
 77             state.addTypes(&.{operand.type});
 78             const op = try builder.create(state);
 79             return .{ .op = op };
 80         }
 81 
 82         pub fn getResult(self: *const @This()) *Value {
 83             return self.op.getResult(0).?;
 84         }
 85     };
 86 }
 87 
 88 pub fn UnaryOpWithResultType(comptime name: []const u8) type {
 89     return struct {
 90         op: *Operation,
 91         pub const operation_name = name;
 92 
 93         pub fn create(ctx: *Context, loc: Location, operand: *Value, result_type: Type) !@This() {
 94             var builder = OperationBuilder.init(ctx);
 95             return createWithBuilder(&builder, loc, operand, result_type);
 96         }
 97 
 98         pub fn createWithBuilder(
 99             builder: anytype,
100             loc: Location,
101             operand: *Value,
102             result_type: Type,
103         ) !@This() {
104             var state = Operation.State.init(operation_name, loc);
105             state.addOperands(&.{operand});
106             state.addTypes(&.{result_type});
107             const op = try builder.create(state);
108             return .{ .op = op };
109         }
110 
111         pub fn getResult(self: *const @This()) *Value {
112             return self.op.getResult(0).?;
113         }
114     };
115 }
116 
117 pub fn BinaryNoResultOp(comptime name: []const u8) type {
118     return struct {
119         op: *Operation,
120         pub const operation_name = name;
121 
122         pub fn create(ctx: *Context, loc: Location, lhs: *Value, rhs: *Value) !@This() {
123             var builder = OperationBuilder.init(ctx);
124             return createWithBuilder(&builder, loc, lhs, rhs);
125         }
126 
127         pub fn createWithBuilder(
128             builder: anytype,
129             loc: Location,
130             lhs: *Value,
131             rhs: *Value,
132         ) !@This() {
133             var state = Operation.State.init(operation_name, loc);
134             state.addOperands(&.{ lhs, rhs });
135             const op = try builder.create(state);
136             return .{ .op = op };
137         }
138     };
139 }
140 
141 pub fn BinaryOpSameType(comptime name: []const u8) type {
142     return struct {
143         op: *Operation,
144         pub const operation_name = name;
145 
146         pub fn create(ctx: *Context, loc: Location, lhs: *Value, rhs: *Value) !@This() {
147             var builder = OperationBuilder.init(ctx);
148             return createWithBuilder(&builder, loc, lhs, rhs);
149         }
150 
151         pub fn createWithBuilder(
152             builder: anytype,
153             loc: Location,
154             lhs: *Value,
155             rhs: *Value,
156         ) !@This() {
157             var state = Operation.State.init(operation_name, loc);
158             state.addOperands(&.{ lhs, rhs });
159             state.addTypes(&.{lhs.type});
160             const op = try builder.create(state);
161             return .{ .op = op };
162         }
163 
164         pub fn getResult(self: *const @This()) *Value {
165             return self.op.getResult(0).?;
166         }
167     };
168 }
169 
170 pub fn BinaryOpWithResultType(comptime name: []const u8) type {
171     return struct {
172         op: *Operation,
173         pub const operation_name = name;
174 
175         pub fn create(
176             ctx: *Context,
177             loc: Location,
178             lhs: *Value,
179             rhs: *Value,
180             result_type: Type,
181         ) !@This() {
182             var builder = OperationBuilder.init(ctx);
183             return createWithBuilder(&builder, loc, lhs, rhs, result_type);
184         }
185 
186         pub fn createWithBuilder(
187             builder: anytype,
188             loc: Location,
189             lhs: *Value,
190             rhs: *Value,
191             result_type: Type,
192         ) !@This() {
193             var state = Operation.State.init(operation_name, loc);
194             state.addOperands(&.{ lhs, rhs });
195             state.addTypes(&.{result_type});
196             const op = try builder.create(state);
197             return .{ .op = op };
198         }
199 
200         pub fn getResult(self: *const @This()) *Value {
201             return self.op.getResult(0).?;
202         }
203     };
204 }