A little stack machine

Threw this together to show an example of computed goto. Computed goto is a handy tool for building little interpreters.

#include 

#define NEXT goto **ip++
int main()
{
  int fact = 6, fact_b0 = 16;
  void* program[] = { 
    &&push, (void*)5, &&call, (void*)fact, &&printi, &&end,
    &&beq0, (void*)fact_b0, &&dup, &&push, (void*)1, &&sub, &&call, (void*)fact, &&mult, &&ret, 
    &&pop, &&push, (void*)1, &&ret  };
  void** ip = program;
  void* stack[16] = {0}; void** sp = stack-1;
  void* cstack[16] = {0}; void** cp = cstack-1;
  NEXT;
call:
  *++cp = ip+1; ip = program + (int)*ip;
  NEXT;
ret:
  ip = *cp--;
  NEXT;
beq0:
  ip = *sp ? ip+1 : program + (int)*ip;
  NEXT;
push:
  *++sp = *ip++;
  NEXT;
pop:
  --sp;
  NEXT;
dup:
  sp[1] = sp[0]; sp++;
  NEXT;
mult:
  sp[-1] = (void*)((int)sp[-1] * (int)sp[0]); sp--;
  NEXT;
sub:
  sp[-1] = (void*)((int)sp[-1] - (int)sp[0]); sp--;
  NEXT;
printi:
  printf("%i\n", (int)*sp--);
  NEXT;
end:
  return 0;
}

On codepad