264 lines
8.3 KiB
Brainfuck
264 lines
8.3 KiB
Brainfuck
|
[
|
||
|
This routine is a demonstration of checking for the three cell sizes
|
||
|
that are normal for Brainfuck. The demo code also checks for bugs
|
||
|
that have been noted in various interpreters and compilers.
|
||
|
|
||
|
It should print one of three slight variations of "Hello world" followed
|
||
|
by an exclamation point then the maximum cell value (if it's less than a
|
||
|
few thousand) and a newline.
|
||
|
|
||
|
If the interpreter is broken in some way it can print a lot of other
|
||
|
different strings and frequently causes the interpreter to crash.
|
||
|
|
||
|
It does work correctly with 'bignum' cells.
|
||
|
]
|
||
|
+>>
|
||
|
|
||
|
This code runs at pointer offset two and unknown bit width; don't
|
||
|
assume you have more that eight bits
|
||
|
|
||
|
======= DEMO CODE =======
|
||
|
First just print "Hello"
|
||
|
|
||
|
Notice that I reset the cells despite knowing that they are zero
|
||
|
this is a test for proper functioning of the ability to skip over
|
||
|
a loop that's never executed but isn't actually a comment loop
|
||
|
|
||
|
Secondly there's a NOP movement between the two 'l' characters
|
||
|
|
||
|
Also there's some commented out code afterwards
|
||
|
|
||
|
>[-]<[-]++++++++[->+++++++++<]>.----[--<+++>]<-.+++++++.><.+++.
|
||
|
[-][[-]>[-]+++++++++[<+++++>-]<+...--------------.>++++++++++[<+
|
||
|
++++>-]<.+++.-------.>+++++++++[<----->-]<.-.>++++++++[<+++++++>
|
||
|
-]<++.-----------.--.-----------.+++++++.----.++++++++++++++.>++
|
||
|
++++++++[<----->-]<..[-]++++++++++.[-]+++++++[.,]-]
|
||
|
|
||
|
===== END DEMO CODE =====
|
||
|
<<-
|
||
|
|
||
|
Calculate the value 256 and test if it's zero
|
||
|
If the interpreter errors on overflow this is where it'll happen
|
||
|
++++++++[>++++++++<-]>[<++++>-]
|
||
|
+<[>-<
|
||
|
Multiply by 256 again to get 65536
|
||
|
[>++++<-]>[<++++++++>-]<[>++++++++<-]
|
||
|
+>[>
|
||
|
Cells should be 32bits at this point
|
||
|
|
||
|
The pointer is at cell two and you can continue your code confident
|
||
|
that there are big cells
|
||
|
|
||
|
======= DEMO CODE =======
|
||
|
This code rechecks that the test cells are in fact nonzero
|
||
|
If the compiler notices the above is constant but doesn't
|
||
|
properly wrap the values this will generate an incorrect
|
||
|
string
|
||
|
|
||
|
An optimisation barrier; unbalanced loops aren't easy
|
||
|
>+[<]>-<
|
||
|
|
||
|
Print a message
|
||
|
++>[-]++++++[<+++++++>-]<.------------.[-]
|
||
|
<[>+<[-]]>
|
||
|
++++++++>[-]++++++++++[<+++++++++++>-]<.--------.+++.------.
|
||
|
--------.[-]
|
||
|
|
||
|
===== END DEMO CODE =====
|
||
|
|
||
|
<[-]<[-]>] <[>>
|
||
|
Cells should be 16bits at this point
|
||
|
|
||
|
The pointer is at cell two and you can continue your code confident
|
||
|
that there are medium sized cells; you can use all the cells on the
|
||
|
tape but it is recommended that you leave the first two alone
|
||
|
|
||
|
If you need 32bit cells you'll have to use a BF doubler
|
||
|
|
||
|
======= DEMO CODE =======
|
||
|
Space
|
||
|
++>[-]+++++[<++++++>-]<.[-]
|
||
|
|
||
|
I'm rechecking that the cells are 16 bits
|
||
|
this condition should always be true
|
||
|
|
||
|
+>>++++[-<<[->++++<]>[-<+>]>]< + <[ >>
|
||
|
|
||
|
Print a message
|
||
|
>[-]++++++++++[<+++++++++++>-]<+++++++++.--------.
|
||
|
+++.------.--------.[-]
|
||
|
|
||
|
<[-]<[-] ] >[> > Dead code here
|
||
|
This should never be executed because it's in an 8bit zone hidden
|
||
|
within a 16bit zone; a really good compiler should delete this
|
||
|
If you see this message you have dead code walking
|
||
|
|
||
|
Print a message
|
||
|
[-]>[-]+++++++++[<++++++++++>-]<.
|
||
|
>++++[<+++++>-]<+.--.-----------.+++++++.----.
|
||
|
[-]
|
||
|
|
||
|
<<[-]]<
|
||
|
===== END DEMO CODE =====
|
||
|
|
||
|
<<[-]] >[-]< ] >[>
|
||
|
Cells should be 8bits at this point
|
||
|
|
||
|
The pointer is at cell two but you only have 8 bits cells
|
||
|
and it's time to use the really big and slow BF quad encoding
|
||
|
|
||
|
======= DEMO CODE =======
|
||
|
|
||
|
A broken wrapping check
|
||
|
+++++[>++++<-]>[<+++++++++++++>-]<----[[-]>[-]+++++[<++++++>-]<++.
|
||
|
>+++++[<+++++++>-]<.>++++++[<+++++++>-]<+++++.>++++[<---->-]<-.++.
|
||
|
++++++++.------.-.[-]]
|
||
|
|
||
|
Space
|
||
|
++>[-]+++++[<++++++>-]<.[-]
|
||
|
|
||
|
An exponent checker for github user btzy
|
||
|
>++[>++<-]>[<<+>>[-<<[>++++<-]>[<++++>-]>]]<<[>++++[>---<++++]>++.
|
||
|
[<++>+]<.[>+<------]>.+++.[<--->++]<--.[-]<[-]]
|
||
|
|
||
|
Another dead code check
|
||
|
[-]>[-]>[-]<++[>++++++++<-]>[<++++++++>-]<[>++++++++<-]>[<++++++++>-
|
||
|
]<[<++++++++>-]<[[-]>[-]+++++++++[<++++++++++>-]<.>++++[<+++++>-]<+.
|
||
|
--.-----------.+++++++.----.>>[-]<+++++[>++++++<-]>++.<<[-]]
|
||
|
|
||
|
Print a message
|
||
|
[-] <[>+<[-]]> +++++>[-]+++++++++[<+++++++++>-]<.
|
||
|
>++++[<++++++>-]<.+++.------.--------.
|
||
|
[-]
|
||
|
===== END DEMO CODE =====
|
||
|
|
||
|
<[-]]<
|
||
|
|
||
|
+[[>]<-] Check unbalanced loops are ok
|
||
|
|
||
|
>>
|
||
|
======= DEMO CODE =======
|
||
|
Back out and print the last two characters
|
||
|
|
||
|
[<[[<[[<[[<[,]]]<]<]<]<][ Deep nesting non-comment comment loop ]]
|
||
|
|
||
|
Check that an offset of 128 will work
|
||
|
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>-[+<-]
|
||
|
|
||
|
And back
|
||
|
+++[->++++++<]>[-<+++++++>]<[->>[>]+[<]<]>>[->]<<<<<<<<<<<<<<<<<<<<<
|
||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
|
||
|
And inside a loop
|
||
|
--[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>++<<<
|
||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+]+>----[++
|
||
|
++>----]-[+<-]
|
||
|
|
||
|
This is a simple multiply loop that looks like it goes off the
|
||
|
start of the tape
|
||
|
+[>]<- [-
|
||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
++++
|
||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
]
|
||
|
|
||
|
[ Check there are enough cells. This takes 18569597 steps. ]
|
||
|
[
|
||
|
>++++++[<+++>-]<+[>+++++++++<-]>+[[->+>+<<]>>
|
||
|
[-<<+>>]<[<[->>+<<]+>[->>+<<]+[>]<-]<-]<[-<]
|
||
|
]
|
||
|
|
||
|
This loop is a bug check for handling of nested loops; it goes
|
||
|
round the outer loop twice and the inner loop is skipped on the
|
||
|
first pass but run on the second
|
||
|
|
||
|
BTW: It's unlikely that an optimiser will notice how this works
|
||
|
|
||
|
>
|
||
|
+[>[
|
||
|
Print the exclamation point
|
||
|
[-]+++>
|
||
|
[-]+++++ +#-
|
||
|
[<+++2+++>-]<
|
||
|
.
|
||
|
|
||
|
<[-]>[-]]+<]
|
||
|
<
|
||
|
|
||
|
Clean up any debris
|
||
|
++++++++[[>]+[<]>-]>[>]<[[-]<]
|
||
|
|
||
|
This is a hard optimisation barrier
|
||
|
It contains several difficult to 'prove' constructions close together
|
||
|
and is likely to prevent almost all forms of optimisation
|
||
|
+[[>]<-[,]+[>]<-[]]
|
||
|
|
||
|
This part finds the actual value that the cell wraps at; even
|
||
|
if it's not one of the standard ones; but it gets bored after
|
||
|
a few thousand: any higher and we print nothing
|
||
|
|
||
|
This has a reasonably deep nested loop and a couple of loops
|
||
|
that have unbalanced pointer movements
|
||
|
|
||
|
Find maxint (if small)
|
||
|
[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<++++[->>++++>>++++>>++
|
||
|
++<<<<<<]++++++++++++++>>>>+>>++<<<<<<[->>[->+>[->+>[->+>+[>
|
||
|
>>+<<]>>[-<<+>]<-[<<<[-]<<[-]<<[-]<<[-]>>>[-]>>[-]>>[-]>->+]
|
||
|
<<<]>[-<+>]<<<]>[-<+>]<<<]>[-<+>]<<<]>+>[[-]<->]<[->>>>>>>[-
|
||
|
<<<<<<<<+>>>>>>>>]<<<<<<<]<
|
||
|
|
||
|
The number is only printed if we found the actual maxint
|
||
|
>+<[
|
||
|
Space
|
||
|
>[-]>[-]+++++[<++++++>-]<++.[-]<
|
||
|
|
||
|
Print the number
|
||
|
[[->>+<<]>>[-<++>[-<+>[-<+>[-<+>[-<+>[-<+>[-<+>[-<+>[-<+>[<[-]+>
|
||
|
->+<[<-]]]]]]]]]]>]<<[>++++++[<++++++++>-]<-.[-]<]]
|
||
|
|
||
|
]
|
||
|
|
||
|
Check if we should have had a value but didn't
|
||
|
>[
|
||
|
>[-]>[-]++++[<++++++++>-]<[<++++++++>-]>+++[<++++++++>-]<+++++++
|
||
|
[<-------->-]<------->+<[[-]>-<]>[>[-]<[-]++++[->++++++++<]>.+++
|
||
|
+++[-<++>]<.[-->+++<]>++.<++++[>----<-]>.[-]<]<
|
||
|
|
||
|
[-]>[-]++++++++[<++++++++>-]<[>++++<-]+>[<->[-]]<[>[-]<[-]++++[-
|
||
|
>++++++++<]>.---[-<+++>]<.---.--------------.[-->+<]>--.[-]<]
|
||
|
]<
|
||
|
|
||
|
Clean up any debris
|
||
|
++++++++[[>]+[<]>-]>[>]<[[-]<]
|
||
|
|
||
|
One last thing: an exclamation point is not a valid BF instruction!
|
||
|
|
||
|
Print the newline
|
||
|
[-]++++++++++.[-]
|
||
|
[
|
||
|
Oh, and now that I can use "!" the string you see should be one of:
|
||
|
Hello World! 255
|
||
|
Hello world! 65535
|
||
|
Hello, world!
|
||
|
|
||
|
And it should be followed by a newline.
|
||
|
]
|
||
|
|
||
|
===== END DEMO CODE =====
|
||
|
|
||
|
<< Finish at cell zero
|