Safe Haskell | Safe |
---|---|
Language | Haskell98 |
- newtype BrainFuck a = BrainFuck (DataPointer -> ([Char], DataPointer, a))
- type DataPointer = Integer
- func :: BrainFuck f -> DataPointer -> ([Char], DataPointer, f)
- brainfuck :: BrainFuck f -> String
- next :: BrainFuck ()
- prev :: BrainFuck ()
- incr :: BrainFuck ()
- decr :: BrainFuck ()
- output :: BrainFuck ()
- input :: BrainFuck ()
- open :: BrainFuck ()
- close :: BrainFuck ()
- debug :: BrainFuck ()
- opcode :: Char -> BrainFuck ()
- opcode' :: (DataPointer -> DataPointer) -> Char -> BrainFuck ()
- loopUnless0 :: BrainFuck a -> BrainFuck a
- addr :: BrainFuck DataPointer
- setAddr :: Integer -> BrainFuck ()
- withAddr :: Integer -> BrainFuck a -> BrainFuck a
- multi :: BrainFuck () -> Int -> BrainFuck ()
- add :: Word8 -> BrainFuck ()
- sub :: Word8 -> BrainFuck ()
- zero :: BrainFuck ()
- set :: Word8 -> BrainFuck ()
- alloc :: BrainFuck a -> BrainFuck a
- alloc' :: (DataPointer -> BrainFuck a) -> BrainFuck a
- withChar :: Char -> BrainFuck a -> BrainFuck a
- loopFrom :: Word8 -> (DataPointer -> BrainFuck ()) -> BrainFuck ()
- forever :: BrainFuck a -> BrainFuck ()
- copy :: DataPointer -> DataPointer -> BrainFuck ()
- withNot :: DataPointer -> BrainFuck () -> BrainFuck ()
- unless0 :: DataPointer -> BrainFuck () -> BrainFuck ()
- when0 :: DataPointer -> BrainFuck () -> BrainFuck ()
- if0 :: DataPointer -> (BrainFuck (), BrainFuck ()) -> BrainFuck ()
- sumNext :: BrainFuck ()
- mult :: Word8 -> BrainFuck ()
- display :: String -> BrainFuck ()
- demo :: String
- demo' :: BrainFuck ()
- cat :: String
- helloworld :: String
- helloworld' :: String
- optimize :: String -> String
- compile :: FilePath -> BrainFuck () -> IO ()
- type ASM = String
- movfuscate :: BrainFuck () -> IO ASM
- nasm :: FilePath -> ASM -> IO FilePath
- ld :: FilePath -> FilePath -> IO ()
Documentation
BrainFuck (DataPointer -> ([Char], DataPointer, a)) |
type DataPointer = Integer Source
func :: BrainFuck f -> DataPointer -> ([Char], DataPointer, f) Source
Retrieve the inner function
opcode :: Char -> BrainFuck () Source
Adds an arbitrary character to the program. Should not be used directly.
opcode' :: (DataPointer -> DataPointer) -> Char -> BrainFuck () Source
Adds an arbitrary character to the program, and updates the data pointer. Should not be used directly.
loopUnless0 :: BrainFuck a -> BrainFuck a Source
The loop is only run if the data pointer doesn't point to 0.
On entry, the loop body is run, and then it loops, until the address the data pointer originally pointed at has a value of 0.
Any change that the loop body makes to the address of the data pointer is reset each time through the loop (and at the end). This is necessary to keep the BrainFuck monad's DataPointer consistent no matter what happens when running the loop.
addr :: BrainFuck DataPointer Source
Gets the current address of the data pointer.
withAddr :: Integer -> BrainFuck a -> BrainFuck a Source
Runs an action with the data pointer temporarily set to an address, then restores the data pointer.
set :: Word8 -> BrainFuck () Source
Changes the current data cell to contain a specific value. (It can start at any value).
alloc :: BrainFuck a -> BrainFuck a Source
For higher-level programming in brainfuck, it's useful to have a way to run a function, while allocating a memory cell, which is initialized to contain 0.
This and many of the functions below assume that cells to the left are in use, while cells to the right are unused and may contain any data. Higher-level functions should generally avoid changing the current cell, and should instead alloc a new one to use.
alloc' :: (DataPointer -> BrainFuck a) -> BrainFuck a Source
withChar :: Char -> BrainFuck a -> BrainFuck a Source
Allocates a new memory cell, populates it with a Char, and runs the action.
loopFrom :: Word8 -> (DataPointer -> BrainFuck ()) -> BrainFuck () Source
Allocates a cell and uses it as the loop counter, starting from the provided value. The action will continue running in a loop until it decrements the counter to 0.
forever :: BrainFuck a -> BrainFuck () Source
Runs an action in an infinite loop. The action can modify its current memory cell, or allocate and use new ones, and will not exit the loop.
copy :: DataPointer -> DataPointer -> BrainFuck () Source
Copies the value of a cell.
withNot :: DataPointer -> BrainFuck () -> BrainFuck () Source
Runs the action with a new cell that is logically NOT the value of the passed pointer.
unless0 :: DataPointer -> BrainFuck () -> BrainFuck () Source
Runs the action unless the data pointer points to 0.
when0 :: DataPointer -> BrainFuck () -> BrainFuck () Source
Runs the action when the data pointer points to 0.
if0 :: DataPointer -> (BrainFuck (), BrainFuck ()) -> BrainFuck () Source
Monadic if; the first action is run if the data pointer points to 0, else the second action is run.
sumNext :: BrainFuck () Source
Adds the current and next data cells. The next cell is zeroed and the sum is left in the current cell.
mult :: Word8 -> BrainFuck () Source
Multiplies the current data cell by some value. Uses and zeros some of the following cells.
display :: String -> BrainFuck () Source
Displays a string. Tries to generate a fairly small brainfuck program, using a few encoding tricks. The current cell is modified, and not cleaned up at the end, so run using alloc if necessary.
Prints out the alphabet, repeatedly, with some whitespace fun to make it more interesting.
Simple hello world.
Optimized to use less space.
compile :: FilePath -> BrainFuck () -> IO () Source
Uses the MOVfuscator v1 to build a Linux executable from a BrainFuck monad action. The executable is implemented entirely using the MOV instruction. It may be a little slow, especially when loops are involved.
Prereq: Clone https://github.com/xoreaxeaxeax/movfuscator, build the v1 brainfuck to MOV compiler (in the poc/) directory, and put it in PATH. Also apt-get install nasm.
movfuscate :: BrainFuck () -> IO ASM Source