Found interesting pattern to write some common code for some enum values.
switch (instruction) {
inline .add,
.subtract,
.multiply,
.divide,
=> |op| {
const b = vm.stack.popOrNull() orelse return error.Runtime;
const a = vm.stack.popOrNull() orelse return error.Runtime;
const result = switch (op) {
.add => a.inner + b.inner,
.subtract => a.inner - b.inner,
.multiply => a.inner * b.inner,
.divide => a.inner / b.inner,
else => comptime unreachable,
};
vm.stack.appendAssumeCapacity(.{ .inner = result });
},
//....some other non binary operators
}
If I add new binary instruction like so:
switch (instruction) {
inline .add,
.subtract,
.multiply,
.divide,
.power, // new
=> |op| {
const b = vm.stack.popOrNull() orelse return error.Runtime;
const a = vm.stack.popOrNull() orelse return error.Runtime;
const result = switch (op) {
.add => a.inner + b.inner,
.subtract => a.inner - b.inner,
.multiply => a.inner * b.inner,
.divide => a.inner / b.inner,
else => comptime unreachable, // reached unreachable
};
vm.stack.appendAssumeCapacity(.{ .inner = result });
},
//....some other non binary operators
}
It will result in compile error since it will reach comptime unreachable in switch. And its pretty nice
But what if I remove binary operator
switch (instruction) {
inline .add,
.subtract,
.multiply, // how needs division anyway
=> |op| {
const b = vm.stack.popOrNull() orelse return error.Runtime;
const a = vm.stack.popOrNull() orelse return error.Runtime;
const result = switch (op) {
.add => a.inner + b.inner,
.subtract => a.inner - b.inner,
.multiply => a.inner * b.inner,
.divide => a.inner / b.inner,
else => comptime unreachable,
};
vm.stack.appendAssumeCapacity(.{ .inner = result });
},
//....some other non binary operators
}
This will compile
Not really a big problem since it’s rare to remove instructions but maybe there is some cleaver solution?