never executed always true always false
    1 module HelVM.HelMA.Automata.BrainFuck.Impl.Fast.Parser (
    2   parseWithOptimizeSafe,
    3   parseAsListSafe,
    4   parseWithOptimize,
    5   parseAsList,
    6 ) where
    7 
    8 import           HelVM.HelMA.Automata.BrainFuck.Impl.Fast.Instruction
    9 import           HelVM.HelMA.Automata.BrainFuck.Impl.Fast.Optimizer
   10 
   11 import qualified HelVM.HelMA.Automata.BrainFuck.Common.SimpleInstruction as Simple
   12 
   13 import           HelVM.HelMA.Automaton.API.IOTypes
   14 import           HelVM.HelMA.Automaton.ReadPExtra
   15 
   16 import           HelVM.HelIO.Control.Safe
   17 
   18 import           Control.Applicative.Tools
   19 
   20 import qualified Data.Text                                               as Text
   21 
   22 import           Text.ParserCombinators.ReadP                            hiding (many)
   23 
   24 parseWithOptimizeSafe :: Source -> Safe FastInstructionList
   25 parseWithOptimizeSafe = parseWithOptimize
   26 
   27 parseAsListSafe :: Source -> Safe FastInstructionList
   28 parseAsListSafe = parseAsList
   29 
   30 parseWithOptimize :: MonadSafe m => Source -> m FastInstructionList
   31 parseWithOptimize = optimize <.> parseAsList
   32 
   33 parseAsList :: MonadSafe m => Source -> m FastInstructionList
   34 parseAsList = runParser parameterizedInstructionsParser . filterComments
   35 
   36 parameterizedInstructionsParser :: ReadP FastInstructionList
   37 parameterizedInstructionsParser = many1 parameterizedInstructionParser
   38 
   39 parameterizedInstructionParser :: ReadP FastInstruction
   40 parameterizedInstructionParser =
   41       moveRParser <|> moveLParser
   42   <|> incParser   <|> decParser
   43   <|> outParser   <|> inParser
   44   <|> whileParser
   45 
   46 moveRParser :: ReadP FastInstruction
   47 moveRParser = Move 1 <$ char '>'
   48 
   49 moveLParser :: ReadP FastInstruction
   50 moveLParser = Move negate1 <$ char '<'
   51 
   52 incParser :: ReadP FastInstruction
   53 incParser = Inc 1 <$ char '+'
   54 
   55 decParser :: ReadP FastInstruction
   56 decParser = Inc negate1 <$ char '-'
   57 
   58 outParser :: ReadP FastInstruction
   59 outParser = Output <$ char '.'
   60 
   61 inParser :: ReadP FastInstruction
   62 inParser = Input <$ char ','
   63 
   64 whileParser :: ReadP FastInstruction
   65 whileParser = While <$> (char '[' *> parameterizedInstructionsParser <* char ']')
   66 
   67 filterComments :: Source -> Source
   68 filterComments = Text.filter isNotComment
   69 
   70 isNotComment :: Char -> Bool
   71 isNotComment c = c `elem` allInstructionChars
   72 
   73 allInstructionChars :: String
   74 allInstructionChars = "[]" <> simpleInstructionChars
   75 
   76 simpleInstructionChars :: String
   77 simpleInstructionChars = show =<< Simple.simpleInstructions
   78 
   79 --
   80 
   81 negate1 :: Integer
   82 negate1 = negate 1