summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--beef.c100
-rw-r--r--readme.md11
-rw-r--r--test.bf20
3 files changed, 131 insertions, 0 deletions
diff --git a/beef.c b/beef.c
new file mode 100644
index 0000000..1e7940e
--- /dev/null
+++ b/beef.c
@@ -0,0 +1,100 @@
+#include <stdlib.h>
+#include <stdio.h>
+#define SIZE 1024
+
+struct stack {
+ long int data;
+ struct stack *next;
+};
+
+void push(struct stack **s, long int i) {
+ struct stack *nuevo = malloc(sizeof(struct stack));
+ nuevo->data = i;
+ nuevo->next = *s;
+ *s = nuevo;
+}
+
+void pop(struct stack **s) {
+ struct stack *temp = *s;
+ *s = (*s)->next;
+ free(temp);
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) return 1;
+ FILE *source = fopen(argv[1], "r");
+ if (!source) return 1;
+ struct stack *open_brackets = 0;
+ char tape[SIZE] = {0};
+ char *curr = tape;
+ int lineNr = 1;
+ int exit = 0;
+ while (!feof(source) && !exit) {
+ char c = fgetc(source);
+ switch (c) {
+ case '\n':
+ lineNr++;
+ break;
+ case '+':
+ *curr += 1;
+ break;
+ case '-':
+ *curr -= 1;
+ break;
+ case '>':
+ if (curr != &tape[SIZE - 1]) curr++;
+ else curr = &tape[0];
+ break;
+ case '<':
+ if (curr != &tape[0]) curr--;
+ else curr = &tape[SIZE - 1];
+ break;
+ case '.':
+ putchar(*curr);
+ break;
+ case ',':
+ *curr = getchar();
+ break;
+ case '[':
+ if (*curr) {
+ push(&open_brackets, ftell(source));
+ }
+ else {
+ int counter = 1;
+ while (counter > 0 && !feof(source)) {
+ c = fgetc(source);
+ if (c == '[') counter++;
+ else if (c == ']') counter--;
+ }
+ if (feof(source)) {
+ printf("Error: Can't find matching ']' at line %d\n", lineNr);
+ exit = 1;
+ }
+ }
+ break;
+ case ']':
+ if (*curr && open_brackets) {
+ fseek(source, open_brackets->data, SEEK_SET);
+ }
+ else if (open_brackets){
+ pop(&open_brackets);
+ }
+ else {
+ printf("Error: Can't find matching '[' at line %d\n", lineNr);
+ exit = 1;
+ }
+ }
+ }
+ if (open_brackets) {
+ lineNr = 1;
+ rewind(source);
+ while (ftell(source) != open_brackets->data) {
+ if (fgetc(source) == '\n') lineNr++;
+ }
+ printf("Error: Can't find matching ']' at line %d\n", lineNr);
+ while (open_brackets) pop(&open_brackets);
+ exit = 1;
+ }
+ fclose(source);
+ return exit;
+}
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..97f942e
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,11 @@
+Beef
+====
+
+Brainfuck interpreter
+---------------------
+
+Usage: beef [file]
+
+Brainfuck is a turing-complete minimalist esoteric language created by Urban Müller.
+
+More info here https://en.wikipedia.org/wiki/Brainfuck
diff --git a/test.bf b/test.bf
new file mode 100644
index 0000000..07f6663
--- /dev/null
+++ b/test.bf
@@ -0,0 +1,20 @@
+Prints hello in an endless loop
+++++ ++++ ++
+[
+ [
+ >++++ +++
+ <-
+ ]
+ >++.
+ <++++ ++++ ++
+ [
+ >+++
+ <-
+ ]
+ >-.
+ ++++ +++
+ ..
+ +++.
+ [-]
+ <++++ ++++ ++.
+]