/* @(#)bf.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
typedef struct BI_t {
struct BI_t *previous, *next;
char *data;
char visited;
} BrainfuckInstruction;
typedef bool (*bi_op)(BrainfuckInstruction*);
BrainfuckInstruction *bi_make(const char *data);
bool bi_delete(BrainfuckInstruction *instruction);
void bi_foreach(BrainfuckInstruction* start, bi_op f);
BrainfuckInstruction *bi_make(const char *data) {
BrainfuckInstruction
*instruction
= calloc(1, sizeof(BrainfuckInstruction
)); if (instruction) {
strcpy(instruction
->data
, data
); } else {
int err = errno;
bi_delete(instruction);
instruction = NULL;
errno = err;
}
}
return instruction;
}
bool bi_discard(BrainfuckInstruction *instruction) {
if (instruction->data) {
printf("discarding '%s'\n", instruction
->data
); }
return 1;
}
bool bi_delete(BrainfuckInstruction *instruction) {
if (instruction->next) {
instruction->next->previous = instruction->previous;
}
if (instruction->previous) {
instruction->previous->next = instruction->next;
}
bi_discard(instruction);
return 1;
}
BrainfuckInstruction* bi_insert_after(BrainfuckInstruction *instruction, BrainfuckInstruction *after) {
instruction->previous = after;
instruction->next = after->next;
after->next = instruction;
if (instruction->next) {
instruction->next->previous = instruction;
}
return instruction;
}
void bi_foreach(BrainfuckInstruction* start, bi_op f) {
while (start) {
if (! f(start)) { return; }
start = start->next;
}
}
bool bi_unvisit(BrainfuckInstruction* instruction) {
if (instruction->visited) {
instruction->visited = 0;
return 1;
}
return 0;
}
bool bi_print(BrainfuckInstruction* instruction) {
printf("%s\n", instruction
->data
); return 1;
}
typedef struct BS_t {
BrainfuckInstruction *head;
} BrainfuckState;
BrainfuckState *bs_make() {
return calloc(1, sizeof(BrainfuckState
)); }
void bs_delete(BrainfuckState *state) {
bi_foreach(state->head, bi_discard);
}
void bs_unvisit(BrainfuckState* state) {
bi_foreach(state->head, bi_unvisit);
}
void bs_foreach(BrainfuckState* state, bi_op f) {
BrainfuckInstruction *curr = state->head;
while (curr && ! curr->visited) {
curr->visited = 1;
if (! f(curr)) { return ; }
curr = curr->next;
}
bs_unvisit(state);
}
void bs_print(BrainfuckState* state) {
bs_foreach(state, bi_print);
}
BrainfuckInstruction * brainfuck_insert_after(BrainfuckState *state, BrainfuckInstruction *after, BrainfuckInstruction *instruction)
{
if (state == NULL || after == NULL || instruction == NULL)
return NULL;
BrainfuckInstruction *next = after->next;
after->next = instruction;
instruction->previous = after;
BrainfuckInstruction *iter = instruction;
while (iter != NULL) {
if (iter->next == NULL)
break;
iter = iter->next;
}
if (next != NULL) {
next->previous = iter;
iter->next = next;
}
if (state->head == after)
state->head = iter;
return instruction;
}
int main(int argc, char **argv) {
BrainfuckInstruction *end;
BrainfuckState *state;
state = bs_make();
end = state->head = bi_make("start");
end = bi_insert_after(bi_make("step 1"), end);
end = bi_insert_after(bi_make("step 2"), end);
end = bi_insert_after(bi_make("step 3"), end);
end = bi_insert_after(bi_make("end"), end);
BrainfuckInstruction *curr;
curr = bi_make("WHOOP");
bi_insert_after(bi_make("DE"), curr);
bi_insert_after(bi_make("DO"), curr->next);
brainfuck_insert_after(state, state->head->next, curr);
bs_print(state);
bs_delete(state);
return 0;
}