packages feed

brainfuck-monad 0.0.1 → 0.1.0

raw patch · 2 files changed

+61/−35 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Control.Monad.BrainFuck: at :: Constants -> Integer -> BrainFuck ()
- Control.Monad.BrainFuck: cmd :: Char -> BrainFuck ()
- Control.Monad.BrainFuck: cmd' :: (DataPointer -> DataPointer) -> Char -> BrainFuck ()
+ Control.Monad.BrainFuck: Constants :: NumConstants -> Integer -> Constants
+ Control.Monad.BrainFuck: cat :: String
+ Control.Monad.BrainFuck: char :: Char -> BrainFuck ()
+ Control.Monad.BrainFuck: helloworld :: String
+ Control.Monad.BrainFuck: opcode :: Char -> BrainFuck ()
+ Control.Monad.BrainFuck: opcode' :: (DataPointer -> DataPointer) -> Char -> BrainFuck ()
+ Control.Monad.BrainFuck: pointAt :: Constants -> Integer -> BrainFuck ()
+ Control.Monad.BrainFuck: type NumConstants = Int
+ Control.Monad.BrainFuck: unchar :: Char -> BrainFuck ()
+ Control.Monad.BrainFuck: withChar :: Char -> BrainFuck a -> BrainFuck a
- Control.Monad.BrainFuck: brainfuckConstants :: (Constants -> BrainFuck a) -> String
+ Control.Monad.BrainFuck: brainfuckConstants :: NumConstants -> (Constants -> BrainFuck a) -> String

Files

Control/Monad/BrainFuck.hs view
@@ -1,8 +1,7 @@-{-# LANGUAGE EmptyDataDecls #-}- module Control.Monad.BrainFuck where  import qualified Control.Monad as M+import qualified Data.Char as Char  newtype BrainFuck a = BrainFuck (DataPointer -> ([Char], DataPointer, a)) @@ -25,21 +24,21 @@  next, prev, incr, decr, output, input, open, close :: BrainFuck () -- | move data pointer right-next = cmd' succ '>'+next = opcode' succ '>' -- | move data pointer left-prev = cmd' pred '<'+prev = opcode' pred '<' -- | increment data-incr = cmd '+'+incr = opcode '+' -- | decrement data-decr = cmd '-'+decr = opcode '-' -- | output byte at data pointer-output = cmd '.'+output = opcode '.' -- | input byte, storing at data pointer-input = cmd ','+input = opcode ',' -- | if byte at data pointer is zero, jump to command after close-open = cmd '['+open = opcode '[' -- | if byte at data pointer is nonzero, jump to command after matching open-close = cmd ']'+close = opcode ']'  add, sub :: Int -> BrainFuck () add = multi incr@@ -47,14 +46,14 @@  -- | Adds an arbitrary character to the program. -- Should not be used directly.-cmd :: Char -> BrainFuck ()-cmd = cmd' id+opcode :: Char -> BrainFuck ()+opcode = opcode' id  -- | Adds an arbitrary character to the program, -- and updates the data pointer. -- Should not be used directly.-cmd' :: (DataPointer -> DataPointer) -> Char -> BrainFuck ()-cmd' f x =  BrainFuck $ \loc -> ([x], f loc, ())+opcode' :: (DataPointer -> DataPointer) -> Char -> BrainFuck ()+opcode' f x =  BrainFuck $ \loc -> ([x], f loc, ())  -- | Run an action multiple times. multi :: BrainFuck () -> Int -> BrainFuck ()@@ -62,6 +61,23 @@ 	_ <- sequence (replicate n c) 	return () +-- | Assuming that the data pointer points to a 0, changes+-- it to the value of a Char.+char :: Char.Char -> BrainFuck ()+char = multi incr . Char.ord++-- | Undoes `char`+unchar :: Char.Char -> BrainFuck ()+unchar = multi decr . Char.ord++-- | Runs an action with the data pointer pointing at a Char.+withChar :: Char.Char -> BrainFuck a -> BrainFuck a+withChar c a = do+	char c+	r <- a+	unchar c+	return r+ -- | Gets the current address of the data pointer. addr :: BrainFuck DataPointer addr = BrainFuck $ \loc -> ([], loc, loc)@@ -76,38 +92,40 @@ 			then next >> setAddr n 			else return () --- | The loop is only entered if the byte at the data pointer is not zero.+-- | 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 when--- the byte at the data pointer is not zero.+-- On entry, the loop body is run, and then it loops, until the data+-- pointer points to 0. loopUnless0 :: BrainFuck () -> BrainFuck () loopUnless0 a = do 	open 	a 	close -data Constants+data Constants = Constants NumConstants Integer --- | Let's run programs with data cells 0-8 reserved to always contain--- the numbers 0 to 8.+type NumConstants = Int++-- | Let's run programs with data addresses 0..n reserved to always contain+-- the numbers n..0 -- -- These constants will make brainfuck quite a bit easier to use!-brainfuckConstants :: (Constants -> BrainFuck a) -> String-brainfuckConstants a = brainfuck $ do-	M.forM_ [0..8] $ \n -> do-		add n+brainfuckConstants :: NumConstants -> (Constants -> BrainFuck a) -> String+brainfuckConstants numconstants a = brainfuck $ do+	M.forM_ [0..numconstants] $ \n -> do+		add (numconstants - n) 		next-	a (undefined :: Constants)+	a (Constants numconstants 0)  -- | Sets data pointer to point to one of the Constants.-at :: Constants -> Integer -> BrainFuck ()-at _ = setAddr+pointAt :: Constants -> Integer -> BrainFuck ()+pointAt (Constants numconstants c) i = setAddr (c + fromIntegral numconstants - i) --- | Run an action in a loop, until it sets its data pointer to 0.+-- | Run an action in a loop, until the data pointer points to 0. loop :: Constants -> BrainFuck () -> BrainFuck () loop constants a = do 	here <- addr-	at constants 1+	pointAt constants 1 	loopUnless0 $ do 		setAddr here 		a@@ -116,14 +134,22 @@ forever :: Constants -> BrainFuck () -> BrainFuck () forever constants a = loop constants $ do 	a-	at constants 1+	pointAt constants 1 --- | Prints out the ASCII table, starting with space, repeatedly.+-- | Prints out the ASCII characters, starting with space, repeatedly. --  -- TODO: Only print printable characters. demo :: String-demo = brainfuckConstants $ \constants -> do-	add 32+demo = brainfuckConstants 1 $ \constants -> do+	add $ Char.ord ' ' 	forever constants $ do 		add 1 		output++cat :: String+cat = brainfuckConstants 1 $ flip forever $ input >> output++helloworld :: String+helloworld = brainfuck $+	M.forM_ "hello, world!" $+		flip withChar output
brainfuck-monad.cabal view
@@ -1,5 +1,5 @@ Name: brainfuck-monad-Version: 0.0.1+Version: 0.1.0 Cabal-Version: >= 1.8 License: BSD3 Maintainer: Joey Hess <id@joeyh.name>@@ -8,7 +8,7 @@ Copyright: 2014 Joey Hess License-File: LICENSE Build-Type: Simple-Category: Utility+Category: Compilers/Interpreters Synopsis: BrainFuck monad Description:  This is a BrainFuck monad, for generating brainfuck programs.