txlyre 1 年之前
父節點
當前提交
9a6266c516
共有 3 個文件被更改,包括 157 次插入0 次删除
  1. 7 0
      langs/bf/Dockerfile
  2. 145 0
      langs/bf/bf.c
  3. 5 0
      langs/bf/run.sh

+ 7 - 0
langs/bf/Dockerfile

@@ -0,0 +1,7 @@
+RUN apt-get install gcc -y
+COPY bf/bf.c .
+RUN gcc -o bf bf.c
+RUN rm bf.c
+RUN chmod +x /usr/bin/bf
+RUN chmod 705 /usr/bin/bf
+RUN apt-get remove gcc -y

+ 145 - 0
langs/bf/bf.c

@@ -0,0 +1,145 @@
+/* https://codeberg.org/milofultz/brainfuck */
+
+#include <stdbool.h>
+#include <stdio.h>
+
+#define BYTE_LIMIT 255
+#define MAX_SIZE 65535
+
+void increment(int *ptr, int max) {
+    if (*ptr == max) {
+        *ptr = 0;
+    } else {
+        (*ptr)++;
+    }
+};
+
+void decrement(int *ptr, int max) {
+    if (*ptr == 0) {
+        *ptr = max;
+    } else {
+        (*ptr)--;
+    }
+}
+
+void outputByte(int *ptr) {
+    printf("%c", *ptr);
+}
+
+void inputByte(int *ptr) {
+    *ptr = getchar();
+}
+
+int main (int argc, char *argv[]) {
+    int dataPointer;
+    int data[MAX_SIZE];
+    int instructionPointer;
+    char instruction[MAX_SIZE];
+    int bracketCounter;
+    int i;
+    char c;
+    FILE *f;
+
+    if (argc < 2) {
+        puts("No filename provided for input.");
+        return 1;
+    }
+
+    f = fopen(argv[1], "r");
+
+    // Zero out all memory in all arrays
+    for (i = 0; i < MAX_SIZE; i++) {
+        data[i] = 0;
+        instruction[i] = '\0';
+    }
+
+    // Load all commands into memory
+    instructionPointer = 0;
+    while ((c = fgetc(f)) != EOF) {
+        instruction[instructionPointer] = c;
+        instructionPointer++;
+    }
+
+    fclose(f);
+
+    dataPointer = 0;
+    instructionPointer = 0;
+    bracketCounter = 0;
+
+    while ((c = instruction[instructionPointer]) != '\0') {
+        switch (c) {
+            case '>':
+                increment(&dataPointer, MAX_SIZE);
+                break;
+            case '<':
+                decrement(&dataPointer, MAX_SIZE);
+                break;
+            case '+':
+                increment(&data[dataPointer], BYTE_LIMIT);
+                break;
+            case '-':
+                decrement(&data[dataPointer], BYTE_LIMIT);
+                break;
+            case '.':
+                outputByte(&data[dataPointer]);
+                break;
+            case ',':
+                inputByte(&data[dataPointer]);
+                break;
+            case '[':
+                if (data[dataPointer] == 0) {
+                    instructionPointer++;
+
+                    while (true) {
+                        c = instruction[instructionPointer];
+
+                        if (c == EOF) {
+                            fputs("Unmatched brackets", stderr);
+                            return 1;
+                        }
+
+                        if (c == ']' && bracketCounter == 0) {
+                            break;
+                        } else if (c == ']') {
+                            bracketCounter--;
+                        } else if (c == '[') {
+                            bracketCounter++;
+                        }
+
+                        instructionPointer++;
+                    }
+                }
+                break;
+            case ']':
+                if (data[dataPointer] != 0) {
+                    instructionPointer--;
+
+                    while (true) {
+                        c = instruction[instructionPointer];
+
+                        if (c == '[' && bracketCounter == 0) {
+                            break;
+                        } else if (c == '[') {
+                            bracketCounter--;
+                        } else if (c == ']') {
+                            bracketCounter++;
+                        }
+
+                        instructionPointer--;
+
+                        if (instructionPointer == -1) {
+                            fputs("Unmatched brackets", stderr);
+                            return 1;
+                        }
+
+                        continue;
+                    }
+                }
+                break;
+        }
+        instructionPointer++;
+    }
+
+    return 0;
+}
+

+ 5 - 0
langs/bf/run.sh

@@ -0,0 +1,5 @@
+#!/usr/bin/bash
+
+IN="$(mktemp --suffix .b)"
+
+bf "$IN"