#include #include #include #include "blang.h" /* no-op */ void Ops_bang(struct State *s){ return; } void Ops_percent(struct State *s){ *(s->chart) = s->hand; } void Ops_carat(struct State *s){ s->hand = 0; } void Ops_ampersand(struct State *s){ s->hand = (char)s->chart; } void Ops_splat(struct State *s){ s->chart = (char *)s->hand; } void Ops_plus(struct State *s){ ++(s->hand); } void Ops_dash(struct State *s){ --(s->hand); } void Ops_right(struct State *s){ putc((char)s->hand, stdout); } void Ops_left(struct State *s){ s->hand = getc(stdin); } void Ops_semi(struct State *s){ int c; while( (c = getc(stdin)) != EOF && strchr("!\n", c) == NULL ); } void Ops_cross(struct State *s){ char *i; i = s->chart; s->chart = (char *)s->hand; s->hand = (unsigned char)i; } const struct { unsigned char name; void (*f)(struct State *); } OPS[] = { { '%', Ops_percent }, { '^', Ops_carat }, { '&', Ops_ampersand }, { '*', Ops_splat }, { '+', Ops_plus }, { '-', Ops_dash }, { '>', Ops_right }, { '<', Ops_left }, { 'x', Ops_cross }, /* no-ops */ { '!', Ops_bang }, { ' ', Ops_bang }, { '\n', Ops_bang }, { '\r', Ops_bang }, { '\t', Ops_bang }, { '\v', Ops_bang } }; /* Slower than a switch but you don't have to update it when you add new * ops! */ void (*Ops_lookup(char op))(struct State *){ size_t i; for(i = 0; i < (sizeof OPS)/(sizeof *OPS); ++i) if(op == OPS[i].name) return OPS[i].f; return NULL; }