fork download
  1. data Op
  2. = Change Int -- +, -
  3. | Move Int -- >, <
  4. | OutP -- .
  5. | InP -- ,
  6. | Loop [Op] -- [...]
  7. | Proc [Op] -- (...)
  8. | Call -- :
  9. deriving (Show, Eq)
  10.  
  11. parse :: String -> [Op]
  12. parse = fst . parseAccum [] Nothing
  13.  
  14. parseAccum :: [Op] -> Maybe Char -> String -> ([Op], String)
  15. parseAccum acc Nothing "" = (reverse acc, "")
  16. parseAccum acc (Just x) "" = error $ "parse error: expected " ++ [x] -- todo
  17. parseAccum acc end ('+' : src) = parseAccum (Change 1 : acc) end src
  18. parseAccum acc end ('-' : src) = parseAccum (Change (-1) : acc) end src
  19. parseAccum acc end ('>' : src) = parseAccum (Move 1 : acc) end src
  20. parseAccum acc end ('<' : src) = parseAccum (Move (-1) : acc) end src
  21. parseAccum acc end ('.' : src) = parseAccum (OutP : acc) end src
  22. parseAccum acc end (',' : src) = parseAccum (InP : acc) end src
  23. parseAccum acc end (':' : src) = parseAccum (Call : acc) end src
  24. parseAccum acc end ('[' : src) = parseAccum (op : acc) end src' where (op, src') = parseBlock src ']' Loop
  25. parseAccum acc end ('(' : src) = parseAccum (op : acc) end src' where (op, src') = parseBlock src ')' Proc
  26. parseAccum acc Nothing (_ : src) = parseAccum acc Nothing src
  27. parseAccum acc e@(Just end) (c : src)
  28. | c == end = (reverse acc, src)
  29. | otherwise = parseAccum acc e src
  30.  
  31. parseBlock :: String -> Char -> ([Op] -> Op) -> (Op, String)
  32. parseBlock src end ctor =
  33. mapFst ctor $ parseAccum [] (Just end) src
  34.  
  35. mapFst f (x, y) = (f x, y)
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty