Browse Source

Add more helper macros for operators

master
cancel 6 years ago
parent
commit
47fcbfe1b4
  1. 73
      sim.c

73
sim.c

@ -2,7 +2,7 @@
#include "mark.h" #include "mark.h"
#include "sim.h" #include "sim.h"
#define OPER_INLINE static inline //////// Utilities
static Glyph const indexed_glyphs[] = { static Glyph const indexed_glyphs[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
@ -71,13 +71,20 @@ oper_move_relative_or_explode(Field_buffer field_buffer, Markmap_buffer markmap,
field_buffer[y * field_width + x] = '.'; field_buffer[y * field_width + x] = '.';
} }
#define ORCA_EXPAND_OPER_CHARS(_oper_name, _oper_char) \
Orca_oper_char_##_oper_name = _oper_char,
#define ORCA_DEFINE_OPER_CHARS(_defs) \
enum Orca_oper_chars { _defs(ORCA_EXPAND_OPER_CHARS) };
#define ORCA_DECLARE_OPERATORS(_defs) ORCA_DEFINE_OPER_CHARS(_defs)
#define OPER_PHASE_N(_phase_number, _oper_name) \ #define OPER_PHASE_N(_phase_number, _oper_name) \
static inline void oper_phase##_phase_number##_##_oper_name( \ static inline void oper_phase##_phase_number##_##_oper_name( \
Field* field, Markmap_buffer markmap, Usz y, Usz x) { \ Field* field, Markmap_buffer markmap, Usz y, Usz x) { \
(void)field; \ (void)field; \
(void)markmap; \ (void)markmap; \
(void)y; \ (void)y; \
(void)x; (void)x; \
enum { This_oper_char = Orca_oper_char_##_oper_name };
#define OPER_PHASE_0(_oper_name) OPER_PHASE_N(0, _oper_name) #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_1(_oper_name) OPER_PHASE_N(1, _oper_name)
@ -96,7 +103,23 @@ oper_move_relative_or_explode(Field_buffer field_buffer, Markmap_buffer markmap,
field->width, _glyph, y, x, _delta_y, \ field->width, _glyph, y, x, _delta_y, \
_delta_x); _delta_x);
OPER_PHASE_2(a) //////// Operators
#define ORCA_OPERATORS(_) \
_(bang, '*') \
_(add, 'a') \
_(East, 'E') \
_(modulo, 'm')
ORCA_DECLARE_OPERATORS(ORCA_OPERATORS)
//////// Phases
OPER_PHASE_0(add)
OPER_END
OPER_PHASE_1(add)
OPER_END
OPER_PHASE_2(add)
Glyph inp0 = OPER_PEEK_RELATIVE(0, 1); Glyph inp0 = OPER_PEEK_RELATIVE(0, 1);
Glyph inp1 = OPER_PEEK_RELATIVE(0, 2); Glyph inp1 = OPER_PEEK_RELATIVE(0, 2);
if (inp0 != '.' && inp1 != '.') { if (inp0 != '.' && inp1 != '.') {
@ -105,11 +128,19 @@ OPER_PHASE_2(a)
} }
OPER_END OPER_END
OPER_PHASE_1(E) OPER_PHASE_0(East)
OPER_END
OPER_PHASE_1(East)
OPER_MOVE_OR_EXPLODE(0, 1, 'E') OPER_MOVE_OR_EXPLODE(0, 1, 'E')
OPER_END OPER_END
OPER_PHASE_2(East)
OPER_END
OPER_PHASE_2(m) OPER_PHASE_0(modulo)
OPER_END
OPER_PHASE_1(modulo)
OPER_END
OPER_PHASE_2(modulo)
Glyph inp0 = OPER_PEEK_RELATIVE(0, 1); Glyph inp0 = OPER_PEEK_RELATIVE(0, 1);
Glyph inp1 = OPER_PEEK_RELATIVE(0, 2); Glyph inp1 = OPER_PEEK_RELATIVE(0, 2);
if (inp0 != '.' && inp1 != '.') { if (inp0 != '.' && inp1 != '.') {
@ -118,9 +149,13 @@ OPER_PHASE_2(m)
} }
OPER_END OPER_END
OPER_PHASE_1(star) OPER_PHASE_0(bang)
OPER_END
OPER_PHASE_1(bang)
OPER_POKE_SELF('.'); OPER_POKE_SELF('.');
OPER_END OPER_END
OPER_PHASE_2(bang)
OPER_END
void orca_run(Field* field, Markmap_buffer markmap) { void orca_run(Field* field, Markmap_buffer markmap) {
Usz ny = field->height; Usz ny = field->height;
@ -135,12 +170,12 @@ void orca_run(Field* field, Markmap_buffer markmap) {
if (markmap_peek(markmap, ny, nx, iy, ix) & Mark_flag_sleep) if (markmap_peek(markmap, ny, nx, iy, ix) & Mark_flag_sleep)
continue; continue;
switch (c) { switch (c) {
case '*': #define X(_oper_name, _oper_char) \
oper_phase1_star(field, markmap, iy, ix); case _oper_char: \
break; oper_phase0_##_oper_name(field, markmap, iy, ix); \
case 'E': break;
oper_phase1_E(field, markmap, iy, ix); ORCA_OPERATORS(X)
break; #undef X
} }
} }
} }
@ -152,15 +187,13 @@ void orca_run(Field* field, Markmap_buffer markmap) {
continue; continue;
Glyph c = glyph_row[ix]; Glyph c = glyph_row[ix];
switch (c) { switch (c) {
case 'a': #define X(_oper_name, _oper_char) \
oper_phase2_a(field, markmap, iy, ix); case _oper_char: \
break; oper_phase1_##_oper_name(field, markmap, iy, ix); \
case 'm': break;
oper_phase2_m(field, markmap, iy, ix); ORCA_OPERATORS(X)
break; #undef X
} }
} }
} }
} }
#undef OPER_INLINE

Loading…
Cancel
Save