Brainfuck

De la Wikipedia, enciclopedia liberă
Salt la: Navigare, căutare

Brainfuck este un limbaj de programare esoteric, cunoscut pentru simplitatea acestuia.

Acest limbaj de programare a fost creat de către programatorul Urban Müller, pentru a pune la încercare acesta neavând nicio aplicație practică. Forme populare de cenzurare fiind brainf***, brainf*ck, brainfsck, b****fuck sau BF. Numele limbajului nu este în general scris cu literă mare, exceptând situația când acesta se afla la începutul propoziției, deși este un substantiv propriu.

Designul limbajului[modificare | modificare sursă]

Urban Müller, inspirat de compilatorul limbajului FALSE, care avea 1024 biți lungime, a creat brainfuck în 1993 cu intenția de a face un limbaj de programare ce putea fi implementat cu cel mai mic compilator posibil. Limbajul prezintă 8 comenzi("<",">","+","-") restul caracterelor fiind ignorate. Un program brainfuck este o secvență de comenzi, acestea fiind citite de la stânga la dreapta și de sus în jos. Programul se termină după ce ajunge la ultima comandă.

Limbajul brainfuck folosește un model simplu reprezentat de programul propriu-zis, un contor al instrucțiunilor (pointer) și un vector de cel puțin 30000 de octeți lungime, având elementele cu valoarea inițală zero și două stream-uri (în general - cel de intrare și cel de ieșire).

Comenzi[modificare | modificare sursă]

Cele opt comenzi, fiecare reprezentată de un caracter:

Caracter Ce acțiune realizează
> trece la elementul din dreapta
< trece la elementul din stânga
+ incrementează valoarea elementului curent
- decrementează valoarea elementului curent
. afișează caracterul ASCII corespunzător valorii elementului curent (sau la unele interpretoare - valoarea numerică a elementului curent)
, citește un caracter (sau la unele interpretoare, un număr) și îl stochează în elementul curent
[ dacă valoarea numerică a elementului curent este 0, atunci, în loc să treacă la următoarea comandă, acesta sare la următoarea comandă "]".
] dacă valoarea numerică a elementului curent este nenulă, atunci sare la comanda succesoare primei comenzi "[", de la dreapta la stânga.

Un limbaj predecesor brainfuck-ului[modificare | modificare sursă]

Exceptând cele două comenzi de citire și de scriere, brainfuck este nimic altceva decât o variație a limbajului de programare P′′ creat de Corrado Böhm în anul 1964. Astfel, conceptul exista deja de aproape trei decenii când Urban Müller a făcut brainfuckul.

Exemple[modificare | modificare sursă]

Hello World![modificare | modificare sursă]

Programul de mai jos afișează mesajul "Hello World!", urmat de o nouă linie:

 
+++++ +++++             valoarea elementului curent ajunge la 10
[                       se folosește o buclă pentru a stabili valoarea următoarelor 4 elemente la 70/100/30/10
    > +++++ ++              adună 7 la elementul 1
    > +++++ +++++           adună 10 la elementul 2 
    > +++                   adună 3 la elementul 3
    > +                     adună 1 la elementul 4
    <<<< -                  decrementează elementul 0
]                   
> ++ .                  afișează 'H'
> + .                   afișează 'e'
+++++ ++ .              afișează 'l'
.                       afișează 'l'
+++ .                   afișează 'o'
> ++ .                  afișează ' '
<< +++++ +++++ +++++ .  afișează 'W'
> .                     afișează 'o'
+++ .                   afișează 'r'
----- - .               afișează 'l'
----- --- .             afișează 'd'
> + .                   afișează '!'
> .                     afișează '\n'

Din motive de ușurință de citire, programul a fost comentat și comenziile au fost grupate. Programul ar fi putut de altfel să fie scris astfel:

 ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

O colecție de algoritmi esențiali[modificare | modificare sursă]

Curățarea unui element[modificare | modificare sursă]

 [-]

O secvență de cod care decrementează elementul curent până când acesta devine nul.

Nulizează elementele predecesoare[modificare | modificare sursă]

 [
     [-]
     <
 ]

Decrementează elementul curent până la atingerea unei valori nule, continuând acest lucru cu toate elementele predecesoare acesteia până la întâlnirea uneia cu valoare numerică egală cu 0.

Deruleaza pana la primul element[modificare | modificare sursă]

 [<]>

Decrementează pointerul de date până găsește un zerou, apoi îl incrementeaza. Notă: Aceasta garantează o valoare nenulă la pointerul final dacă pointerul initial sau pointerul următor are o valoare nenulă.

Adunare[modificare | modificare sursă]

Versiunea distructivă.

 [
     ->   
     +<
 ]

Versiunea nedistructivă.

 [
     -    
     >+   
     >+   
     <<
 ]
 >>       
 [
     -
     <<+
     >>
 ]

Această versiune este nedistructivă însă folsește de 1.5 ori mai multă memorie.

Bucle condiționate[modificare | modificare sursă]

 ,----------[----------------------.,----------]

Acest program citește de la tastatură un caracter scăzând 10 din valoarea numerică a acesteia (valoarea ASCII a unei linii noi) și dacă valoarea nu este nenulă, acesta mai scade 22, rezultând un caracter cu 32 mai mic (aceasta este diferența între literele mici si cele mari).

Portabilitatea[modificare | modificare sursă]

Deoarece Urban Müller nu a specificat un standard al acestui limbaj, numeroasele interpretoare si compilatoare ale limbajului utilizează mai multe "dialecte". Una dintre diferențele principale fiind cea în care programul citește valori numerice sau ASCII.

Mărimea unui element[modificare | modificare sursă]

În distribuția originală, lungimea unui element este echivalentă cu cea de 8 biți, însă există de asemenea interpretoare care folosesc 16, 32 sau chiar 64 de biți.

Mărimea vectorului[modificare | modificare sursă]

În distribuția originală, numărul elementelor este de 30000, elementul curent inițial fiind cel cu indicele 0. Unele versiuni însă extind vectorul dinamic sau folosesc mărimi foarte mari, altele lasă utilizatorul să-și seteze dimensiunea.

Variația valorii numerice a caracterului linie nouă[modificare | modificare sursă]

Având în vedere că unele sisteme de operare folosesc diferite tabele ASCII, programele portabile nu pot depinde de valoarea caracterului linie nouă.

Legături externe[modificare | modificare sursă]