How does the Brainfuck Hello World brain world work?

Someone sent this to me and stated that this is a hello world at Brainfuck (and I hope so ...)

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

I know the basics that it works by moving the pointer and increasing and decreasing the number of files ...

But I still want to know how it works? How does he print anything on the screen in the first place? How does it encode text? I don’t understand at all ...

+83
brainfuck esoteric-languages
May 30 '13 at 12:57
source share
4 answers

1. The basics

To understand Brainfuck, you have to represent an infinite array of cells initialized with each 0 .

 ...[0][0][0][0][0]... 

When the brainfuck program starts, it points to any cell.

 ...[0][0][*0*][0][0]... 

If you move the pointer to the right > , you move the pointer from cell X to cell X + 1

 ...[0][0][0][*0*][0]... 

If you increase the value of cell + , you get:

 ...[0][0][0][*1*][0]... 

If you increase the value of cell + again, you get:

 ...[0][0][0][*2*][0]... 

If you decrease the value of cell - , you will get:

 ...[0][0][0][*1*][0]... 

If you move the pointer to the left < , you move the pointer from cell X to cell X-1

 ...[0][0][*0*][1][0]... 

2. Enter

To read a character, you use a comma,. What it does: read the character from standard input and write its decimal ASCII code into the actual cell.

See the ASCII table . For example, a decimal code ! is 33 , and a is 97 .

Well, imagine that your BF program memory looks like this:

 ...[0][0][*0*][0][0]... 

Assuming standard input means a , if you use the comma operator, then what BF does is read a decimal ASCII code 97 into memory:

 ...[0][0][*97*][0][0]... 

Usually you think so, but the truth is a little more complicated. The truth is that the BF does not read a character, but a byte (no matter what this byte is). Let me show you an example:

In linux

 $ printf Ε‚ 

prints:

 Ε‚ 

which is specific Polish character. This character is not ASCII encoded. In this case, this is UTF-8 encoding, so it used more than one byte in the computer's memory. We can prove this by making a hex dump:

 $ printf Ε‚ | hd 

which shows:

 00000000 c5 82 |..| 

Zeros are offset. 82 is the first, and c5 is the second byte representing Ε‚ (so that we read them). |..| - This is a graphical representation that is not possible in this case.

Well, if you pass Ε‚ as input to your BF program, which reads one byte, the program memory will look like this:

 ...[0][0][*197*][0][0]... 

Why 197 ? Well 197 decimal symbol c5 hexadecimal. Seems familiar? Sure. This is the first byte Ε‚ !

3. Exit

To print the character you use dot . What it does: Assuming we treat the actual value of the cell as an ASCII decimal code, print the corresponding character to standard pins.

Well, imagine that your BF program memory looks like this:

 ...[0][0][*97*][0][0]... 

If you are now using the dot (.) Operator, then what BF does is print:

but

Since a decimal code in ASCII is 97 .

So, for example, a BF program like this (97 pluses 2 points):

++++++++++++++++++++++++++++++++++++++++++++++++++ +++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ..

Increases the value of the cell to which it points to 97, and prints it 2 times.

aa

4. Loops

In a loop, BF consists of a begin loop [ and the end of a loop ] . You can think of it like in C / C ++, where the condition is the actual value of the cell.

Check out the BF program below:

 ++[] 

++ increments the value of the actual cell twice:

 ...[0][0][*2*][0][0]... 

And [] is similar to while(2) {} , so this is an infinite loop.

Say we do not want this cycle to be infinite. We can do, for example:

 ++[-] 

Thus, each time a loop cycle decreases the actual value of the cell. When the actual value of cell 0 ends with the end:

 ...[0][0][*2*][0][0]... loop starts ...[0][0][*1*][0][0]... after first iteration ...[0][0][*0*][0][0]... after second iteration (loop ends) 

Consider another example of a finite loop:

 ++[>] 

This example shows that we should not end the cycle in the cell where the cycle was started:

 ...[0][0][*2*][0][0]... loop starts ...[0][0][2][*0*][0]... after first iteration (loop ends) 

However, this is a great practice with which we started. What for? Since if the loop terminates another cell, we cannot assume where the cell pointer will be. Honestly, this practice makes brain injection less brain.

+161
Nov 08 '13 at 22:27
source share

Wikipedia has a commented version of the code.

 +++++ +++++ initialize counter (cell #0) to 10 [ use loop to set the next four cells to 70/100/30/10 > +++++ ++ add 7 to cell #1 > +++++ +++++ add 10 to cell #2 > +++ add 3 to cell #3 > + add 1 to cell #4 <<<< - decrement counter (cell #0) ] > ++ . print 'H' > + . print 'e' +++++ ++ . print 'l' . print 'l' +++ . print 'o' > ++ . print ' ' << +++++ +++++ +++++ . print 'W' > . print 'o' +++ . print 'r' ----- - . print 'l' ----- --- . print 'd' > + . print '!' > . print '\n' 

To answer your questions, input characters , and . used for input / output. The text is ASCII.

Wikipedia article goes on a deeper basis.

The first line initializes a[0] = 10 simple ten-fold increase from 0. The loop from line 2 effectively sets the initial values ​​for the array: a[1] = 70 (close to 72, ASCII code for the character 'H'), a[2] = 100 (close to 101 or 'e'), a[3] = 30 (close to 32, code for a space) and a[4] = 10 (new line). The cycle works by adding 7, 10, 3 and 1 to cells a[1] , a[2] , a[3] and a[4] respectively, every time through the cycle - 10 additions for each cell as a whole (providing a[1]=70 , etc.). At the end of the cycle, a[0] is equal to zero. >++. then moves the pointer to a[1] , which contains 70, adds two to it (producing 72, which is the ASCII code of capital H) and displays it.

The next line moves the array pointer to a[2] and adds it to it, producing 101, the lower case "e", which is then output.

As "l" happens to be the seventh letter after "e", to output "seven more" seven more are added ( +++++++ ) to a[2] , and the result is displayed twice.

'o' is the third letter after 'l', so a[2] increases three more times and print the result.

The rest of the program continues the same way. For spaces and uppercase letters, various cells of the array are selected and, if necessary, increase or decrease.

+41
May 30 '13 at 13:06
source share

To answer the question of how he knows what to print, I added the calculation of ASCII values ​​to the right of the code in which the print takes place:

 > just means move to the next cell < just means move to the previous cell + and - are used for increment and decrement respectively. The value of the cell is updated when the increment/decrement happens +++++ +++++ initialize counter (cell #0) to 10 [ use loop to set the next four cells to 70/100/30/10 > +++++ ++ add 7 to cell #1 > +++++ +++++ add 10 to cell #2 > +++ add 3 to cell #3 > + add 1 to cell #4 <<<< - decrement counter (cell #0) ] > ++ . print 'H' (ascii: 70+2 = 72) //70 is value in current cell. The two +s increment the value of the current cell by 2 > + . print 'e' (ascii: 100+1 = 101) +++++ ++ . print 'l' (ascii: 101+7 = 108) . print 'l' dot prints same thing again +++ . print 'o' (ascii: 108+3 = 111) > ++ . print ' ' (ascii: 30+2 = 32) << +++++ +++++ +++++ . print 'W' (ascii: 72+15 = 87) > . print 'o' (ascii: 111) +++ . print 'r' (ascii: 111+3 = 114) ----- - . print 'l' (ascii: 114-6 = 108) ----- --- . print 'd' (ascii: 108-8 = 100) > + . print '!' (ascii: 32+1 = 33) > . print '\n'(ascii: 10) 
+4
Mar 20 '17 at 6:34
source share

All answers are comprehensive, but they lack one tiny detail: Printing. When building your brainfuck translator, you also consider a symbol . , this is actually what the expression about printing in brainfuck looks like. So, what should your brainfuck translator do whenever it encounters a symbol . , it prints the current byte.

Example:

suppose you have β†’ char *ptr = [0] [0] [0] [97] [0] ... if this is an expression about the brain: >>>. your pointer should be moved 3 places before the right landing: [97] , so now *ptr = 97 , after your translator meets . he must then call

 write(1, ptr, 1) 

or any equivalent print statement for printing the current byte, which has a value of 97 , and the letter a will be printed on std_output .

+1
Jul 18 '16 at 10:00
source share



All Articles