Build a complete opcode subsystem from one X-macro list. The
boilerplate provides:
``c
#define OPS \
X(ADD, 1) \
X(SUB, 2) \
X(MUL, 3)
`
Implement (using OPS — the enum, dispatch, and name lookup must all be
generated from it):
`c
/* OP_ADD=1, OP_SUB=2, OP_MUL=3 via pasting, plus OP_COUNT sentinel */
/* applies op to a and b; returns 0 and fills *out; -1 on bad op/args */
int op_apply(int op, int a, int b, int *out);
/* "ADD" -> OP_ADD; -1 if unknown */
int op_from_name(const char *name);
``
Rules: SUB is a-b; MUL is a*b; arithmetic must not overflow (use long
internally, return -1 if the true result does not fit int).
Difficulty: intermediate