blang/src/ops.c

113 lines
1.8 KiB
C
Raw Normal View History

2022-12-09 21:33:04 +00:00
#include <stdio.h>
#include <stdlib.h>
2022-12-10 00:46:32 +00:00
#include <string.h>
2022-12-09 21:33:04 +00: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-10 00:26:10 +00:00
s->hand = 0;
2022-12-09 21:33:04 +00:00
}
void Ops_ampersand(struct State *s){
2022-12-10 02:59:48 +00:00
s->hand = (uint64_t)s->chart;
2022-12-09 21:33:04 +00:00
}
2022-12-10 00:26:10 +00:00
void Ops_splat(struct State *s){
2022-12-10 00:46:32 +00:00
s->chart = (char *)s->hand;
2022-12-10 00:26:10 +00:00
}
2022-12-09 21:33:04 +00:00
void Ops_plus(struct State *s){
2022-12-10 00:26:10 +00:00
++(s->hand);
2022-12-09 21:33:04 +00:00
}
void Ops_dash(struct State *s){
2022-12-10 00:26:10 +00:00
--(s->hand);
2022-12-09 21:33:04 +00:00
}
2022-12-10 02:59:48 +00:00
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;
}
2022-12-09 21:33:04 +00:00
void Ops_right(struct State *s){
2022-12-10 00:26:10 +00:00
putc((char)s->hand, stdout);
2022-12-09 21:33:04 +00:00
}
2022-12-10 02:59:48 +00:00
void Ops_what(struct State *s){
if(!s->hand)
++(s->counter);
2022-12-09 21:33:04 +00:00
}
void Ops_semi(struct State *s){
2022-12-10 00:46:32 +00:00
int c;
2022-12-10 02:59:48 +00:00
while(strchr("!\n", *++s->counter) == NULL);
}
void Ops_mirror(struct State *s){
s->hand = !s->hand;
2022-12-09 21:33:04 +00:00
}
void Ops_cross(struct State *s){
char *i;
i = s->chart;
s->chart = (char *)s->hand;
2022-12-10 02:59:48 +00:00
s->hand = (uint64_t)i;
2022-12-09 21:33:04 +00:00
}
const struct {
unsigned char name;
void (*f)(struct State *);
2022-12-10 00:46:32 +00:00
} OPS[] = {
2022-12-10 02:59:48 +00:00
{ '#', Ops_semi },
2022-12-09 21:33:04 +00:00
{ '%', Ops_percent },
2022-12-10 00:46:32 +00:00
{ '^', Ops_carat },
2022-12-09 21:33:04 +00:00
{ '&', Ops_ampersand },
{ '*', Ops_splat },
{ '+', Ops_plus },
{ '-', Ops_dash },
2022-12-10 02:59:48 +00:00
{ '{', Ops_lbrack },
{ '}', Ops_rbrack },
{ ';', Ops_semi },
2022-12-09 21:33:04 +00:00
{ '>', Ops_right },
{ '<', Ops_left },
2022-12-10 02:59:48 +00:00
{ '?', Ops_what },
{ 'v', Ops_mirror },
2022-12-09 21:33:04 +00:00
{ '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-10 00:46:32 +00:00
void (*Ops_lookup(char op))(struct State *){
2022-12-09 21:33:04 +00:00
size_t i;
for(i = 0; i < (sizeof OPS)/(sizeof *OPS); ++i)
if(op == OPS[i].name)
return OPS[i].f;
return NULL;
}