Programcıya tövbe ettiren dil - Brainfuck programlama dili



Merhaba sayın okurlar.

Çoğu kişinin bilmediği fakat kodlarken hem beyninizi yakan hem de eğlendiren "Brainfuck" (beyin beceren) dilinden bahsedeceğim, bu programlama dilinin adının hakkını vereceğini garanti ederiz.


Brainfuck dili, aslında en basit dillerden biridir, hatta en basiti bile olabilir. Çok kişi tarafından bilinmeyen ve kısıtlı olan bu dil, sadece 8 komut barındırıyor. Bu dil ile Class, tür, hatta değişken bile tanımlayamıyoruz fakat bu dil Turing-Complete bir dildir, yani herhangi bir programlama diliyle yapabileceğini herhangi bir şeyi, Brainfuck dili ile de yapabilirsiniz. Brainfuck'ın güzelliği basitliğinde yatar. Dilin yapımcısı Urban Müller bu dili yaparken mümkün olan en küçük boyuttaki derleyiciyi yazmaktı. Başardığını da söyleyebiliriz. Öyle ki, bu dilin bazı derleyicileri 200 bayttan bile küçüktür.

Aklınızdan "Bu dilin gerçek kullanım amacı yok." gibi bir cümle geçtiyse, sonuna kadar haklısınız. Brainfuck'ın hedefi, programcıları zorlamak ve eğlendirmektir. Peki bu dili neden öğrenesiniz? Öncelikle, yeni bir şeyler öğrenmekten asla zarar gelmez ve Turing-Complete bir dilin bu kadar basit olabileceğini görmek sizi şaşırtabilir. Ve son olarak, gerçekten zorlayıcı şeyler arıyorsanız, bu dil tam sizin için.

Brainfuck dili, pointer mantığı ile ilerleyen bir dildir. Bu yüzden başlamadan önce, eğer pointerlara aişna değil iseniz, bir göz atmanızın yararı olur. Ben yine de basitçe size anlatacağım.


Dilin derleyicisini buradan indirebilirsiniz veya online derleyici ile kodları çalıştırabilirsiniz.


Daha önce de bahsettiğim üzere, brainfuck dili sadece 8 adet komut barındırıyor. Derleyici, bu komutları temsil eden karakterler hariç her şeyi görmezden gelir.

1- + Pointer’ınızın gösterdiği memory cell’in (Hafıza kutucuğu) değerini bir arttırır.

2- - Pointer’ınızın gösterdiği memory cell’in değerini bir azaltır.

3- > Pointer’ınızı sonraki memory cell’e kaydırır.

4- < Pointer’ınızı önceki memory cell’e kaydırır.

5- , Pointer’ınızın gösterdiği memory cell’e, girilen standart input değerini atar.

6- . Pointer’ınızın gösterdiği memory cell’deki değeri output olarak verir.

7- [ Bulunduğunuz memory cell’deki değer 0 değil ise, bir döngü başlatır.

8- ] Döngünün sonunu ifade eder.

İlk olarak, memory cell'ler arasında gidip gelme, değeri artırma ve azaltma işlemlerinin mantığını oturtmamız gerekiyor. Daha iyi anlayabilmeniz için, somut bir gösterim üzerinden gideceğim. Her bir parantez bir memory cell'i temsil etsin, "^" da pointer'imizi temsil eden imleç olsun

[ 0 ]    [ 0 ]    [ 0 ]
  ^
+++++                                // ilk memory cell’in değerini 5 artır.

[ 5 ]    [ 0 ]    [ 0 ]
  ^
>                                    // sonraki memory cell’e geç

[ 5 ]    [ 0 ]    [ 0 ]
           ^
++++                                 // ikinci memory cell’in değerini 4 artır.

[ 5 ]    [ 4 ]    [ 0 ]
           ^
>                                    // sonraki memory cell’e geç.
+++++++++                            // üçüncü memory cell’in değerini 9 artır. 

[ 5 ]    [ 4 ]    [ 9 ]
                    ^
<                                    // önceki memory cell’e geç
--                                   //  ikinci memory cell’in değerini iki azalt

[ 5 ]    [ 2 ]    [ 9 ]
           ^

Her memory cell'deki bilgiler maksimum 1 baytlık değer içerebiliyor. Yani kutulardaki sayı en fazla 255 olabiliyor. Eğer kutudaki değeri 255 den bir arttırısanız, yeni değer 0 olacaktır. Aynı şekilde, 0 olan bir değeri azalttığınızda 255 elde edersiniz.

Açıklamalardan kurtulup tekrar yazdığımızda, kodun aşağıdaki gibi olacaktır.

+++++>++++>+++++++++<--

Bu kısmı anladıysak, artık döngüleri görebiliriz. Bildiğiniz üzere döngüler, bir dilde olmazsa olmazdır ve işimizi gerçekten kolaylaştırırlar.

7 tane memory cell değerimizi sırasıyla 89,56,53,48,71,3,18 yapacak bir kod yazalım. En basit yol olarak, memory cell değerlerini döngüler aracılığıyla 10 katına tamlayıp ince ayar kısmını yapabiliriz. Bunun için döngüyü 10 kez kullanmamız gerekiyor. Yani sekizinci bir memory cell'de, 10 değerini tutmalıyız. Hadi başlayalım.

+++++ +++++                          // memory cell0 = 10
[                                    // döngüye gir
>                                    // sonraki memory cell  
+++++ ++++                           // memory cell1 += 9
>                                    // sonraki memory cell
+++++ +                              // memory cell2 += 6
>                                    // sonraki memory cell 
+++++                                // memory cell3 += 5
>                                    // sonraki memory cell
+++++                                // memory cell4 += 5
>                                    // sonraki memory cell
+++++ ++                             // memory cell5 += 7
>                                    // sonraki memory cell
>                                    // sonraki memory cell
++                                   // memory cell7 += 2
<<<<<<<                              // memory cell0’a dön
-                                    // memory cell0 --
]                                    // eğer memory cell0’ın değeri 0 ise döngüden çık, değilse başa dönİl

İlk memory cell'in değerini her seferde 1 azalttık, ve olduğu zaman döngüden çıkmış olduk. Döngüden çıktıktan sonra elimizde olan: 

[ 0 ]    [ 90 ]    [ 60 ]    [ 50 ]    [ 50 ]    [ 70 ]    [ 0 ]    [ 20 ]
  ^

Memory cell'lerdeki değerler istediklerimize yeterince yakın, devam edebiliriz.

>-
>----
>+++
>--
>+
>+++
>--

Ve işte, istediğimiz değerler!

Yeni bir dil öğrendiğimizde geleneği bozmamak gerek, tabii ki "Hello World!" yazacağız. Maalesef diğer dillerdeki kadar kolay değil tabii ki, fakat bir kere yaptıktan sonra çok kolay gelecek!

Brainfuck dili, outputları sayı olarak değil, memory cell'lerdeki değerlerin ASCII tablosundaki karakter karşılığı olarak veren bir dildir.                                                                 Bu yüzden brainfuck ile kod yazarken, bir sekmenizde ASCII tablosunu açık tutmanızı tavsiye ederiz. ASCI tablosuna buradan ulaşabilirsiniz.

Öncelikle kullanacağımız karakterleri ASCII tablosundaki değerlerine göz gezdirelim.

H:  72
e:  101
l:  108
o:  111
boşluk: 32
W:  87
r:  114
d:  100
ünlem işareti: 33

108, 111 ve 114 sayıları birbirine oldukça yakın, onları ekrana yansıtmak için tek bir memory cell'i kullanabiliriz. Aynı şey 100 ve 101 için de geçerli. Değerleri atamakla başlayalım. Yine döngümüzü 10 kez tekrarlamak mantıklı gibi duruyor.

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

İşlem sonunda elimizde

[ 0 ]    [ 70 ]    [ 100 ]    [ 110 ]    [ 30 ]    [ 90 ]
  ^

olacak. Gelelim bastırma aşamasına.

>++ .              // memory cell1 değerini 2 artır. memory cell1 = 72 = “H”, bastır.
>+ .               // memory cell2 değerini 1 artır. memory cell2 = 101 = “e”, bastır.
>-- ..             // memory cell3 değerini 2 azalt. memory cell3 = 108 = “l”, iki kez art arda bastır.
+++.               // Hala memory cell3’teyiz. Değerini 3 artır. memory cell3 = 111 = “o”, bastır.
>++ .              // memory cell4 değerini 2 artır. memory cell4 = 32 = “ “ , bastır.
>--- .             // memory cell5 değerini 3 azalt. memory cell5 = 87 = “W”, bastır.
<< .               // memory cell3’e git. memory cell3’te hala 111 = “o” değeri mevcut. Bastır.
+++ .              // memory cell3 değerini 3 artır. memory cell3 = 114 = “r”, bastır.
------ .           // memory cell3 değerini 6 azalt. memory cell3 = 108 = “l”, bastır.
<- .               // memory cell2 değerini 1 azalt. memory cell2 = 100 = “d”, bastır.
>>+ .              // memory cell4’e git, değerini 1 artır. memory cell4 = 33 = “!”, bastır.

Eğlenceli, değil mi?

Brainfuck'ın işlevi sadece karakter bastırmakla sınırlı değil. Matematiksel işlemler yapabilir, hatta bir memory cell'deki değeri başka bir memory cell'e kopyalabiliyir, hatta ve hatta if-else koşullarını test edebilirsiniz. Dediğimiz gibi, brainfuck Turing-Complete bir dildir.

Bu eğlendirici ve zorlayıcı dili anlatmaya çalıştım, umarım anlamışsınızdır. Herhangi bir takıldığınız yer var ise yorumlarda belirtebilirsiniz.

Kaynakça:


- Mevcut yorum.

Daha yeni Daha eski