packages feed

brainfuck-monad 0.4.0 → 0.5.0

raw patch · 4 files changed

+90/−13 lines, 4 filesdep +directorydep +processsetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: directory, process

API changes (from Hackage documentation)

- Control.Monad.BrainFuck: instance Monad BrainFuck
+ Control.Monad.BrainFuck: compile :: FilePath -> BrainFuck () -> IO ()
+ Control.Monad.BrainFuck: demo' :: BrainFuck ()
+ Control.Monad.BrainFuck: instance GHC.Base.Applicative Control.Monad.BrainFuck.BrainFuck
+ Control.Monad.BrainFuck: instance GHC.Base.Functor Control.Monad.BrainFuck.BrainFuck
+ Control.Monad.BrainFuck: instance GHC.Base.Monad Control.Monad.BrainFuck.BrainFuck
+ Control.Monad.BrainFuck: ld :: FilePath -> FilePath -> IO ()
+ Control.Monad.BrainFuck: movfuscate :: BrainFuck () -> IO ASM
+ Control.Monad.BrainFuck: nasm :: FilePath -> ASM -> IO FilePath
+ Control.Monad.BrainFuck: type ASM = String

Files

+ CHANGELOG view
@@ -0,0 +1,12 @@+brainfuck-monad (0.5.0) unstable; urgency=medium++  * Applicative instance.+  * Can use movfuscator to build elf executables.++ -- Joey Hess <id@joeyh.name>  Fri, 25 Sep 2015 16:01:03 -0400++brainfuck-monad (0.4.0) unstable; urgency=low++  * First release.++ -- Joey Hess <joeyh@debian.org>  Wed, 02 Apr 2014 13:57:42 -0400
Control/Monad/BrainFuck.hs view
@@ -1,10 +1,19 @@+{-# LANGUAGE DeriveFunctor #-}+ module Control.Monad.BrainFuck where  import qualified Control.Monad as M+import Control.Applicative+import Control.Monad (ap) import qualified Data.Char as Char import Data.Word (Word8)+import System.Process+import System.IO+import System.Exit+import System.Directory  newtype BrainFuck a = BrainFuck (DataPointer -> ([Char], DataPointer, a))+	deriving (Functor)  type DataPointer = Integer @@ -17,13 +26,17 @@ brainfuck (BrainFuck f) = bytes where (bytes, _, _) = f 0  instance Monad BrainFuck where-	return ret = BrainFuck $ \loc -> ([], loc, ret)+	return = pure 	a >>= b = BrainFuck $ \start -> let 		(left, mid, val) = func a start 		(right, end, ret) = func (b val) mid 		in (left ++ right, end, ret) -next, prev, incr, decr, output, input, open, close :: BrainFuck ()+instance Applicative BrainFuck where+	pure v = BrainFuck $ \loc -> ([], loc, v)+	(<*>) = ap++next, prev, incr, decr, output, input, open, close, debug :: BrainFuck () -- | move data pointer right next = opcode' succ '>' -- | move data pointer left@@ -163,9 +176,9 @@ -- current memory cell, or allocate and use new ones, and will not -- exit the loop. forever :: BrainFuck a -> BrainFuck ()-forever a = loopFrom 1 $ \i ->-	alloc' $ \scratch -> do-		a+forever a = loopFrom 1 $ \_i ->+	alloc' $ \_scratch -> do+		_ <- a 		return ()  -- | Copies the value of a cell.@@ -255,7 +268,7 @@ 		setAddr c1 		loopUnless0 $ do 			decr-			loopFrom y $ \c2 -> do+			loopFrom y $ \_c2 -> do 				decr 				setAddr x 				incr@@ -269,7 +282,7 @@ 	-- Get to letter 104 ('a' is 97) quickly by multiplication. 	start = do 		zero-		x <- addr+		_x <- addr 		add 13 		mult 8 		return (13 * 8)@@ -289,7 +302,10 @@ -- | Prints out the alphabet, repeatedly, with some whitespace fun -- to make it more interesting. demo :: String-demo = brainfuck $ alloc' $ \tilt -> do+demo = brainfuck demo'++demo' :: BrainFuck () +demo' = alloc' $ \tilt -> do 	settilt 	alloc' $ \tc -> do 		decr -- set to 255@@ -297,7 +313,7 @@ 			copy tilt wc 			forever $ alloc' $ \c -> do 				set (fromIntegral start)-				loopFrom (fromIntegral numchars) $ \i -> do+				loopFrom (fromIntegral numchars) $ \_i -> do 					decr 		 					withAddr wc decr@@ -397,3 +413,48 @@ 	-- Any sequence of > and < at the end of a program is a noop. 	trimend = reverse . dropWhile (`elem` "><") . reverse +-- | 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.+compile :: FilePath -> BrainFuck () -> IO ()+compile dest b = movfuscate b >>= nasm dest >>= ld dest++type ASM = String++movfuscate :: BrainFuck () -> IO ASM+movfuscate b = do+	(Just hin, Just hout, Nothing, h) <- createProcess $+		(proc "movfuscator" [])+			{ std_out = CreatePipe+			, std_in = CreatePipe+			}+	hPutStr hin $ optimize $ brainfuck b+	hClose hin+	asm <- hGetContents hout+	writeFile "asm" asm+	c <- waitForProcess h+	case c of+		ExitSuccess -> return ()+		_ -> error ("movfuscator exited nonzero")+	return asm++nasm :: FilePath -> ASM -> IO FilePath+nasm dest a = do+	-- nasm needs a real file, can't use stdin+	writeFile asmfile a+	callProcess "nasm" ["-felf", asmfile, "-o", objfile]+	removeFile asmfile+	return objfile+  where+	asmfile = dest ++ ".asm"+	objfile = dest ++ ".o"++ld :: FilePath -> FilePath -> IO ()+ld dest objfile = do+	callProcess "ld" ["-melf_i386", objfile, "-o", dest]+	removeFile objfile
Setup.hs view
@@ -1,2 +1,5 @@+{- cabal setup file -}+ import Distribution.Simple+ main = defaultMain
brainfuck-monad.cabal view
@@ -1,5 +1,5 @@ Name: brainfuck-monad-Version: 0.4.0+Version: 0.5.0 Cabal-Version: >= 1.8 License: BSD3 Maintainer: Joey Hess <id@joeyh.name>@@ -12,12 +12,13 @@ Synopsis: BrainFuck monad Description:  This is a BrainFuck monad, for generating brainfuck programs.+Extra-Source-Files: CHANGELOG  Library-  GHC-Options: -Wall+  GHC-Options: -Wall -fno-warn-tabs   Exposed-Modules: Control.Monad.BrainFuck-  Build-Depends: base (>= 4.5), base < 5+  Build-Depends: base (>= 4.5), base < 5, process, directory  source-repository head   type: git-  location: git://git.kitenet.net/brainfuck-monad.git+  location: git://git.joeyh.name/brainfuck-monad.git