Brainfuck
Den här artikeln har källor, men den behöver fler fotnoter för att kunna verifieras. (2023-03) Hjälp gärna Wikipedia med att lägga till fotnoter om du kan, eller diskutera saken på diskussionssidan. Material som inte verifieras kan tas bort. |
Brainfuck är ett turingkomplett esoteriskt programspråk skapat 1993 av den schweiziske fysikstudenten Urban Müller, med syfte att skapa ett språk med så liten kompilator som möjligt. Maskinkoden till Müllers ursprungliga kompilator till AmigaOS 2.0 upptog 240 bytes.[1]
Att programmera i brainfuck är svårt och att läsa koden ännu svårare. Namnet Brainfuck syftar på just detta.
Paradigm
redigeraCentralt 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 kan användas som introduktion till programmering av turingmaskiner.
Minnesareans storlek varierar mellan olika implementationer men brukar i allmänhet sägas vara minst 30000 bytes.[källa behövs]
Det finns totalt åtta instruktioner. Dessa flyttar pekaren, manipulerar det minne pekaren pekar på, hanterar I/O samt styr programflödet. För att tydligare illustrera hur brainfuck-kod fungerar går den att översätta till motsvarande C-kod.
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 [ | } |
Implementationsproblem
redigeraMånga variationer av språket har dykt upp under årens lopp, vilket har resulterat i ett antal portabilitetsproblem av varierande magnitud. Till exempel anser somliga[vilka?] att hash-tecknet ('#') skall betraktas som en särskild avlusningsinstruktion och vissa[vilka?] hävdar bestämt att varje cell i minnessekvensen skall vara två bytes stor.
Ett annat problem ä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.
Exempelkod
redigera++++++++++[>+++++++>++++++++++>+++>+<<<<-]
>++.>+.+++++++..+++.>++.<<+++++++++++++++.
>.+++.------.--------.>+.>.
Ett alternativ med förklaringar
[ Det här programmet skriver ut "Hello World!" och en ny rad, längden
är 106 aktiva tecken. [Det är inte det kortaste.]
Den här loopen är en "kommentarsloop", ett enkelt sätt att lägga till en
kommentar till ett BF-program så att man inte behöver oroa sig för några
kommandotecken. Alla ".", ",", "+", "-", "<" och ">" ignoreras,
loopkaraktärerna "[" and "]", måste dock balanseras. Den här loopen
och kommandona den innehåller ignoreras eftersom den nuvarande cellen (#0)
är 0 från början; värdet 0 gör att den här loopen hoppas över.
]
++++++++ Sätt cell #0 till 8
[
>++++ Addera 4 till cell #1; det här kommer alltid att sätta cell #1 till 4
[ eftersom cellen nollställs av loopen
>++ Addera 2 till cell #2
>+++ Addera 3 till cell #3
>+++ Addera 3 till cell #4
>+ Addera 1 till cell #5
<<<<- Minska loopräknaren i cell #1 med 1
] Loopa tills cell #1 är 0; antalet iterationer är 4
>+ Addera 1 till cell #2
>+ Addera 1 till cell #3
>- Subtrahera 1 från cell #4
>>+ Addera 1 till Cell #6
[<] Flytta tillbaka till den första nollan; det kommer att
vara cell #1 som sattes till 0 i den förra loopen
<- Minska loopräknaren i cell #0 med 1
] Loopa tills cell #0 är 0; antalet iterationer är 8
Resultatet av det här är:
Cell nr.: 0 1 2 3 4 5 6
Innehåll: 0 0 72 104 88 32 8
Pekare : ^
>>. Cell #2 har värdet 72 vilket är 'H'
>---. Subtrahera 3 från cell #3 för att få 101 vilket är 'e'
+++++++..+++. På samma sätt får man 'llo' från cell #3
>>. Cell #5 är 32 för blanksteg
<-. Subtrahera 1 från cell #4 för att få 87 vilket är 'W'
<. Cell #3 var 'o' från slutet av 'Hello'
+++.------.--------. Cell #3 för att få 'rld'
>>+. Addera 1 till cell #5 för att få ett utropstecken
>++. Till sist får vi en ny rad från cell #6
Divisionsrutin 1
redigera>>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<[->>+>+<<<]>>>[-<<<+>>>]<<[->>+>+<<<]>>>[-<
<<+>>>]<<[>[>>>>[-]<<<<<[->>+>>>+<<<<<]>>[-<<+>>]<[-<->>+<<[>>-<<[->>>+<<<]
]>>>[-<<<+>>>]<[-<[-]>]<]<[<[->>+>+<<<]>>>[-<<<+>>>]>>+<<<<[->>+<<]]>>[-<<+
>>]<]<<[->+>+<<]>[-<+>]>>>>>[-<<+<+>>>]<<<[-<->]+<[>-<[-]]>[>[-]>+<<-]<<][-
]>[-]>>[-<<+>>]>[-<<<<+>>>>]>[-]<[-]<[-]<[-]<<<<
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 |
Alfabetet
redigera+++++[>+++++++++++++<-]>.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.
Se även
redigera- Ook! en variant av brainfuck
- Turingmaskin är en abstrakt mekanism för att utföra beräkningar.
Källor
redigera- ^ Urban Müller (9 juni 1993). ”dev/lang/brainfuck-2.lha”. aminet. Arkiverad från originalet den 2 oktober 2010. https://web.archive.org/web/20101002142229/http://aminet.net/package/dev/lang/brainfuck-2. Läst 24 januari 2018.