-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStep1.hs
74 lines (60 loc) · 2 KB
/
Step1.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
64
65
66
67
68
69
70
71
72
73
module Step1 where
-- opcode definitions, compilation, peep-hole optimization
data Instr = Move Int | Inc Int | Read | Print | Open | Close | Debug String
deriving (Read, Show, Eq)
-- a peephole optimizer
simplify :: [Instr] -> [Instr]
simplify [] = []
simplify (Move 0 : xs) = simplify xs
simplify (Move a : Move b : xs) = simplify (Move (a+b) : xs)
simplify (Inc 0 : xs) = simplify xs
simplify (Inc a : Inc b : xs) = simplify (Inc (a+b) : xs)
simplify (x : xs) = x : simplify xs
-- translate a list of Instr to a String
toOpcodes :: [Instr] -> String
toOpcodes xs = concatMap go xs
where go (Move x)
| x > 0 = replicate x '>'
| x < 0 = replicate (-x) '<'
| otherwise = ""
go (Inc x)
| x > 0 = replicate x '+'
| x < 0 = replicate (-x) '-'
| otherwise = ""
go Open = "["
go Close = "]"
go Read = ","
go Print = "."
go (Debug x)
| ok x = "!" ++ x ++ "!"
| otherwise = error $ "bad debug message: " ++ x
where ok x = all (\c -> notElem c x) "![]<>+-.,"
compile = toOpcodes . simplify
-- print the letter A
ex1 = [ Inc 10 -- set cell 0 to 10
, Open
, Move 1, Inc 6 -- increment cell 1 by 6
, Move (-1), Inc (-1) -- move back to 0 and decrement by 1
, Close
, Move 1, Inc 5 -- add 5 to cell 1
, Print
]
ex1' = compile ex1
-- clear cell x
clear x = [ Move x, Open, Inc (-1), Close, Move (-x) ]
-- increment cell x by the constant a
incr_by x a = [ Move x, Inc a, Move (-x) ]
-- perform body the number of times in cell x
dotimes' x body = [ Move x, Open, Move (-x) ]
++ body
++ [ Move x, Inc (-1), Close, Move (-x) ]
at x body = [ Move x ] ++ body ++ [ Move (-x) ]
-- print the letter 'A'
ex2 = incr_by 0 10
++ dotimes' 0 (incr_by 1 6)
++ incr_by 1 5
++ at 1 [ Print ]
++ at 1 [ Debug "" ]
-- :add BFInterp
-- :m *Step1 *BFInterp
-- runBF $ compile ex1