GUIDA Guida al BrainFuck

Hero467

Utente Attivo
689
404
OS
I use ARCH btw
GUIDA AL BRAINFUCK

Questa guida nasce dalla mia passione per i linguaggi di programmazione esoterici ma, soprattutto, per portare qualche altra anima giù nel baratro a smattare con questo linguaggio in particolare. Capirete perché leggendo questa breve guida.

Non tutto ciò che leggerete qui è esclusivamente frutto della mia mente. Alcune parti sono prese da articoli esistenti (quasi esclusivamente in inglese) e rielaborate/tradotte. In fondo alla guida metterò i link a tutte le fonti da cui ho preso spunto.





STORIA
Il BrainFuck è un linguaggio di programmazione esoterico, creato nel 1993 da Urban Müller. Lo scopo di questo linguaggio è di avere il più piccolo compilatore possibile, pur rimanendo Turing-completo. Il compilatore più piccolo mai scritto per questo linguaggio pesa solo 240 byte.
Il linguaggio è stato ispirato dal linguaggio di programmazione FALSE (anch’esso esoterico), che aveva un compilatore di 1024 byte.



STRUTTURA
Il BrainFuck si compone di sole 8 istruzioni. Tuttavia, nonostante la sua semplicità, la struttura di questo linguaggio può risultare confusa per chi non è pratico con i puntatori e i valori ASCII.
Le 8 istruzioni del BrainFuck sono le seguenti:
> < + - [ ] . ,


Il significato dei simboli è il seguente:
> incrementa il puntatore
< decrementa il puntatore
+ incrementa il valore della cella puntata
- decrementa il valore della cella puntata
[ ] indicano rispettivamente l’inizio e la fine di un loop. Si esce dal loop solo quando il valore della cella indicata dal puntatore è 0
. Stampa il carattere ASCII corrispondente al valore della cella indicata
, prende in input un carattere, salvandolo nella cella indicata col valore decimale ASCII



IL FUNZIONAMENTO DELLE CELLE
Il BrainFuck è composto da un insieme di celle, ognuna delle quali contiene un valore numerico. Di default, il valore di ogni cella è impostato a 0. Il programma manipola il valore all'interno di ogni cella, aumentandolo o diminuendolo con le istruzioni + e -.
Potete immaginarvi le celle in questo modo:
Codice:
[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]....

E quando andate a manipolare il valore di una cella, per esempio con questo programma +++, potete visualizzare lo stato delle celle in questo modo:
Codice:
[3][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]....

Inoltre, il puntatore "punta" ad una cella. La cella indicata dal puntatore sarà quella su cui avranno effetto tutte le istruzioni. Il puntatore può puntare a qualsiasi cella, ma solamente una alla volta. Quando si avvia il programma, prima di qualsiasi istruzione, il puntatore punta alla prima cella.
Per modificare quale cella il puntatore sta indicando, ci avvaliamo delle istruzioni > e <. Queste due istruzioni spostano il puntatore avanti o indietro di una cella, così che tutte le istruzioni a seguito vadano ad operare sulla nuova cella.
Ecco una rappresentazione grafica del puntatore:
Codice:
[0][0][0][0][0][0]...
 ^   // quella freccetta è il puntatore


I LOOP
In BrainFuck è possibile eseguire dei loop, similmente a come fareste con un ciclo while in qualsiasi linguaggio di programmazione, grazie ai caratteri [ ]. Ogni istruzione nelle parentesi quadre verrà ripetuta finché il valore della cella puntata alla fine del blocco non sarà 0. In questo modo è possibile eseguire un blocco di istruzioni più volte senza doverlo scrivere ogni volta.
In seguito, quando andremo ad esaminare un semplice programma per stampare su console “Hello, world!”, vedremo meglio come funzionano queste due istruzioni.


OUTPUT E INPUT
BrainFuck permette anche l’output di dati, tramite l’istruzione .. Quando il programma incontra questa istruzione legge il valore contenuto nella cella correntemente indicata, e stampa su console il carattere ASCII corrispondente. Per chi non sapesse cos’è l’ASCII, è un tipo di encoding che associa i vari caratteri dell’alfabeto più altri caratteri utili alla formattazione dei file ai numeri da 0 a 127. Tramite una tabella ASCII si può controllare quale valore è associato ad ogni carattere in binario, ottale, decimale ed esadecimale. Se per esempio vogliamo controllare il carattere “A” vedremo che il suo valore è 65.
Seguendo il principio inverso quando il programma troverà . controllerà il valore della cella in sistema decimale, e stamperà il carattere ASCII corrispondente.

Allo stesso modo il linguaggio permette all’utente di immetere un input grazie all’istruzione ,, sempre di un carattere. Questo carattere sarà poi convertito nel valore decimale ASCII corrispondente e salvato nella cella puntata fino al termine del programma o finché il valore di quella cella non sarà modificato da altre istruzioni.




ANALISI DI UN PROGRAMMA
Ora che abbiamo tutti gli elementi per poter leggere o scrivere un programma in BrainFuck, andiamo ad esaminarne uno. Il codice seguente impiega tutte le istruzioni che abbiamo visto fino ad ora (eccetto una) per stampare su schermo la scritta Hello, world!.

Codice:
>++++++++[<+++++++++>-]<.>++++[<+++++++>-]<+.+++++++..+++.>>++++++[<+++++++>-]<++.------------.>++++++[<+++++++++>-]<+.<.+++.------.--------.>>>++++[<++++++++>-]<+


Visto così può sembrare complicato e spaventare, quindi vediamo di spezzarlo un po’


Codice:
>++++++++[<+++++++++>-]<.

Questa parte si occupa di stampare la prima lettera. Possiamo vedere che all’inizio il puntatore viene spostato di una cella in avanti, e quella cella viene incrementata 8 volte. Viene poi iniziato un loop che torna alla prima cella e ne incrementa il valore di 9, per poi riscivolare nella seconda e decrementarla di 1. Visto che ogni decremento della seconda cella corrisponde a 9 incrementi della prima possiamo arrivare alla conclusione che essa alla fine del loop (cioè quando la seconda cella arriverà a 0) avrà un valore di 8x9, cioè 72, che è il valore ASCII della lettera “H”. Terminato il loop il puntatore viene nuovamente spostato alla prima cella, e ne viene stampato il suo valore.



Codice:
>++++[<+++++++>-]<+.

Questa parte segue lo stesso principio della prima. Viene spostato il puntatore alla seconda cella e viene incrementata di 4. Il programma entra poi in un altro loop che sposta il puntatore alla prima cella e la incrementa di 28 (4x7), per poi uscire. Ne incrementa il valore un’altra volta, e ne stampa il contenuto in output. Siccome il valore della prima cella era già 72, il risultato di questa porzione di codice sarà 72+28+1, che è 101. 101 è anche il valore ASCII del carattere “e”, e tale sarà il carattere emesso.



Il resto del programma è pressoché identico e sarebbe inutile spiegarlo, oltre che ridondante, quindi andiamo avanti, che le cose iniziano a farsi interessanti.



TRUCCHI UTILI
In questa sezione andremo ora a guardare alcuni programmini che possono essere utili in certi casi, facilmente implementabili in codici più complessi.

Codice:
+++++[>>+<<-]
Questo programma molto semplice serve per spostare il contenuto di una cella ad un’altra. Semplicemente porta la prima cella al valore desiderato (in questo caso 5) ed entra in un ciclo che si sposta di 2 celle, incrementa, torna indietro di 2 celle e decrementa. Ad ogni iterazione la prima cella sarà decrementata di 1 e la terza sarà incrementata di 1, cosicché alla fine la prima cella sarà 0 e la terza 5.



Codice:
+++++[>>+>+<<<-]>>>[<<<+>>>-]
Ora abbiamo un programmino per copiare il contenuto di una cella ad un’altra. Il funzionamento è anche in questo caso di facile comprensione: si parte sempre con l’impostare la prima cella con il valore desiderato (5 anche in questo caso). Il programma entra poi in un loop che segue lo stesso principio del programma visto prima, ma con la differenza che al posto di spostare il valore in una sola cella lo sposta in 2, la terza e la quarta. In questo modo alla fine del loop avremo queste due celle con il valore di 5, e la prima con il valore di 0. Il puntatore si sposta poi alla quarta cella ed entra in un loop che ne sposta il valore nella prima. Alla fine del programma avremo copiato il contenuto della prima cella nella terza.


Passiamo ora a vedere qualche operazione aritmetica



Codice:
+++++>+++[<+>-]
In questo snippet si somma il valore di 2 celle, impostate relativamente a 5 e a 3. L’addizione non è altro che spostare il valore di una cella ad un’altra non vuota, in modo che il risultato sia la somma dei due valori. Quindi se noi spostiamo il 3 della seconda cella nel 5 della prima otterremo che la prima avrà un valore di 8, mentre la seconda di 0.



Codice:
+++++++>+++++[<->-]
Come ultimo snippet vediamo la sottrazione del valore di una cella da un’altra di valore maggiore. Il programma imposta le prime 2 celle con il valore di 7 e 5. Successivamente entra in un loop che decrementa la prima cella e anche la seconda. Ponendo la seconda cella come ultima ci assicuriamo che il puntatore sia posizionato lì prima di arrivare alla fine del blocco, in questo modo quando la seconda cella arriverà a 0 il loop terminerà, sottraendo 5 da entrambe le celle. Alla fine otterremo una cella con valore 2 ed una con valore 0.





SPECIFICHE TECNICHE
Qua sotto riporto ora alcune specifiche tecniche se mai voleste realizzare un interprete o un compilatore per Brainfuck:
  • Nel compilatore originale il valore delle celle non poteva essere minore di 0. In molte implementazioni moderne, tuttavia, questo limite è stato rimosso
  • Di solito le varie implementazioni hanno un numero di celle di 30.000. In alcune versioni, però, sono state aggiunte altre celle prima della cella iniziale
  • Ogni carattere non facente parte del set di istruzioni verrà ignorato dal compilatore/interprete, e può essere utilizzato come commento
  • Le estensioni più comuni per i file BrainFuck sono .b e .bf
Queste sono le più importanti. Potete trovare di più nelle pagine citate sotto








FONTI
 
Ultima modifica:

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili