79 lines
2.0 KiB
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;
|
|
}
|