module Parser(parseProgram) where import AST parseProgram :: String -> Either String Program parseProgram src = do (inss, "") <- parseLoop 0 src return $ Program $ IStart : inss parseLoop :: Int -> String -> Either String ([Instruction], String) parseLoop 0 "" = Right ([], "") parseLoop _ "" = Left "More '[' than ']'" parseLoop 0 (']':_) = Left "Unexpected ']'" parseLoop _ (']':cs) = Right ([], cs) parseLoop d ('[':cs) = do (lp, rest) <- parseLoop (d+1) cs (after, rest') <- parseLoop d rest return (ILoop lp 0 : after, rest') parseLoop d (c:cs) | Just ins <- parseSimple c = do (lp, rest) <- parseLoop d cs return (ins:lp, rest) parseLoop d (_:cs) = parseLoop d cs parseSimple :: Char -> Maybe Instruction parseSimple '+' = Just $ IAdd 1 0 parseSimple '-' = Just $ IAdd (negate 1) 0 parseSimple '>' = Just $ ISlide 1 parseSimple '<' = Just $ ISlide (-1) parseSimple ',' = Just $ IInput 0 parseSimple '.' = Just $ IOutput 0 parseSimple _ = Nothing