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 }