Execute Brain****/Haskell: Difference between revisions

m
Fixed syntax highlighting.
(unsafePerformIO sounds scary)
m (Fixed syntax highlighting.)
 
(7 intermediate revisions by 7 users not shown)
Line 1:
{{implementation|Brainf***}}{{collection|RCBF}}[[Category:Haskell]]
Quick implementation of a [[Brainfuck]] interpreter in [[Haskell]].
 
Pairs of lists are used to implement both the two-side infinite band of cells, and the program storage. This means that it can also work on infinite Brainfuck programs (which could be generated lazily).
Line 8:
A more efficient implementation could for example only admit well-bracketed brainfuck programs, and parse bracket blocks first, to replace the ''matchLeft'' and ''matchRight'' which need linear time.
 
<syntaxhighlight lang="haskell">module BF where
moveLeft (x:l,r) = (l,x:r)
 
moveRight (l,x:r) = (x:l,r)
moveLeft (x:l,r) = (l,x:r)
moveRight (l,x:r) = (x:l,r)
matchLeft d@('[':_,_) = d
 
matchLeft d@(']':_,_) = matchLeft $ moveLeft $ matchLeft $ moveLeft $ d
matchLeft d @('[':_,_) = matchLeft $ moveLeft $ d
matchLeft d@(']':_,_) = matchLeft $ moveLeft $ matchLeft $ moveLeft $ d
matchLeft d = matchLeft $ moveLeft $ d
matchRight d@(_,']':_) = moveRight $ d
 
matchRight d@(_,'[':_) = matchRight $ matchRight $ moveRight $ d
matchRight d @(_,']':_) = matchRight $ moveRight $ d
matchRight d@(_,'][':_) = matchRight $ matchRight $ moveRight $ d
matchRight d@(_,'[':_) = matchRight $ = matchRight $ moveRight $ d
pad ([],[]) = ([0],[0])
 
pad ([],r) = ([0],r)
pad (l[],[]) = (l[0],[0])
pad d ([],r) = d([0],r)
pad ([]l,[]) = ([0]l,[0])
pad d = d
modify f (l,x:r) = (l,(f x):r)
 
modify f (l,x:r) = (l,(f x):r)
exec :: (String, String) -> ([Integer], [Integer]) -> [Integer] -> [Integer]
 
exec (_,[]) _ _ = []
exec :: (String, String) -> ([Integer], [Integer]) -> [Integer] -> [Integer]
exec p@(_,'>':_) d cs = exec (moveRight p) (pad $ moveRight $ d) cs
exec p@ (_,'<':_[]) d _ cs = exec (moveRight_ p) (pad $ moveLeft $ d)= cs[]
exec p@(_,'+>':_) d cs = exec (moveRight p) (modifypad (+$ 1)moveRight $ d) cs
exec p@(_,'-<':_) d cs = exec (moveRight p) (modifypad (-$ 1)moveLeft $ d) cs
exec p@(_,',+':_) d (c: cs) = exec (moveRight p) (modify (const+ c1) d) cs
exec p@(_,'.-':_) d@(_,x:_) cs = x : cs = exec (moveRight p) (modify (subtract 1) d) cs
exec p@(_,'[,':_) d@ (_,0c:_cs) cs = exec (matchRightmoveRight $p) moveRight(modify $(const pc) d) cs
exec p@(_,'[.':_) d @(_,x:_) cs = x : exec (moveRight p) d cs
exec p@(_,'][':_) d@(_,0:_) cs = exec (matchRight $ moveRight $ p) d cs
exec p@(_,'][':_) d cs = exec (matchLeft $ moveLeft $moveRight p) d cs
exec p@(_,'>]':_) d @(_,0:_) cs = exec (moveRight p) (pad $ moveRight $ d) cs
exec p@(_,']':_) d cs = exec (matchLeft $ moveLeft $ p) d cs
run :: String -> [Integer] -> [Integer]
 
run s = exec ([],s) ([0],[0])
run :: String -> [Integer] -> [Integer]
padrun s = exec ([],rs) = ([0],r[0])
dialog :: String -> IO ()
 
dialog s = mapM_ print . run s . map read . lines =<< getContents
dialog :: String -> IO ()
dialog s = mapM_ print . run s . map read . lines =<< getContents
</syntaxhighlight>(This version compiles with GHC and will run if loaded into ghci using ':load BF')
 
Example session:
 
<pre>
: *Main> dialog ",[>+<-].>."
: ''5''
: 0
: 5
</pre>
9,476

edits