Listing 1 A state machine that maintains type safety

/*      J. Greg Davidson
 *      3:17 p.m., Monday, 28 November, 1994
 */
#include <stdio.h>
#include <ctype.h>

#define STATE(state_func) void (state_func) \
      ( struct state *return_state )
struct state { STATE(*func); };
#define GO(new_state) \
      { return_state->func = new_state; return; }

STATE(Sign);
STATE(Digit);
STATE(Finish);

char Char;
int  Ivalue = 0;
int  Isign = 1;

STATE(Sign)
{
  if (Char == '-')
    Isign = -1;
  else if (Char != '+')
    ungetc(Char, stdin);
  GO(Digit)
}

STATE(Digit)
{
  if (!isdigit(Char)) {
       ungetc(Char, stdin);
       GO(Finish)
  }
  Ivalue = Ivalue * 10 + (Char - '0');
  GO(Digit)
}

STATE(Finish)
{
  Ivalue *= Isign;
  ungetc(Char, stdin);
  GO(0)
}

int main()
{
  struct state s = { Sign };

  printf("Please enter an integer: ");
  while ( (Char = getchar()) != EOF && s.func )
     s.func(&s);
  printf("Value = %d\n", Ivalue);

  return 0;
}