yabi 0.1.1.0 → 0.2.0.0
raw patch · 2 files changed
+34/−16 lines, 2 files
Files
- yabi.cabal +5/−1
- yabi.hs +29/−15
yabi.cabal view
@@ -1,5 +1,5 @@ name: yabi-version: 0.1.1.0+version: 0.2.0.0 synopsis: Yet Another Brainfuck Interpreter description: Yet Another Brainfuck Interpreter. Usage: yabi path homepage: https://github.com/fgaz/yabi@@ -12,6 +12,10 @@ build-type: Simple -- extra-source-files: cabal-version: >=1.10++source-repository head+ type: git+ location: git://github.com/fgaz/yabi.git executable yabi main-is: yabi.hs
yabi.hs view
@@ -1,19 +1,32 @@ import Data.Word8 (Word8) import Data.Char (ord, chr) import System.Environment (getArgs)-import System.IO (readFile, putChar, getChar, stdout, stdin, hSetBuffering, BufferMode (NoBuffering))+import Control.Monad (when)+import System.IO+ ( readFile, putChar, getChar, hPutStrLn,+ stdout, stdin, stderr,+ hSetBuffering, BufferMode (NoBuffering) ) import System.Exit (exitFailure) --represents a bf instruction or a loop-data Instruction = Plus | Minus | Next | Prev | Input | Output | Loop [Instruction] | MDump | PDump deriving (Show, Eq)+data Instruction = Plus+ | Minus+ | Next+ | Prev+ | Input+ | Output+ | Loop [Instruction]+ | MDump+ | PDump+ deriving (Show, Eq) type Program = [Instruction] --the memory zipper: (left, pointer:right)-type Memory = ([Word8],[Word8])+type Memory = ([Word8], [Word8]) --the default memory, an infinite zipper filled with zeros defaultMemory :: Memory-defaultMemory = ((repeat 0),(repeat 0))+defaultMemory = (repeat 0, repeat 0) --breaks a string when the brackets are balanced --an open bracket adds 1 to the balance, a closed one subtracts 1@@ -22,7 +35,7 @@ breakWhenBalanced balance (s:str) | s == '[' = let (first, second) = breakWhenBalanced (balance+1) str in (s:first, second) | s == ']' = let (first, second) = breakWhenBalanced (balance-1) str in (s:first, second) | otherwise = let (first, second) = breakWhenBalanced balance str in (s:first, second)-breakWhenBalanced balance [] = error $ "malformed code, brackets balance off by " ++ (show balance)+breakWhenBalanced balance [] = error $ "malformed code, brackets balance off by " ++ show balance --parse a string to a Program@@ -46,7 +59,7 @@ char2instruction ',' = Just Input char2instruction '#' = Just MDump char2instruction '§' = Just PDump --i picked a random not-widely-used character for this-char2instruction _ = Nothing --comments+char2instruction _ = Nothing --comments --the actual interpreter bf :: Program -> Memory -> IO Memory@@ -75,13 +88,13 @@ --debug --memory dump ('#', according to Urban Müller's original interpreter) bf (MDump:commands) (ml,m:mr) = do- putStrLn "Memory dump:"- putStrLn $ " " ++ (show $ takeWhile (/=0) ml) ++ " >" ++ (show m) ++ "< " ++ (show $ takeWhile (/=0) mr)+ hPutStrLn stderr "Memory dump:"+ hPutStrLn stderr $ " " ++ show (takeWhile (/=0) ml) ++ " >" ++ show m ++ "< " ++ show (takeWhile (/=0) mr) bf commands (ml,m:mr) --program dump bf (PDump:commands) memory = do- putStrLn "Program dump:"- putStrLn $ " " ++ (show commands)+ hPutStrLn stderr "Program dump:"+ hPutStrLn stderr $ " " ++ show commands bf commands memory --catch-all pattern. I have yet to discover a way to fall down there --whitout the infinite zipper it would be out of memory@@ -91,18 +104,19 @@ main :: IO () main = do args <- getArgs- if length args /= 1 then do+ when (length args /= 1) $ do putStrLn "Usage: yabi path" exitFailure- else return () rawProgram <- readFile $ head args- putStrLn "[yabi] Parsing..."+ hPutStrLn stderr "[yabi] Parsing..." --parse the program string let program = bfParse rawProgram []- putStrLn "[yabi] Parsed. Executing..."+ hPutStrLn stderr "[yabi] Parsed. Executing..." --disable buffering hSetBuffering stdout NoBuffering hSetBuffering stdin NoBuffering --start the interpreter- bf program defaultMemory+ --we need the side effects, not the final memory, hence `_ <-`+ _ <- bf program defaultMemory return ()+