From f1b61a6346ae695568aa51b3502d58b8b36d346a Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Tue, 28 Apr 2009 00:34:55 +0000 Subject: brainfuck interpreter --- Makefile | 6 ++++ bf.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw.bf | 17 +++++++++ 3 files changed, 141 insertions(+) create mode 100644 Makefile create mode 100644 bf.c create mode 100644 hw.bf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..82f2073 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +# $Id$ + +PROG= bf +NOMAN= + +.include diff --git a/bf.c b/bf.c new file mode 100644 index 0000000..411f50d --- /dev/null +++ b/bf.c @@ -0,0 +1,118 @@ +/* $Id$ */ +/* + * Copyright (c) 2009 Dimitri SokolyukE + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +typedef struct cell Cell; + +struct cell { + char value; + Cell *next; + Cell *prev; +}; + +Cell * +alloccell(void) +{ + Cell *c; + + c = malloc(sizeof(Cell)); + assert(c); + + c->value = 0; + c->next = NULL; + c->prev = NULL; + + return c; +} + +int +main(int argc, char **argv) +{ + FILE *fd; + Cell *data, *prog, **progp, *p; + int ch; + + if (argc != 2) + return -1; + + fd = fopen(argv[1], "r"); + assert(fd); + + prog = NULL; + progp = &prog; + p = NULL; + + while ((ch = fgetc(fd)) != EOF) { + *progp = alloccell(); + (*progp)->value = ch; + (*progp)->prev = p; + p = *progp; + progp = &(*progp)->next; + } + + fclose(fd); + + data = alloccell(); + + for (p = prog; p; p = p->next) + switch (p->value) { + case '>': + if (!data->next) { + data->next = alloccell(); + data->next->prev = data; + } + data = data->next; + break; + case '<': + if (!data->prev) { + data->prev = alloccell(); + data->prev->next = data; + } + data = data->prev; + break; + case '+': + ++data->value; + break; + case '-': + --data->value; + break; + case '.': + fputc(data->value, stdout); + fflush(stdout); + break; + case ',': + data->value = fgetc(stdin); + break; + case '[': + if (data->value == 0) + while (p && p->value != ']') + p = p->next; + break; + case ']': + if (data->value != 0) + while (p && p->value != '[') + p = p->prev; + break; + default: + break; + } + + return 0; +} diff --git a/hw.bf b/hw.bf new file mode 100644 index 0000000..76e0dc1 --- /dev/null +++ b/hw.bf @@ -0,0 +1,17 @@ +++++++++++ initializes cell zero to 10 +[ + >+++++++>++++++++++>+++>+<<<<- +] this loop sets the next four cells to 70/100/30/10 +>++. print 'H' +>+. print 'e' ++++++++. 'l' +. 'l' ++++. 'o' +>++. space +<<+++++++++++++++. 'W' +>. 'o' ++++. 'r' +------. 'l' +--------. 'd' +>+. '!' +>. newline -- cgit v1.2.3