2022-12-09 14:33:04 -07:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2022-12-09 17:46:32 -07:00
|
|
|
#include <string.h>
|
2022-12-09 14:33:04 -07:00
|
|
|
|
|
|
|
#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){
|
2022-12-09 17:26:10 -07:00
|
|
|
s->hand = 0;
|
2022-12-09 14:33:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Ops_ampersand(struct State *s){
|
2022-12-09 17:46:32 -07:00
|
|
|
s->hand = (char)s->chart;
|
2022-12-09 14:33:04 -07:00
|
|
|
}
|
|
|
|
|
2022-12-09 17:26:10 -07:00
|
|
|
void Ops_splat(struct State *s){
|
2022-12-09 17:46:32 -07:00
|
|
|
s->chart = (char *)s->hand;
|
2022-12-09 17:26:10 -07:00
|
|
|
}
|
|
|
|
|
2022-12-09 14:33:04 -07:00
|
|
|
void Ops_plus(struct State *s){
|
2022-12-09 17:26:10 -07:00
|
|
|
++(s->hand);
|
2022-12-09 14:33:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Ops_dash(struct State *s){
|
2022-12-09 17:26:10 -07:00
|
|
|
--(s->hand);
|
2022-12-09 14:33:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Ops_right(struct State *s){
|
2022-12-09 17:26:10 -07:00
|
|
|
putc((char)s->hand, stdout);
|
2022-12-09 14:33:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Ops_left(struct State *s){
|
2022-12-09 17:26:10 -07:00
|
|
|
s->hand = getc(stdin);
|
2022-12-09 14:33:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Ops_semi(struct State *s){
|
2022-12-09 17:46:32 -07:00
|
|
|
int c;
|
|
|
|
|
2022-12-09 14:33:04 -07:00
|
|
|
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 *);
|
2022-12-09 17:46:32 -07:00
|
|
|
} OPS[] = {
|
2022-12-09 14:33:04 -07:00
|
|
|
{ '%', Ops_percent },
|
2022-12-09 17:46:32 -07:00
|
|
|
{ '^', Ops_carat },
|
2022-12-09 14:33:04 -07:00
|
|
|
{ '&', 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! */
|
2022-12-09 17:46:32 -07:00
|
|
|
void (*Ops_lookup(char op))(struct State *){
|
2022-12-09 14:33:04 -07:00
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for(i = 0; i < (sizeof OPS)/(sizeof *OPS); ++i)
|
|
|
|
if(op == OPS[i].name)
|
|
|
|
return OPS[i].f;
|
|
|
|
return NULL;
|
|
|
|
}
|