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