diff --git a/.clang-format b/.clang-format index 0194e0d..fca6e0e 100644 --- a/.clang-format +++ b/.clang-format @@ -1,3 +1,6 @@ BasedOnStyle: LLVM PointerAlignment: Left ReflowComments: false + +MacroBlockBegin: "^OPER_PHASE_." +MacroBlockEnd: "^OPER_END" diff --git a/sim.c b/sim.c index b2de700..1fc2cbd 100644 --- a/sim.c +++ b/sim.c @@ -71,39 +71,55 @@ oper_move_relative_or_explode(Field_buffer field_buffer, Markmap_buffer markmap, field_buffer[y * field_width + x] = '.'; } -static inline void oper_phase2_a(Field* field, Markmap_buffer markmap, Usz y, - Usz x) { - (void)markmap; - Glyph inp0 = field_peek_relative(field, y, x, 0, 1); - Glyph inp1 = field_peek_relative(field, y, x, 0, 2); +#define OPER_PHASE_N(_phase_number, _oper_name) \ + static inline void oper_phase##_phase_number##_##_oper_name( \ + Field* field, Markmap_buffer markmap, Usz y, Usz x) { \ + (void)field; \ + (void)markmap; \ + (void)y; \ + (void)x; + +#define OPER_PHASE_0(_oper_name) OPER_PHASE_N(0, _oper_name) +#define OPER_PHASE_1(_oper_name) OPER_PHASE_N(1, _oper_name) +#define OPER_PHASE_2(_oper_name) OPER_PHASE_N(2, _oper_name) +#define OPER_END } + +#define OPER_PEEK_RELATIVE(_delta_y, _delta_x) \ + field_peek_relative(field, y, x, _delta_y, _delta_x) +#define OPER_POKE_RELATIVE(_delta_y, _delta_x, _glyph) \ + field_poke_relative(field, y, x, _delta_x, _delta_y, _glyph) +#define OPER_POKE_ABSOLUTE(_y, _x, _glyph) field_poke(field, _y, _x, _glyph) + +#define OPER_MOVE_OR_EXPLODE(_delta_y, _delta_x) \ + oper_move_relative_or_explode(field->buffer, markmap, field->height, \ + field->width, 'E', y, x, 0, 1); + +OPER_PHASE_2(a) + Glyph inp0 = OPER_PEEK_RELATIVE(0, 1); + Glyph inp1 = OPER_PEEK_RELATIVE(0, 2); if (inp0 != '.' && inp1 != '.') { Glyph g = glyphs_sum(inp0, inp1); field_poke_relative(field, y, x, 1, 0, g); } -} +OPER_END -static inline void oper_phase1_E(Field* field, Markmap_buffer markmap, Usz y, - Usz x) { +OPER_PHASE_1(E) oper_move_relative_or_explode(field->buffer, markmap, field->height, field->width, 'E', y, x, 0, 1); -} +OPER_END -static inline void oper_phase2_m(Field* field, Markmap_buffer markmap, Usz y, - Usz x) { - (void)markmap; - Glyph inp0 = field_peek_relative(field, y, x, 0, 1); - Glyph inp1 = field_peek_relative(field, y, x, 0, 2); +OPER_PHASE_2(m) + Glyph inp0 = OPER_PEEK_RELATIVE(0, 1); + Glyph inp1 = OPER_PEEK_RELATIVE(0, 2); if (inp0 != '.' && inp1 != '.') { Glyph g = glyphs_mod(inp0, inp1); - field_poke_relative(field, y, x, 1, 0, g); + OPER_POKE_RELATIVE(1, 0, g); } -} +OPER_END -static inline void oper_phase1_star(Field* field, Markmap_buffer markmap, Usz y, - Usz x) { - (void)markmap; - field_poke(field, y, x, '.'); -} +OPER_PHASE_1(star) + OPER_POKE_ABSOLUTE(y, x, '.'); +OPER_END void orca_run(Field* field, Markmap_buffer markmap) { Usz ny = field->height;