module Parser (Parser, main) where
import Data.Char (isDigit, isSpace, isUpper, isLower, isAlphaNum)
import Control.Applicative
import Data.Maybe
import Data.Functor
import Text.ParserCombinators.ReadP
takeWhileSplit :: (t -> Bool) -> [t] -> ([t], [t])
takeWhileSplit _ [] = ([], [])
takeWhileSplit f (x:xs)
| f x = (x:collected, rest)
| otherwise = ([], xs)
where (collected, rest) = takeWhileSplit f xs
newtype Parser a = Parser { runParser :: String -> (String, Maybe a) }
instance Functor Parser where
fmap f (Parser p) = Parser $ \s ->
let (s', mf) = p s
in (s', f <$> mf)
instance Applicative Parser where
pure x = Parser $ \s -> (s, Just x)
Parser pf <*> Parser px = Parser $ \s ->
let (s1, mf) = pf s
(s2, mx) = px s1
in (s2, mf <*> mx)
instance Alternative Parser where
empty = Parser $ \s -> (s, Nothing)
Parser p <|> Parser q = Parser $ \s ->
case (p s, q s) of
(lhs@(_, Just _), _) -> lhs
(_, rhs) -> rhs
parseDigit :: Parser Char
parseDigit = Parser p
where
p "" = ("", Nothing)
p (x:xs)
| x `elem` ['0'..'9'] = (xs, Just x)
| otherwise = (xs, Nothing)
parseInt :: Parser Integer
parseInt = read <$> some parseDigit
data Unary = Output | Prompt | Bang deriving(Show)
parseUnary :: Parser Unary
parseUnary = string "OUTPUT" $> Output
<|> string "PROMPT" $> Prompt
<|> char '!' $> Bang
main =
let (_, x) = runParser parseUnary "OUTPUT"
in print (fromJust x)