#include #include #include #include "libblang.h" /* assumes unmodified chart */ void Chart_iron(struct State *s){ chart_t index; chart_t lookahead; index = s->chart; while(*index != '\0'){ if(*index == ';'){ lookahead = index; while( *lookahead != '!' && *lookahead != '\n' && *lookahead != '\0' ) ++lookahead; } ++index; } } void Ops_bang(struct State *s){ return; } /* more like a whimper */ void Ops_land(struct State *s){ return; } void Ops_snd(struct State *s) { *(s->chart) = s->hand; } void Ops_rcv(struct State *s) { s->hand = (hand_t)*(s->chart); } void Ops_et(struct State *s) { s->hand = (hand_t)s->chart; } void Ops_splat(struct State *s) { s->chart = (chart_t)s->hand; } void Ops_inc(struct State *s) { ++(s->hand); } void Ops_dec(struct State *s) { --(s->hand); } void Ops_invert(struct State *s){ s->hand = !s->hand; } void Ops_sail(struct State *s) { while(Ops_lookup(*(s->counter)) != Ops_land) --*(s->counter); } void Ops_in(struct State *s) { s->hand = *++s->counter; } void Ops_out(struct State *s) { putc((char)s->hand, stdout); } void Ops_what(struct State *s) { s->counter += !s->hand; } void Ops_comment(struct State *s){ while(strchr(BLANG_COMMENT_END, *++s->counter) == NULL); } const struct { unsigned char name; void (*f)(struct State *); } OPS[] = { { '!', Ops_bang }, { ' ', Ops_bang }, { '\n', Ops_bang }, { '\r', Ops_bang }, { '\t', Ops_bang }, { '\v', Ops_bang }, { '%', Ops_snd }, { '^', Ops_rcv }, { '&', Ops_et }, { '*', Ops_splat }, { '+', Ops_inc }, { '-', Ops_dec }, { 'v', Ops_invert }, { '{', Ops_land }, { '}', Ops_sail }, { '<', Ops_in }, { '>', Ops_out }, { '?', Ops_what }, { ';', Ops_comment }, { '#', Ops_comment } }; /* 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; }