BrainFuck – generatory kodu

Po przeszukaniu internetów i znalezieniu esolangs.org okazało się, że nie jestem pierwszym, który wpadł na bezsensowny pomysł napisania generatora kodu dla BrainFucka.
Generatory można podzielić na dwie grupy:

  • makroasemblery
  • kompilatory

Makroasemblery

Makroasemblery są często realizowane jako zestawy makr. Nie dokonują one żadnej optymalizacji. Znalezione makroasemblery dla BrainFucka to:

  • BrainClub – silnik w js i prosty zestaw nierozszerzalnych makr składnią przypominających Fortha;
  • eso_bfm – silnik w Pythonie do rozszerzania makr. Same makra nie są zdefiniowane;
  • mandelbrot – zestaw prawdziwych makr dla preprocesowa C;
  • bfmacro – zestaw makr w Perlu, wymaga podawania zmiennych tymczasowych na obliczenia.

Kompilatory

Drugą, o wiele ciekawszą grupą, są kompilatory. W przeciwieństwie do asemblera próbują dokonywać prostych optymalizacji. Jako język źródłowy często jest wybierany uproszczony C posiadający jeden tym danych będący 32 bajtowym słowem. Niektóre z kompilatorów generują kod pośredni w postaci języka makroasemblera. Znalezione makroasemblery to:

  • BFBASIC – implementacja w Javie, totalny brak dokumentacji;
  • C2BF – kompilator i linker napisane w C, brak dokumentacji;
  • FuckBrainfuck – własny język, implementacja w Lua, dokumentacja dwa razy dłuższa od kodu;
  • libbf – kod zaginął;
  • TBF – kod zaginął;
  • EBF-compiler – rozszerzenie do BF, gdzie kompilator sam w sobie jest napisany;
  • bfcomp – pseudo C napisane w C.

Z całej listy sensowną konkurencją wydaje się tylko C2BF i bfcomp. z FBF można próbować pożyczyć kilka algorytmów implementacji makr.

Inne języki docelowe

Znalazłem też makroasemblery i kompilatory tłumaczące do innych ezoterycznych języków programowania. Są to:

  1. Higher Subleq dla SubLeq – jeden plik cpp bez dokumentacji;
  2. etacc dla ETA – kompilator napisany z pomocą Flexa i Bisona w C;
  3. Piet – zestaw rozkazów napisany w perlu
  4. BeFunge:
    • sponge -podzbiór Scheme w Common Lispie;
    • BefunGen – kompilator C w C#.

W tej kolejności zapewne będę próbował pokonać konkurencję. Będzie to o tyle trudne, że architektury docelowe są skrajnie różne.

Podsumowanie

Pozostaje tylko wybrać składnię języka źródłowego i zabrać się za implementację front-endu i back-endu kompilatora.

BrainFuck – początek

Na początku studiów informatycznych kolega matematyk pokazał mi język programowania BrainFuck. Język nie przydatny do niczego za wyjątkiem sprawiania sobie radości, że potrafi się bohatersko rozwiązywać problemy nie istniejące w innych językach programowania.

Język jest niesamowicie prosty, posiada tylko osiem rozkazów, ale jednocześnie jest kompletny w sensie Turinga co oznacza, że można w nim wykonywać dowolny algorytm.

Od razu jak to zobaczyłem to stwierdziłem, że ja nie jestem matematykiem, żeby rozwiązywać informatyczne sudoku. Ja napiszę sobie język pseudoasemblerowy kompilowany do BrainFucka, a skoro będę miał język asemblerowy, to mogę też sobie napisać kompilator języka wyższego poziomu.

Początkowo chciałem napisać implementację Pascala w Javie, bo jeszcze miałem sentyment do Pascala, a do Javy ogromny entuzjazm, bo właśnie ją poznałem. Niestety zacząłem rozwiązywanie problemu od końca, który wydawał mi się początkiem, czyli od implementacji asemblera. Tak zacząłem marnować czas na tworzeniu nieprzydatnych rozkazów i optymalizowaniu rzadko używanych. W wyniku czego nastąpił brak postępów i obecnie nie mam niczego czym mógłbym się pochwalić.