bf.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /* https://codeberg.org/milofultz/brainfuck */
  2. #include <stdbool.h>
  3. #include <stdio.h>
  4. #define BYTE_LIMIT 255
  5. #define MAX_SIZE 65535
  6. void increment(int *ptr, int max) {
  7. if (*ptr == max) {
  8. *ptr = 0;
  9. } else {
  10. (*ptr)++;
  11. }
  12. };
  13. void decrement(int *ptr, int max) {
  14. if (*ptr == 0) {
  15. *ptr = max;
  16. } else {
  17. (*ptr)--;
  18. }
  19. }
  20. void outputByte(int *ptr) {
  21. printf("%c", *ptr);
  22. }
  23. void inputByte(int *ptr) {
  24. *ptr = getchar();
  25. }
  26. int main (int argc, char *argv[]) {
  27. int dataPointer;
  28. int data[MAX_SIZE];
  29. int instructionPointer;
  30. char instruction[MAX_SIZE];
  31. int bracketCounter;
  32. int i;
  33. char c;
  34. FILE *f;
  35. if (argc < 2) {
  36. puts("No filename provided for input.");
  37. return 1;
  38. }
  39. f = fopen(argv[1], "r");
  40. // Zero out all memory in all arrays
  41. for (i = 0; i < MAX_SIZE; i++) {
  42. data[i] = 0;
  43. instruction[i] = '\0';
  44. }
  45. // Load all commands into memory
  46. instructionPointer = 0;
  47. while ((c = fgetc(f)) != EOF) {
  48. instruction[instructionPointer] = c;
  49. instructionPointer++;
  50. }
  51. fclose(f);
  52. dataPointer = 0;
  53. instructionPointer = 0;
  54. bracketCounter = 0;
  55. while ((c = instruction[instructionPointer]) != '\0') {
  56. switch (c) {
  57. case '>':
  58. increment(&dataPointer, MAX_SIZE);
  59. break;
  60. case '<':
  61. decrement(&dataPointer, MAX_SIZE);
  62. break;
  63. case '+':
  64. increment(&data[dataPointer], BYTE_LIMIT);
  65. break;
  66. case '-':
  67. decrement(&data[dataPointer], BYTE_LIMIT);
  68. break;
  69. case '.':
  70. outputByte(&data[dataPointer]);
  71. break;
  72. case ',':
  73. inputByte(&data[dataPointer]);
  74. break;
  75. case '[':
  76. if (data[dataPointer] == 0) {
  77. instructionPointer++;
  78. while (true) {
  79. c = instruction[instructionPointer];
  80. if (c == EOF) {
  81. fputs("Unmatched brackets", stderr);
  82. return 1;
  83. }
  84. if (c == ']' && bracketCounter == 0) {
  85. break;
  86. } else if (c == ']') {
  87. bracketCounter--;
  88. } else if (c == '[') {
  89. bracketCounter++;
  90. }
  91. instructionPointer++;
  92. }
  93. }
  94. break;
  95. case ']':
  96. if (data[dataPointer] != 0) {
  97. instructionPointer--;
  98. while (true) {
  99. c = instruction[instructionPointer];
  100. if (c == '[' && bracketCounter == 0) {
  101. break;
  102. } else if (c == '[') {
  103. bracketCounter--;
  104. } else if (c == ']') {
  105. bracketCounter++;
  106. }
  107. instructionPointer--;
  108. if (instructionPointer == -1) {
  109. fputs("Unmatched brackets", stderr);
  110. return 1;
  111. }
  112. continue;
  113. }
  114. }
  115. break;
  116. }
  117. instructionPointer++;
  118. }
  119. return 0;
  120. }