blang/src/libblang.c

79 lines
2.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}