-
Notifications
You must be signed in to change notification settings - Fork 0
/
Interpreter.hs
66 lines (43 loc) · 1.3 KB
/
Interpreter.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
module Interpreter where
import Data.Char
import Types
import ParserBrainFuck
-- (data pointer index, memory list with data)
type State = ( Int, [Int])
spred 0 = 0
spred x = pred x
ssucc 127 = 0
ssucc x = succ x
add, sub, inc, dec :: State -> State
add (p, m) = ( p, x ++ [ssucc v] ++ xs )
where (x,v:xs) = splitAt p m
sub (p, m) = ( p, x ++ [spred v] ++ xs )
where (x,v:xs) = splitAt p m
inc (p, m) = (succ p, m)
dec (p, m) = (spred p, m)
out :: State -> IO State
out (p, m) = putChar c >> return (p, m)
where c = chr $ m !! p
run :: BrainFuck -> State -> IO State
run (Add:t) state = run t (add state)
run (Sub:t) state = run t (sub state)
run (Inc:t) state = run t (inc state)
run (Dec:t) state = run t (dec state)
run (Out:t) state = out state >>= run t
run (Inp:t) state = getChar >>= run t . (iterate add zero !!) . ord
where zero = iterate sub state !! 127
run ((Loop b):t) (s,m) =
if (m !! s) /= 0
then
do
(s',m') <- run b (s,m)
if (m' !! s') /= 0
then run ((Loop b):t) (s',m')
else run t (s',m')
else run t (s,m)
run ((Cmt s):t) state = run t state
run [] state = return state
memory :: State
memory = (0 , repeat 0)
brainFuck b = (take 20 . snd) <$> run inst memory
where inst = parserBrainFuck b