Skip to content

Instantly share code, notes, and snippets.

@samkhn
Created January 18, 2023 15:24
Show Gist options
  • Save samkhn/8a244aaddd84715b74639c2ed0d5dd6b to your computer and use it in GitHub Desktop.
Save samkhn/8a244aaddd84715b74639c2ed0d5dd6b to your computer and use it in GitHub Desktop.
// Demo of a FSM using function pointers.
#include <stdio.h>
enum return_codes { ok, fail, repeat };
int entry_state() { return ok; }
int foo_state() { return ok; }
int bar_state() { return ok; }
int end_state() { return ok; }
int unknown_state() { return ok; }
enum state_codes { entry, foo, bar, end, unknown };
const char *get_state_name(int state_codes) {
switch (state_codes) {
case entry: return "entry";
case foo: return "foo";
case bar: return "bar";
case end: return "end";
case unknown: return "unknown";
default: break;
}
return "";
}
int (*state[])() = { entry_state, foo_state, bar_state, end_state, unknown_state };
struct transition {
enum state_codes src_state;
enum return_codes return_code;
enum state_codes dst_state;
};
// Optmization from O(n) is to make it a multidimensional array
struct transition state_transitions [] = {
{entry, ok, foo},
{entry, fail, end},
{foo, ok, bar},
{foo, fail, end},
{foo, repeat, foo},
{bar, ok, end},
{bar, fail, end},
{bar, repeat, foo}
};
int lookup_transitions(enum state_codes prev_state, enum return_code previous_return_code) {
int num_transitions = sizeof(state_transitions)/sizeof(struct transition);
int r = unknown;
struct transition t;
for (int i = 0; i < num_transitions; ++i) {
t = state_transitions[i];
if (t.src_state == prev_state && t.return_code == previous_return_code) {
r = t.dst_state;
break;
}
}
printf("Transitioning from %s to %s\n", get_state_name(prev_state), get_state_name(r));
return r;
}
#define ENTRY_STATE entry
#define END_STATE end
int main() {
enum state_codes current_state = ENTRY_STATE;
enum return_codes return_code;
int (* state_func)();
for (;;) {
state_func = state[current_state];
return_code = state_func();
if (END_STATE == current_state) {
break;
}
current_state = lookup_transitions(current_state, return_code);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment