Вступление
Сидел я тут как-то вечером и думал, что можно такое интересное написать на Python’е и тут я вспомнил, что когда-то давно, ещё на C#, пытался написать интерпретатор какого-нибудь простого языка, того же BASIC например, но особо ничего не получалось. В момент этих попыток я наткнулся на ��акой язык, как Brainfuck. Сейчас я решил написать интерпретатор именно этого языка, так как он является одновременно простым для написания и сложным для понимания))
О самом языке
Brainfuck – по истине мозговыносящий (и это ещё мягко сказано) эзотерический язык программирования (нестандартный язык, который создаётся с целью развлечения или исследования особенностей программирования. Он обычно имеет необычный синтаксис и принципы работы, что делает его сложным для понимания и использования в реальных проектах).
Он имеет всего 8 простых команд:
Команда | Описание |
> | Следующая ячейка |
< | Предыдущая ячейка |
+ | Значение текущей ячейки увеличивает на 1 |
- | Значение текущей ячейки уменьшают на 1 |
. | Напечатать значение из текущей ячейки |
, | Ввести извне значение и сохранить в текущей ячейке |
[ | Начало цикла |
] | Конец цикла |
Как всё писалось?
Я начал смотреть видеоролики, просматривал статью на Википедии, чтобы понять, что это за язык и с чем его едят)) Это оказалось не таким уж лёгким занятием, но я справился.
Как только я создал проект, я начал с создания класса Pyfuck, в который добавлял следующие функции:
Функция инициализации:
def __init__(self): self.memory = [0] * 30000 # Память для хранения данных self.pointer = 0 # Указатель текущей ячейки памяти self.output = "" # Результирующая строка
Интерпретатор имеет память под 30.000 однобайтовых ячеек с нулевыми начальными значениями (всё, как в оригинальном Brainfuck).
Имеется указатель текущей ячейки памяти (его переключение осуществляется с помощью команд > и < в коде программы) и результирующая строка (она выводит итоговый результат программы).
Следующей является функция интерпретации:
def interpret(self, program): self.output = "" for i in range(len(program)): command = program[i] if command == ">": # Следующая ячейка self.pointer += 1 elif command == "<": # Предыдущая ячейка self.pointer -= 1 elif command == "+": # Значение текущей ячейки увеличивает на 1 self.memory[self.pointer] += 1 elif command == "-": # Значение текущей ячейки уменьшают на 1 self.memory[self.pointer] -= 1 elif command == ".": # Напечатать значение из текущей ячейки self.output += chr(self.memory[self.pointer]) elif command == ",": # Ввести извне значение и сохранить в текущей ячейке input_value = input("Введите значение: ") if len(input_value) <= 1: self.memory[self.pointer] = ord(input_value) else: return elif command == "[": # Начало цикла if self.memory[self.pointer] == 0: nested = 1 while nested > 0: i += 1 if program[i] == "[": nested += 1 elif program[i] == "]": nested -= 1 elif command == "]": # Конец цикла if self.memory[self.pointer] != 0: nested = 1 while nested > 0: i -= 1 if program[i] == "]": nested += 1 elif program[i] == "[": nested -= 1 else: print("Ошибка: неизвестная команда!") return self.output
В цикле for происходит итерация по каждой команде программы. В зависимости от команды выполняются различные действия: перемещение указателя на следующую или предыдущую ячейку памяти, увеличение или уменьшение значения текущей ячейки, печать символа из текущей ячейки памяти и считывание введённого значения в текущую ячейку.
Также реализована поддержка циклов: если значение текущей ячейки равно 0, программа пропускает все команды до соответствующей закрывающей скобки. Если же значение текущей ячейки памяти не равно 0, то происходит возврат к соответствующей открывающей скобке, чтобы продолжить выполнение цикла.
Как составляется программа?
Тут всё довольно интересно) Для составления программ удобно использовать таблицу символов ASCII:

Мы должны обратить внимание на Decimal (это число, которое соответствует определённому символу. Это десятичное представление числа символа в таблице ASCII. Например, символ «A» имеет значение 65 в ASCII). В Brainfuck это будет выглядеть, как 65 команд «+».
Вот приме�� программы, печатающая «Hello World!»:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++++++++.+++++++..+++.>++++++++++++++++++++++++++++++++.<------------------------.++++++++++++++++++++++++.+++.------.--------.>+.

Заключение
Я хотел бы подчеркнуть, что написание данного интерпретатора было интересным и познавательным опытом. Это позволило мне лучше понять работу простых языков программирования и тонкости их реализации. Полученный интерпретатор может быть полезен для изучения и демонстрации возможностей Brainfuck, а также в качестве инструмента для выполнения простых задач на этом языке.
Полный код можно посмотреть на моём GitHub.
С вами был Yura_FX. Спасибо, что дочитали данную статью до конца. Не забывайте делиться своим мнением в комментариях :)
