packages feed

parsley-1.0.0.1: benchmarks/BrainfuckBench/Handrolled/Parser.hs

module BrainfuckBench.Handrolled.Parser where
import BrainfuckBench.Shared

brainfuck :: String -> Maybe [BrainFuckOp]
brainfuck input =
  let walk :: String -> [BrainFuckOp] -> Maybe ([BrainFuckOp], String)
      walk [] acc            = return (reverse acc, [])
      walk input@(']':_) acc = return (reverse acc, input)
      walk (c:rest) acc      = case c of
        '>' -> walk rest (RightPointer:acc)
        '<' -> walk rest (LeftPointer:acc)
        '+' -> walk rest (Increment:acc)
        '-' -> walk rest (Decrement:acc)
        '.' -> walk rest (Output:acc)
        ',' -> walk rest (Input:acc)
        '[' -> do (body, rest') <- loop rest; walk rest' (Loop body:acc)
        _   -> walk rest acc
      loop :: String -> Maybe ([BrainFuckOp], String)
      loop input = do
        (body, rest) <- walk input []
        case rest of
          ']':rest' -> return (body, rest')
          _ -> fail "unclosed loop"
  in  do
    (res, []) <- walk input []
    return res