never executed always true always false
1 module HelVM.HelMA.Automata.BrainFuck.Impl.Tree.Evaluator
2 ( evalSource
3 ) where
4
5 import HelVM.HelMA.Automata.BrainFuck.Impl.Tree.Instruction
6 import HelVM.HelMA.Automata.BrainFuck.Impl.Tree.Parser
7
8 import HelVM.HelMA.Automata.BrainFuck.Common.SimpleInstruction
9 import HelVM.HelMA.Automata.BrainFuck.Common.Symbol
10 import HelVM.HelMA.Automata.BrainFuck.Common.TapeOfSymbols
11
12 import HelVM.HelMA.Automaton.API.IOTypes
13 import HelVM.HelMA.Automaton.Eff.MonadEff
14 import HelVM.HelMA.Automaton.Types.DumpType
15
16 import HelVM.HelIO.Containers.MTIndexSafe
17
18 import Control.Type.Operator
19
20 evalSource ∷ (AppSafeEff m , Symbol e) ⇒ Source → FullTape e → DumpType → m ()
21 evalSource source tape dt = logDump dt =<< flip runVector tape =<< parseAsVector source
22
23 runVector ∷ (AppSafeEff m , Symbol e) ⇒ TreeInstructionVector → FullTape e → m $ Memory e
24 runVector iv = nextStep (IM iv 0)
25
26 nextStep ∷ (AppSafeEff m , Symbol e) ⇒ InstructionMemory → FullTape e → m $ Memory e
27 nextStep (IM iv ic) = doInstruction (iv `indexMaybe` ic) (IM iv $ ic + 1)
28
29 doInstruction ∷ (AppSafeEff m , Symbol e) ⇒ Maybe TreeInstruction → InstructionMemory → FullTape e → m $ Memory e
30 doInstruction (Just (Simple MoveR )) table tape = nextStep table (moveHeadRight tape)
31 doInstruction (Just (Simple MoveL )) table tape = nextStep table (moveHeadLeft tape)
32 doInstruction (Just (Simple Inc )) table tape = nextStep table (nextSymbol tape)
33 doInstruction (Just (Simple Dec )) table tape = nextStep table (prevSymbol tape)
34 doInstruction (Just (Simple Output )) table tape = doOutputChar table tape
35 doInstruction (Just (Simple Input )) table tape = doInputChar table tape
36 doInstruction (Just (While iv )) table tape = doWhile iv table tape
37 doInstruction Nothing table tape = doEnd table tape
38
39 doWhile ∷ (AppSafeEff m , Symbol e) ⇒ TreeInstructionVector → InstructionMemory → FullTape e → m $ Memory e
40 doWhile _ table tape@(_ , 0:_) = nextStep table tape
41 doWhile iv table tape = doWhileWithTape =<< runVector iv tape where
42 doWhileWithTape ∷ (AppSafeEff m , Symbol e) ⇒ Memory e → m $ Memory e
43 doWhileWithTape = doWhile iv table . memoryTape
44
45 -- | IO instructions
46 doOutputChar ∷ (AppSafeEff m , Symbol e) ⇒ InstructionMemory → FullTape e → m $ Memory e
47 doOutputChar _ (_ , []) = error "Illegal State"
48 doOutputChar table tape@(_ , e:_) = putChar (toChar e) *> nextStep table tape
49
50 doInputChar ∷ (AppSafeEff m , Symbol e) ⇒ InstructionMemory → FullTape e → m $ Memory e
51 doInputChar table tape = (nextStep table . flip writeSymbol tape) =<< getChar
52
53 -- | Terminate instruction
54 doEnd ∷ AppSafeEff m ⇒ InstructionMemory → FullTape e → m $ Memory e
55 doEnd im tape = pure $ Memory im tape
56
57 -- | Types
58 data Memory e
59 = Memory
60 { memoryIM :: InstructionMemory
61 , memoryTape :: FullTape e
62 }
63 deriving stock (Eq, Show)
64
65 data InstructionMemory
66 = IM !TreeInstructionVector !InstructionCounter
67 deriving stock (Eq, Show)
68
69 type InstructionCounter = Int