Մասնակից:Fperson/Ավազարկղ1
Brainfuck, 1993 թվականին Ուրբան Մյուլերի (գերմ.՝ Urban Müller) կողմից ստեղծված ամենահայտնի էզոտերիկ ծրագրաբորման լեզուներից մեկը, որը հայտնի է իր մինիմալիզմով: Լեզվի անվանումը հայերեն կարելի է թարգմանել՝ որպես ուղեղի բռնաբարում, ինչը ուղղակիորեն ծագել է անգլերեն brainfuck (brain՝ ուղեղ, fuck՝ սեռական հարաբերություն ունենալ) արտահայտությունից, այսինքն՝ անհեթեթությամբ զբաղվել: Լեզուն ունի ութ հրաման, որոնցից յուրաքանչյուրը գրառվում է մեկ սիմվոլով: Brainfuck-ի ելքային կոդը իրենից ներկայացնում է այդ սիմվոլների հերթականությունը՝ առանց որևէ լրացուցիչ շարահյուսության։
Ուրբան Մյուլերի հիմնական դրդապատճառներից մեկը եղել է հնարավորինս փոքր կոմպիլյատորով ծրագրավորման լեզվի ստեղծումը։ Մասամբ նա ոգեշնչված է եղել FALSE ծրագրավորման լեզվով, որի համար գոյություն ուներ 1024 բայթ չափսով կոմպիլյատոր։ Brainfuck-ի համար գոյություն ունեն 200 բայթից ավելի քիչ չափսով կոմպիլյատորներ[1]։ Brainfuck լեզվով դժվար է ծրագրեր գրել, ինչի համար երբեմն այն անվանում են մազոխիստների լեզու։ Միևնույն ժամանակ պետք է նշել, որ Brainfuck-ը բոլորովին բնական, լիակատար ու հասարակ լեզու է և կարող է օգտագործվել հաշվարկվածության հասկացության սահնանման համար։
Մեքենան, որը կառավարում են Brainfuck-ի հրամանները, բաղկացած է Թյուրինգի մեքենայի ժապավենն ու գլխիկը հիշեցնող բջիջների կարգավորված հավաքածույից և տվյալ բջջի ցուցիչից: Բացի այդ, ենթադրվում է ներմուծման և արտածման հոսքերի միջոցով արտաքին աշխարհի հետ շփման սարք:
Brainfuck լեզուն կարելի է նկարագրել C լեզվի համարժեքների միջոցով՝
Brainfuck-ի հրաման | C-ի համարժեք | Հրամանի նկարագրում |
---|---|---|
Ծրագրի սկիզբ | int i = 0; |
выделяется память под 30 000 ячеек с нулевыми начальными значениями |
> |
i++; |
անցնել հաջորդ բջջին |
< |
i--; |
անցնել նախորդ բջջին |
+ |
arr[i]++; |
տվյալ բջջի արժեքը ավելացնել մեկով |
- |
arr[i]--; |
տվյալ բջջի արժեքը նվազեցնել մեկով |
. |
putchar(arr[i]); |
տպել տվյալ բջջի արժեքը |
, |
arr[i] = getchar(); |
ввести извне значение и сохранить в текущей ячейке |
[ |
while(arr[i]){ |
если значение текущей ячейки ноль, перейти вперёд по тексту программы на ячейку, следующую за соответствующей ] (с учётом вложенности) |
] |
} |
если значение текущей ячейки не нуль, перейти назад по тексту программы на символ [ (с учётом вложенности) |
Չնայած արտաքին պարզությանը՝ բջիջների անսահման թվով Brainfuck-ը ունի Թյուրինգի լիություն, հետևաբար՝ Несмотря на внешнюю примитивность, Brainfuck с бесконечным набором ячеек имеет тьюринговскую полноту, а, следовательно, по потенциальным возможностям не уступает «настоящим» языкам, подобным Си, Паскалю или Java.
Brainfuck подходит для экспериментов по генетическому программированию из-за простоты синтаксиса, и, соответственно, генерации исходного кода.
В «классическом» Brainfuck, описанном Мюллером, размер ячейки — один байт, количество ячеек 30 000. В начальном состоянии указатель находится в крайней левой позиции, а все ячейки заполнены нулями. Увеличение/уменьшение значений ячеек происходит по модулю 256. Ввод-вывод также происходит побайтно, с учётом кодировки ASCII (то есть в результате операции ввода (,) символ 1 будет записан в текущую ячейку как число 0x31 (49), а операция вывода (.), совершённая над ячейкой, содержащей 0x41 (65), напечатает латинскую А). В других вариантах языка размер и количество ячеек может быть другим (бо́льшим). Есть версии, где значение ячеек не целочисленно (с плавающей точкой).
Ծրագրի օրինակ
խմբագրել- Brainfuck֊ով գրված ծրագիր, որն արտածում է «Hello World!»՝
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++
.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.
------.--------.>+.>.
Разбор программы:
Подготовка в памяти (с ячейки 1) массива значений, близких к ASCII-кодам символов, которые необходимо вывести (70, 100, 30, 10), через повторение 10 раз приращения ячеек на 7, 10, 3 и 1, соответственно | ||
++++++++++ |
присваивание ячейке 0 (счетчику) значения 10 | |
[ |
повторять, пока значение текущей ячейки (ячейки 0) больше нуля | |
>+++++++ |
приращение ячейки 1 на 7 | |
>++++++++++ |
приращение ячейки 2 на 10 | |
>+++ |
приращение ячейки 3 на 3 | |
>+ |
приращение ячейки 4 на 1 | |
<<<<- |
возврат к ячейке 0 (счетчику), и его уменьшение на 1 | |
] |
вернуться к началу цикла | |
Տառերի կոդերի ստացում և դրանց արտածում | ||
>++. |
Вывод «Н». Получение кода «H» (72) из 70 в ячейке 1 и вывод | |
>+. |
Вывод «e». Получение кода «e» (101) из 100 в ячейке 2 и вывод | |
+++++++.. |
Вывод «ll». Получение кода «l» (108) из 101 в ячейке 2 и вывод дважды | |
+++. |
Вывод «o». Получение кода «o» (111) из 108 в ячейке 2 и вывод | |
>++. |
Вывод пробела. Получение кода пробела (32) из 30 в ячейке 3 и вывод | |
<<+++++++++++++++. |
Вывод «W». Получение кода «W» (87) из 72 в ячейке 1 и вывод | |
>. |
Вывод «o». Код «o» (111) уже находится в ячейке 2, просто его выводим | |
+++. |
Вывод «r». Получение кода «r» (114) из 111 в ячейке 2 и вывод | |
------. |
Вывод «l». Получение кода «l» (108) из 114 в ячейке 2 и вывод | |
--------. |
Вывод «d». Получение кода «d» (100) из 108 в ячейке 2 и вывод | |
>+. |
Вывод «!». Получение кода «!» (33) из 32 в ячейке 3 и вывод | |
>. |
Вывод кода перевода строки (10) из ячейки 4 |
В принципе, печать «Hello World!» можно реализовать проще, но программа будет в три с лишним раза больше, чем приведённый выше оптимизированный вариант:
+++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++.+++++++++++++++++
++++++++++++.+++++++..+++.-------------------
---------------------------------------------
---------------.+++++++++++++++++++++++++++++
++++++++++++++++++++++++++.++++++++++++++++++
++++++.+++.------.--------.------------------
---------------------------------------------
----.-----------------------.
Brainfuck֊ի ինտերպրետատոր
խմբագրելПример интерпретатора Brainfuck, написанный на языке Perl
#!/usr/bin/perl
open F, shift;
@code = grep {/[+-\.,\[\]><]/} split '', <F>;
for (my $_ = 0; $_ < @code; ++$_) {
++$cpu[$i] if $code[$_] eq '+';
--$cpu[$i] if $code[$_] eq '-';
--$i if $code[$_] eq '<';
++$i if $code[$_] eq '>';
print chr $cpu[$i] if $code[$_] eq '.';
$cpu[$i] = ord <STDIN> if $code[$_] eq ',';
if ($code[$_] eq '[') {
if (!$cpu[$i]) {
++$brc;
while ($brc) {
++$_;
++$brc if $code[$_] eq '[';
--$brc if $code[$_] eq ']';
}
} else {
next;
}
} elsif ($code[$_] eq ']') {
if (!$cpu[$i]) {
next;
} else {
++$brc if $code[$_] eq ']';
while ($brc) {
--$_;
--$brc if $code[$_] eq '[';
++$brc if $code[$_] eq ']';
}
--$_;
}
}
}
Пример интерпретатора Brainfuck, написанный на языке C++
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
static char cpu[30000];
int main(int argc, char **argv) {
vector<char> acc;
char ch;
ifstream infile(argv[1]);
while (infile) {
infile.get(ch);
acc.push_back(ch);
}
infile.close();
unsigned int j = 0;
int brc = 0;
for (int i = 0; i < acc.size(); ++i) {
if (acc[i] == '>')
j++;
if (acc[i] == '<')
j--;
if (acc[i] == '+')
cpu[j]++;
if (acc[i] == '-')
cpu[j]--;
if (acc[i] == '.')
cout << cpu[j];
if (acc[i] == ',')
cin >> cpu[j];
if (acc[i] == '[') {
if (!cpu[j]) {
++brc;
while (brc) {
++i;
if (acc[i] == '[')
++brc;
if (acc[i] == ']')
--brc;
}
} else
continue;
} else if (acc[i] == ']') {
if (!cpu[j])
continue;
else {
if (acc[i] == ']')
brc++;
while (brc) {
--i;
if (acc[i] == '[')
brc--;
if (acc[i] == ']')
brc++;
}
--i;
}
}
}
}
Программирование на языке Brainfuck
խմբագրելКаждый начинающий программировать на Brainfuck немедленно сталкивается со следующими проблемами:
- отсутствие операции копирования значения
- отсутствие промежуточной (аккумуляторной) памяти
- отсутствие условных операторов в их привычном виде
- отсутствие привычной арифметики, операций умножения и деления
Эти проблемы могут быть решены.
Обозначим через @(k) сдвиг на k ячеек вправо, если k>0, и влево, если k<0 Соответственно, @(k) = >…k раз…> либо <…-k раз…<
zero(): обнуление текущей ячейки: [-] = [+]
add(k): прибавление значения ячейки n (текущей) к значению ячейки n+k: [ — @(k) + @(-k) ] при этом значение ячейки n теряется (обнуляется).
mov(k): копирование значения ячейки n (текущей) в ячейку n+k с потерей (обнулением) значения ячейки n: @(k) zero() @(-k) add(k) = @(k) [-] @(-k) [ — @(k) + @(-k) ]
copy(k,t): копирование значения ячейки n (текущей) в ячейку n+k c использованием промежуточной ячейки n+k+t, благодаря чему значение ячейки n не теряется (сохраняется). @(k) zero() @(t) zero() @(-k-t) [ — @(k) + @(t) + @(-k-t) ] @(k+t) mov(-k-t) = @(k) [-] @(t) [-] @(-k-t) [ — @(k) + @(t) + @(-k-t) ] @(k+t) [ — @(-k-t) + @(k+t) ]
ifelse(t): если текущая ячейка>0, то выполняется условие true если текущая ячейка=0, то выполняется условие false t-относительный номер вспомогательной ячейки: @(t)[-]+@(-t) устанавливаем флаг 1 для случая else [ здесь действия ветки true @(t)[-]@(-t) устанавливаем флаг 0 для случая else [-] выход из цикла ] @(t) [@(-t) здесь действия ветки false @(t)[-] выход из цикла ] @(-t-1)
Brainfuck почти не используется для практического программирования (за исключением работ отдельных энтузиастов), а используется преимущественно для головоломок и задач для соревнований.
Brainfuck֊ի հիման վրա ստեղծված լեզուներ
խմբագրելԿաղապար:Highlight1 |Ook! | Կաղապար:Highlight1 |COW | Կաղապար:Highlight1 |Brainfuck | Կաղապար:Highlight1 |Описание |
Ook. Ook. | MoO | + | Значение текущей ячейки увеличивает на 1 |
Ook! Ook! | MOo | - | Значение текущей ячейки уменьшают на 1 |
Ook. Ook? | moO | > | Следующая ячейка |
Ook? Ook. | mOo | < | Предыдущая ячейка |
Ook! Ook? | moo | [ | Начало цикла |
Ook? Ook! | MOO | ] | Конец цикла |
Ook! Ook. | OOM | . | Вывод значения текущей ячейки |
Ook. Ook! | oom | , | Запрос значения текущей ячейки |
mOO | отсутствует | Выполняет инструкцию с номером, который берётся из текущей ячейки (если значение в текущей ячейке равно 3, то это приводит к бесконечному циклу). | |
Moo | отсутствует | Если значение текущей ячейки равно нулю, то ввести его с клавиатуры; если же значение текущей ячейки — не ноль, то вывести его на экран. | |
OOO | [-] | Обнуляет значение в текущей ячейке | |
MMM | отсутствует |
Տես նաև
խմբագրելДиалекты и реализации
խմբագրելЕщё описание множества диалектов этого языка можно найти в вики-энциклопедии эзотерических языков[2]
Ծանոթաագրություններ
խմբագրել- ↑ Например, «исходник компилятора размером 166 байт». Արխիվացված է օրիգինալից 2011-08-25-ին. Վերցված է 2010-08-18-ին.
{{cite web}}
: Unknown parameter|deadurl=
ignored (|url-status=
suggested) (օգնություն) - ↑ Category:Brainfuck_derivatives, esolangs.org
Արտաքին հղումներ
խմբագրել- Немного о brainfuck на русском языке и пара инструментов для работы с ним
- Оригинальное описание BF на английском языке и ссылки на BF-ресурсы
- Brainfuck interpreter with integrated debugger (IDE) for Windows
- Կաղապար:Lj comm — русское ЖЖ-сообщество любителей эзотерических языков
- статья на rsdn.ru об эзотерических языках программирования
- Processing_BF — оптимизирующий интерпретатор и транслятор в PHP, написанный на языке PHP
- BrainfuckInterpreter — кроссплатформенный оптимизирующий интерпретатор на Java, переехал на Brainfuck Interpreter bfrun
- esco — универсальный интерпретатор эзотерических языков
- Интерпретатор brainfuck на JavaScript с открытым исходным кодом
- Переводчик с brainfuck на Perl и обратно с открытым исходным кодом
- Интерпретатор brainfuck с открытым исходным кодом
- Статья о создании транслятора brainfuck в C
- The Brainfuck Archive
- Brainfuck on the Esolang (Esoteric Languages) wiki
- Visual brainfuck, a brainfuck IDE compatible with Windows 7 x86 and x64.
- Brainfuck Developer, Brainfuck IDE for Windows (also works with WINE under Linux)
- Fperson/Ավազարկղ1 հոդվածը Curlie-ում (ըստ DMOZ-ի)
- bf2c, a Brainfuck to C translator.
- ookie, a Brainfuck and Ook! language interpreter
- Ook.jar, another Ook! and Brainfuck language interpreter, this time written in Java.
- BrainForce, compiler (wrap gcc) and C translator (has lots of options to control wrapping values, cell sizes, etc.)
- esolang, a Brainfuck interpreter for iPhone written in objective c.
- Le Brainfuck, a Javascript based optimizing interpreter. Also has many options, including memory dumping.
- Brainfuck C, a lightweight Brainfuck interpreter written in C.
- Brainfuck Java, an interpreter for the Brainfuck language and its dialects written in the Java programming language.
- lex/yacc-based Brainfuck interpreter in C and Python
- Bfck, open-source Brainfuck interpreter written in C.
|