module Language.Brainfuck.Parse (
parse,
matchJumps,
JumpPairs
) where
import Language.Brainfuck.Types (Term(..))
parse :: String -> [Term]
parse [] = []
parse (x:xs) = case x of
'>' -> IncDP : parse xs
'<' -> DecDP : parse xs
'?' -> OutDP : parse xs
'+' -> IncByte : parse xs
'-' -> DecByte : parse xs
'.' -> OutByte : parse xs
',' -> InByte : parse xs
'[' -> JumpForward : parse xs
']' -> JumpBackward : parse xs
_ -> parse xs
data JumpMatchError
= ForwardJumpNotMatched Int
| BackwardJumpNotMatched Int deriving Show
type JumpPairs = [(Int,Int)]
matchJumps :: [Term] -> Either JumpPairs JumpMatchError
matchJumps ts' = go ts' [] 0 []
where go (JumpForward:t:ts) acc pos ret = go (t:ts) (pos:acc) (pos+1) ret
go (JumpBackward:ts) (p:acc) pos ret = go ts acc (pos+1) ((p,pos):ret)
go (JumpBackward:_) [] pos _ = Right $ BackwardJumpNotMatched pos
go [JumpForward] _ pos _ = Right $ ForwardJumpNotMatched pos
go [] (p:_) _ _ = Right $ ForwardJumpNotMatched p
go [] [] _ ret = Left ret
go (_:ts) acc pos ret = go ts acc (pos+1) ret