Well its that time of year again when you can either conform and buy your significant other a box of chocolates and fist of flowers and watch her dreary eyed try to remember when your relationship actually was exciting or, or you could give her…… a brainfuck program! This feat of extraordinary thoughtfulness will undoubtedly poke her memories of that juvenile lust that once saturated your affair. So get with loop and increment your chances of popping your stack on the 14 of February! Heap… Moving along; for this experiment you will need the following things:

The Glasgow Haskell Compiler (GHC) Graphics.HGL 3.2.0.0

Extending SamBs brainfuck interpreter with a visual representation of the brainfuck machines memory.

What we are going to do is extend this excellent brainfuck interpreter written by SamB with a UI that shows the content of the memory. The memory will be displayed as oversized pixels varying in redness depending on their value.

First lets import two libraries we are going to need later on:



import System.Posix (usleep)

import Graphics.HGL hiding (char)



We are going to use usleep so delay the execution of the program so we can see the memory cells update in realtime and HGL is for creating this display.

Next we need to change the StateT encapsulation to include our display window and the initial pointer (this is so we can calculate which cell we are at). There is no need for something fancy so we do this by just creating a nested tuple.



type BF a b = StateT (Ptr a, (Ptr a, Window)) IO b



Taking care to change the definition of the functions to satisfy this new type requirement (change read, write etc..).

Now lets add a higher-order function called update that will update both the memory and the display window.

update :: (Storable a, Integral a) => (a -> a -> a) -> BF a () update f = do x <- read (p,(i, w)) <- get let n = fromEnum $ (ptrToIntPtr p) - (ptrToIntPtr i) let a = (f x 1) liftIO (cell w n (toEnum $ fromEnum a)) write a

And now the definitions of incr and decr become very short:



incr = update (+)

decr = update (-)



You may have noticed in the update function that we reference a function that is not defined (cell); so lets define it:

cell :: Window -> Int -> Word8 -> IO () cell w n v = do let s = 50 (x, _) <- getWindowSize w q <- createBrush (RGB v 0 0) let (a, b) = quotRem (n * s) x let c = (regionToGraphic $ rectangleRegion (b, a * s) (b + s, (a * s) + s)) drawInWindow w (withBrush q c) usleep 500

Now if you have been enough of a £33+ type jockey all we will have to do is add a slightly different main function.

main :: IO () main = runGraphics $ do (name:[]) <- getArgs source <- readFile name w <- openWindow "Memory" (600, 600) tape <- (mallocBytes 10000 :: IO (Ptr Word8)) (either print (`evalStateT` (tape, (tape, w)))) (parse parseInstrs name source)

Now we are good to go and if you dont have the patience to edit the source yourself here is as

they say on TV something i prepared earlier:

BrainfuckHGL.hs.

Brianfuck programs and their memory footprint.

First lets test our visualization, assuming you saved the source to a file called BrainfuckHGL.hs; create a file called Pulse and add:



+[>-[-]+]



And to test; run this at the shell:



runhaskell BrainfuckHGL.hs Pulse



The output should look something like this:

with the square moving to the right and “pulsating”.

Now for something a little more complicated; a program that prints out a list squares.



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

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



I won’t bother taking a screenshot of this but if you squint a little you can make out the memory cells flashing as their values change. If you change the definition of cell to use the color white it’s easier to make out the values.

A portrait of the brainfuck programmer as a young man.

And now for the finale we are going to create some cheesy valentines art with brainfuck. We have here a canvas that is 12/12 pixles of varying degrees of redness. The first little masterpiece we are going to create is a simple static heart:



;; To set a cell to 255 just decrement it from 0

>>>>>>>>>>>>

>>>->->>>->->>>>

>>->->->->->->->->>>

>->->->->->->->->->->>

>->->->->->->->->->->>

>->->->->->->->->->->>

>->->->->->->->->->->>

>>->->->->->->->->>>

>>>->->->->->->>>>

>>>>->->->->>>>>

>>>>>->->>>>>>





Not too hard, just move the cursor around and set the correct cells to 255. Now lets do some aliasing. Here is

a heart with some random aliasing and some verbose coding.



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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





After this lets really flex our muscles and add pulsating effect to our heart too really drive home that this is

a labor of love. This effect is achieved by using a buffer cell off screen that repeats with a 39 step period. There is

alot of boiler plate because you have to move between the cells you want to update and the buffer.

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

There is no screenshot here but it’s basically the same as the aliased heart but with a couple cells “beating”.

That’s it; send these brainfuck programs to your loved ones and watch them amaze at your tedious personality!

P.S If you have created something yourself please let me know; it would be awesome to see some other examples. Also a

possible extension could be to union three cells to create the full RGB scale.