Brainfuck
Från Rilpedia
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
- Ook!, en variant av brainfuck
- Turingmaskin
- Externa länkar på den engelska motsvarighet till denna sida