#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 = (uint64_t)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_lbrack(struct State *s){ s->point = s->counter; } void Ops_rbrack(struct State *s){ s->counter = s->point; } void Ops_left(struct State *s){ s->hand = *++s->counter; } void Ops_right(struct State *s){ putc((char)s->hand, stdout); } void Ops_what(struct State *s){ if(!s->hand) ++(s->counter); } void Ops_semi(struct State *s){ int c; while(strchr("!\n", *++s->counter) == NULL); } void Ops_mirror(struct State *s){ s->hand = !s->hand; } void Ops_cross(struct State *s){ char *i; i = s->chart; s->chart = (char *)s->hand; s->hand = (uint64_t)i; } const struct { unsigned char name; void (*f)(struct State *); } OPS[] = { { '#', Ops_semi }, { '%', Ops_percent }, { '^', Ops_carat }, { '&', Ops_ampersand }, { '*', Ops_splat }, { '+', Ops_plus }, { '-', Ops_dash }, { '{', Ops_lbrack }, { '}', Ops_rbrack }, { ';', Ops_semi }, { '>', Ops_right }, { '<', Ops_left }, { '?', Ops_what }, { 'v', Ops_mirror }, { '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; }