Сегодня разберем как программировать на самом лучшем эзотерическим языке программирования, а именно BrainFuck.
[spoiler]
Немного истории
BrainFuck дословно переводится как "еб**ь мозг" =) из за названия он не очень популярен, а так его можно было бы использвать в школах, дабы преподать людям основы основ. BrainFuck придумал Урбаном Мюллером (нем) в 2003 году. Сейчас это самый популярный эзотерический язык программирования. BrainFuck предстовляет собой только 8 команд, и этого достаточно что бы написать любую программу как и на С++, это как раз минимальный набор для языка.
Об языке
Как говорилось ранее язык имеент всего лишь 8 комманд.
> ----------------перейти к следующей ячейке
< ----------------перейти к предыдущей ячейке
+ ----------------увеличить значение в текущей ячейке на 1
- ----------------уменьшить значение в текущей ячейке на 1
. ----------------напечатать значение из текущей ячейки
, ----------------ввести извне значение и сохранить в текущей ячейке
[ ----------------если значение текущей ячейки нуль, перейти вперёд по тексту программы на ячейку, следующую за соответствующей ] (с учётом вложенности)
] ----------------если значение текущей ячейки не нуль, перейти назад по тексту программы на символ [ (с учётом вложенности)
Как вы уже заметили, что статья находится в разделе C++, не странно ли, нет, так как сдесь пойдет речь именно о С++, а именно написания интерпретатора к BrainFuck. Почему? Просто в BrainFuck всего лишь 8 комманд и пишется все это очень быстро.
Начнем
Нам потребуется только ввод-вывод и чтение исходника, для этого подойдут iostream и fstream, так что подключаем их
/*http://esate.ru, isaer*/
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char** argv)
{
}
А теперь не будем замарачиваться какими то замудренными паттернами и тд а просто через switch перебираем наши комманды, читаем первую комманду и начинаем перебирать:
/*http://esate.ru, isaer*/
file >> c;
while(!(file.eof()))
{
switch(c)
{
case '>': break;
case '<': break;
case '+': break;
case '-': break;
case '.': break;
case ',': break;
case '[': break;
case ']': break;
default: break;
}
file >> c;
}
переменная b будет отвечать за выполнение комманд переменная a хранит в себе ячейки значений переменная c хранит в себе текущую комманду переменная file содержит поток исходника
Теперь приступим к заполнению реакций на команду
> < Этими командами мы перемещаемся в ячейках, реализуем их
/*http://esate.ru, isaer*/
b++;
и
/*http://esate.ru, isaer*/
b--;
все очень просто, b у нас держит адрес первого элемента массива, и если прибавить еденицу то он переместится к следующиму, а если отнять еденицу то переместся к предыдущей (я не делаю проверку на выход за массив, хотя вы можете реализовать)
+ - Эти команды изменяют значение текущей ячейки, реализуется тоже очень просто
/*http://esate.ru, isaer*/
(*b)--;
и
/*http://esate.ru, isaer*/
(*b)++;
Сначало разименовываем а потом прибавляем к текущему значению еденицу. Скобочки нужны обязательно так как приоритет у инкрементов больше чем у разименовывания.
. , Вывод -
/*http://esate.ru, isaer*/
cout << *c;
Ввод -
/*http://esate.ru, isaer*/
cin >> *c;
тоже все просто, разименовываем и записываем в ячейку.
[ ] ну и наконец то циклы, тоже ничего сложного не прелставляют, как они работают можно почитать выше
тут мы смотрим, если значение равно 0 то пропускаем все что находится между [] n - уровень вложения
Конец цикла-
/*http://esate.ru, isaer*/
int n = 1;
if((*b) != 0)
while(n != 0)
{
int k = file.tellg();
file.seekg(k - 2);
file >> c;
if(c == ']')
n++;
else if(c == '[')
n--;
}
сдесь все тоже самое, нашли закрывающуюся скобку, перемещаямся на 2 позиции назад, читаем символ, если закрывающая скобка то прибавляем вложение если открывающаяся то убавляем
Вот и все, 8 комманд, теперь компилируем и смотрим выполнение примера
сдесь не применяются ячейки, про них может позже стандартная ячейка стоит 0 и все изменения применяются к ней вначале мы прибавляем 69 и выводим на экран, это получается большое E (69) дальше прибавляем 46 и выводим получаем s(115), потом отнимаем от 115 18 и выводим получаем a(97) и так далее и получаем на выходе Esate.ru и новоя строчка (10) таблицу можно посмотреть тут
В примере выше, где hello world там используются ячейки, можете поизучать.
Заключение
Есть еще такой язык pbrain там все тоже самое только добавлены 3 комманды - ( ) : () - открытие закрытие функции : - вызов функции
Ну вот и все, жду ваших интересных программ на BrainFuck =)
Понравилась публикация? Сохраните ее, чтобы вернуться к изучению материала!
Жесткий язык!=) Наверное пока не решусь воспользоваться), сильно сложно, лучше буду вводить команды ассемблера Нex-ами)))) так хоть мозг цел будет=)))) Супер!!! +1 к статьи, только плиз мат убери=) это как раз минимальный набор бля(для) языка))
Наверное пока не решусь воспользоваться), сильно сложно, лучше буду вводить команды ассемблера Нex-ами)))) так хоть мозг цел будет=))))
Супер!!!
+1 к статьи, только плиз мат убери=)
это как раз минимальный набор бля(для) языка))