Brainfuck

Från Rilpedia

Hoppa till: navigering, sök
Wikipedia_letter_w.pngTexten från svenska WikipediaWikipedialogo_12pt.gif
rpsv.header.diskuteraikon2.gif

Brainfuck är ett kompakt och turingkomplett programspråk.

Brainfuck uppfanns 1993 av Urban Müller, vars avsikt var att skapa ett turingkomplett programspråk som kunde implementeras med en minimal kompilator. Den ursprungliga kompilatorn var endast 240 bytes stor.

Att programmera i brainfuck är svårt, att läsa brainfuckkod är ännu svårare. Namnet Brainfuck, som betyder hjärnknull eller hjärntrassel, syftar på vad en programmerare kan tänkas uppleva då denne sysslar med brainfuckutveckling.

Innehåll

Paradigm

Centralt i språket står en pekare och en sekvens av bytes. Initialt pekar pekaren längst till vänster i sekvensen och alla bytes har värdet noll. Det finns även en indata- och en utdata-ström. Brainfuck påminner i många avseenden om turingmaskinen och fungerar därför utmärkt som introduktion till programmering av turingmaskiner.

Minnesareans storlek varierar mellan olika implementationer men brukar i allmänhet sägas vara minst 30000 bytes.

Det finns totalt åtta instruktioner. Dessa flyttar pekaren, manipulerar det minne pekaren pekar på, hanterar I/O samt styr programflödet. Det är vanligt att översätta brainfuckkod till C-kod (motsvarande) för att ge den oinsatte en bättre uppfattning om instruktionernas funktion.

Tecken Betydelse Motsvarighet i C
> flytta pekaren ett steg åt höger pointer++;
< flytta pekaren ett steg åt vänster pointer--;
+ addera ett till byten pekaren pekar på (*pointer)++;
- subtrahera ett från byten pekaren pekar på (*pointer)--;
. skriv innehållet i byten pekaren pekar på till utdata-strömmen putchar(*pointer);
, läs en byte från indata-strömmen och lagra den där pekaren pekar *pointer=getchar();
[ om byten pekaren pekar på är noll, hoppa förbi till motsvarande ] while(*pointer){
] om byten pekaren pekar på är skild från noll, hoppa tillbaka till motsvarande [ }

Problem

Många variationer av språket har dykt upp under årens lopp, vilket har resulterat i ett antal portabilitetsproblem av varierande magnitud. T ex anser somliga att hash-tecknet ('#') skall betraktas som en särskild debuginstruktion och vissa hävdar bestämt att varje cell i minnessekvensen skall vara två bytes stor. Det instruktionsset och den cellstorlek som presenteras på denna sida kan nog anses vara den vanligast förekommande modellen.

Ett annat stort problem, förmodligen det största, är vad som skall hända om ','-instruktionen exekveras då det inte finns någon data att hämta från indata-strömmen. Vissa implementationer väljer att skriva 0x00 till minnet, andra väljer att skriva 0xff (-1) till minnet och ett fåtal väljer att inte skriva något alls. Tyvärr finns det inget konsensus i frågan bland brainfuckutvecklarna.

Exempelkod

Hello World!

Ett program som skriver ut texten "Hello World!":

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

Divisionsrutin 1

Ett stycke kod som genomför division:

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

Låt cellen pekaren pekar på innehålla täljare och låt cellen närmast till höger innehålla nämnare. Ytterligare sex (6) celler används då koden exekveras. Följande tabell illustrerar hur minnet ser ut före och efter exekvering:

Före exekvering täljare nämnare
Efter exekvering: täljare nämnare kvot rest 0 0 0 0

Se även

Personliga verktyg