BrainF*ck
Принцип разнообразия присутствует всюду. Языки программирования не исключение. Есть, например, такие языки, которые в повседневной жизни мало используются и существуют забавы ради. Такие языки программирования называются эзотерическими. Так в далеком 1993 году некий Urban Müller решил создать свой язык программирования с компилятором минимального размера. Давайте посмотрим, что у него из этого получилось.
Имя у этого языка BrainFuck. Компилятор получился действительно маленький, размер первой версии 240 байт. Вторая версия после ряда улучшений составила всего 200 байт.
Так что же он может? Может он немногое. Всего 8 команд-символов. Но, тем не менее, этот язык имеет тьюринговскую полноту.
| BrainFuck | С++ | Описание |
| > | ++p; | Сдвинуть указатель вправо |
| < | --p; | Сдвинуть указатель влево |
| + | ++*p; | Увеличить значение байта на 1 |
| - | --*p; | Уменьшить значение байта на 1 |
| . | putchar(*p); | Вывести символ |
| , | *p = getchar(); | Ввести символ |
| [ | while (*p) { | Цикл с предусловием «Пока под указателем не ноль» |
| ] | } | Конец цикла с предусловием |
Суть такова. Программа имеет массив байтов [0..30000] и указатель установленный на нулевой байт массива. Входные и выходные данные являются символами кодовой таблицы ASCII. Все предельно просто. Предлагаю рассмотреть классическую программу "Hello World!":
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Думаю, теперь вы понимаете, почему зверек так называется. Давайте вместе разберемся, что тут к чему. Начало ++++++++++ увеличивает содержимое нулевого байта памяти до 10. Это будет счётчик повторений цикла. Далее [ начинает цикл и > сдвигает указатель вправо. Теперь указатель указывает на следующий байт памяти, плюсами накручивается его значение, и так выставляются ещё несколько байтов. Серия команд <<<<- возвращает указатель на счетчик повторений цикла и уменьшает его на единицу. После работы цикла (всех десяти итераций) первые пять байт памяти будут выглядеть так: 0, 70, 100, 30, 10. Идем далее. Серия >++. смещает указатель на байт со значением 70, увеличивает его на два и выводит символ из таблицы ASCII с кодом 72 – «H». Далее из 100 получаются коды букв «e», «l» и «o» (101, 108 и 111). Серия .. выводит на экран две буквы «l». Затем из 30 делается пробел (код 32), из байта с буквой «H» делается «W», и остальные символы получаются на базе этих же четырёх байтов. Последнее >. выводит код 0 (видимо, как признак конца строки). Вот собственно и все!
Предлагаю читателю реализовать следующие программы на языке BrainFuck:
- умножение числа на число
- возведение числа в куб
- деление на два
- программу, печатающую на экран свой исходный код.